cleanup unused

This commit is contained in:
Mike Jerris 2017-11-20 11:30:50 -05:00
parent efcc6c4e93
commit f7e2505fc7
278 changed files with 0 additions and 130321 deletions

14
.gitignore vendored
View File

@ -255,17 +255,3 @@ libs/broadvoice-*/
libs/libcodec2-*/
libs/libsilk-*/
libs/libconfig-*
libs/libsodium-*
libs/civetweb-*
libs/libblade/libblade.VC.db
libs/libblade/libblade.VC.VC.opendb
libs/libblade/Win32/
libs/libblade/x64/
libs/libks/libks.VC.db
libs/libks/libks.VC.VC.opendb
libs/pax_global_header
libs/win32/libconfig/Win32
libs/win32/libconfig/x64
libs/win32/libsodium/Win32
libs/win32/libsodium/x64

18
debian/copyright vendored
View File

@ -1693,24 +1693,6 @@ Files: src/switch_dso.c
Copyright: 2008 Michael Jerris
License: BSD-like
Files: libs/libks/*
libs/libscgi/src/include/scgi_oop.h
libs/libscgi/src/scgi.c
Copyright: 2007-2013, Anthony Minessale II
2007 Michael Jerris
1996-2000 Gray Watson
License: BSD-3-clause
Files: libs/libks/*/ks_json.[ch]
src/include/switch_json.h
src/switch_json.c
Copyright: 2009 Dave Gamble
License: MIT/X11 (BSD like)
Files: libs/libks/*/simclist.[ch]
Copyright: 2007-2011 Mij <mij@bitchx.it>
License: ISC
Files: libs/libtpl-1.5/src/tpl.[ch]
Copyright: 2005-2010, Troy D. Hanson
License: BSD-2-clause

View File

@ -1,4 +0,0 @@
Makefile
Makefile.in
build/*.m4
configure

View File

View File

@ -1 +0,0 @@

View File

@ -1,370 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell command `./configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -1,57 +0,0 @@
ACLOCAL_AMFLAGS=-I build
EXTRA_DIST =
SUBDIRS = . test switchblade
AUTOMAKE_OPTIONS = subdir-objects
CIVETWEB_VERSION=1.9.1
CIVETWEB=civetweb-$(CIVETWEB_VERSION)
CIVETWEB_DIR=$(top_srcdir)/../$(CIVETWEB)
CIVETWEB_LIB=$(top_srcdir)/../$(CIVETWEB)/libcivetweb.a
LIBKS_DIR=$(top_srcdir)/../libks
LIBKS=$(LIBKS_DIR)/libks.la
AM_CFLAGS += -I$(top_srcdir)/src -I$(top_srcdir)/src/include -I$(CIVETWEB_DIR)/include -I$(LIBKS_DIR)/src/include
AM_LDFLAGS += -L$(CIVETWEB_DIR)
noinst_LTLIBRARIES = libunqlite.la
libunqlite_la_SOURCES = src/unqlite.c
libunqlite_la_CFLAGS = -DUNQLITE_ENABLE_THREADS
libunqlite_la_LIBADD = -lpthread
lib_LTLIBRARIES = libblade.la
libblade_la_SOURCES = src/blade.c src/blade_stack.c
libblade_la_SOURCES += src/blade_transportmgr.c src/blade_rpcmgr.c src/blade_routemgr.c src/blade_subscriptionmgr.c
libblade_la_SOURCES += src/blade_mastermgr.c src/blade_connectionmgr.c src/blade_sessionmgr.c src/blade_restmgr.c
libblade_la_SOURCES += src/blade_identity.c src/blade_rpc.c src/blade_connection.c src/blade_session.c
libblade_la_SOURCES += src/blade_protocol.c src/blade_subscription.c src/blade_channel.c
libblade_la_SOURCES += src/blade_transport.c src/blade_transport_wss.c src/blade_web.c
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(PCRE_CFLAGS)
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm -lconfig -lcivetweb $(AM_LDFLAGS)
libblade_la_LIBADD = libunqlite.la $(PCRE_LIBS)
library_includedir = $(prefix)/include
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h
library_include_HEADERS += src/include/blade_transportmgr.h src/include/blade_rpcmgr.h src/include/blade_routemgr.h src/include/blade_subscriptionmgr.h
library_include_HEADERS += src/include/blade_mastermgr.h src/include/blade_connectionmgr.h src/include/blade_sessionmgr.h src/include/blade_restmgr.h
library_include_HEADERS += src/include/blade_identity.h src/include/blade_rpc.h src/include/blade_connection.h src/include/blade_session.h
library_include_HEADERS += src/include/blade_protocol.h src/include/blade_subscription.h src/include/blade_channel.h
library_include_HEADERS += src/include/blade_transport.h src/include/blade_transport_wss.h src/include/blade_web.h
library_include_HEADERS += src/include/unqlite.h test/tap.h
BUILT_SOURCES=$(CIVETWEB_LIB) $(LIBKS)
$(CIVETWEB_LIB): $(CIVETWEB_DIR)
cd $(CIVETWEB_DIR) && $(MAKE) lib USE_STACK_SIZE=102400 MAX_REQUEST_SIZE=16384 WITH_LUA=1 LUA_COMPAT_ALL=1 USE_LUA_SQLITE3=1 USE_LUA_FILE_SYSTEM=1 WITH_IPV6=1 WITH_WEBSOCKET=1 && $(MAKE) lib USE_STACK_SIZE=102400 MAX_REQUEST_SIZE=16384 WITH_LUA=1 LUA_COMPAT_ALL=1 USE_LUA_SQLITE3=1 USE_LUA_FILE_SYSTEM=1 WITH_IPV6=1 WITH_WEBSOCKET=1 WITH_DUKTAPE=1
$(CIVETWEB_DIR):
$(GETLIB) $(CIVETWEB).tar.gz
$(LIBKS):
cd $(top_srcdir)/../libks && /bin/sh ./bootstrap.sh && /bin/sh ./configure && $(MAKE)
tests: libblade.la
$(MAKE) -C test tests
switchblade: libblade.la
$(MAKE) -C switchblade sb

View File

View File

@ -1,26 +0,0 @@
== Build ==
To build against the in tree version of libks follow these steps, from the starting point of ./libs/libblade/:
<code>
cd ../libks/
./bootstrap.sh
./configure
make
make check
cd ../libblade/
./boostrap.sh
./configure --with-libks=`realpath ../libks/`
make
make check
</code>
If you are trying to run the 'make distcheck' target while using the
in tree version of libks, then you need to specify the
DISTCHECK_CONFIGURE_FLAGS env variable like:
<code>
DISTCHECK_CONFIGURE_FLAGS="--with-libks=/usr/src/freeswitch/libs/libks" make distcheck
</code>

View File

@ -1,7 +0,0 @@
m4_include([build/config/ax_compiler_vendor.m4])
m4_include([build/config/ax_cflags_warn_all_ansi.m4])
m4_include([build/config/ax_cc_maxopt.m4])
m4_include([build/config/ax_check_compiler_flags.m4])
m4_include([build/config/ac_gcc_archflag.m4])
m4_include([build/config/ac_gcc_x86_cpuid.m4])
m4_include([build/config/sac-openssl.m4])

View File

@ -1,4 +0,0 @@
#!/bin/sh
set -x
${AUTORECONF:-autoreconf} -fi

View File

@ -1,347 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,142 +0,0 @@
AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl
AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic % m4_ifval($2,$2,-option)" dnl GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl the only difference - the LANG selection... and the default FLAGS
AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl
AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CXX
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic % m4_ifval($2,$2,-option)" dnl GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl -------------------------------------------------------------------------
AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl
AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic % m4_ifval($1,$1,-option)" dnl GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"])
m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl the only difference - the LANG selection... and the default FLAGS
AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl
AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CXX
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic % m4_ifval($1,$1,-option)" dnl GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"])
m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1,
[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])])
AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1,
[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])])

View File

@ -1,140 +0,0 @@
AC_DEFUN([AX_CFLAGS_SUN_OPTION_OLD], [dnl
AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_sun_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for sun/cc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "+xstrconst % -xc99=all m4_ifval($2,$2,-option)" dnl Solaris C
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl the only difference - the LANG selection... and the default FLAGS
AC_DEFUN([AX_CXXFLAGS_SUN_OPTION_OLD], [dnl
AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_sun_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for sun/cc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CXX
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "+xstrconst % -xc99=all m4_ifval($2,$2,-option)" dnl Solaris C
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl -----------------------------------------------------------------------
AC_DEFUN([AX_CFLAGS_SUN_OPTION_NEW], [dnl
AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_sun_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for sun/cc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "+xstrconst % -xc99=all m4_ifval($1,$1,-option)" dnl Solaris C
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"])
m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl the only difference - the LANG selection... and the default FLAGS
AC_DEFUN([AX_CXXFLAGS_SUN_OPTION_NEW], [dnl
AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_sun_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for sun/cc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CXX
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "+xstrconst % -xc99=all m4_ifval($1,$1,-option)" dnl Solaris C
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"])
m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
AC_DEFUN([AX_CFLAGS_SUN_OPTION],[ifelse(m4_regexp([$2],[-]),-1,
[AX_CFLAGS_SUN_OPTION_NEW($@)],[AX_CFLAGS_SUN_OPTION_OLD($@)])])
AC_DEFUN([AX_CXXFLAGS_SUN_OPTION],[ifelse(m4_regexp([$2],[-]),-1,
[AX_CXXFLAGS_SUN_OPTION_NEW($@)],[AX_CXXFLAGS_SUN_OPTION_OLD($@)])])

View File

@ -1,148 +0,0 @@
AC_DEFUN([AX_GCC_ARCHFLAG],
[AC_REQUIRE([AC_PROG_CC])
AC_ARG_WITH(gcc-arch, [AC_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
ax_gcc_arch=$withval, ax_gcc_arch=yes)
AC_MSG_CHECKING([for gcc architecture flag])
AC_MSG_RESULT([])
AC_CACHE_VAL(ax_cv_gcc_archflag,
[
ax_cv_gcc_archflag="unknown"
if test "$GCC" = yes; then
if test "x$ax_gcc_arch" = xyes; then
ax_gcc_arch=""
if test "$cross_compiling" = no; then
case $host_cpu in
i[[3456]]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
AX_GCC_X86_CPUID(0)
AX_GCC_X86_CPUID(1)
case $ax_cv_gcc_x86_cpuid_0 in
*:756e6547:*:*) # Intel
case $ax_cv_gcc_x86_cpuid_1 in
*5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
*5??:*:*:*) ax_gcc_arch=pentium ;;
*6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
*6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
*6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
*6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
*6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
*6??:*:*:*) ax_gcc_arch=pentiumpro ;;
*f3[[347]]:*:*:*|*f4[1347]:*:*:*)
case $host_cpu in
x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
*) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
esac ;;
*f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
esac ;;
*:68747541:*:*) # AMD
case $ax_cv_gcc_x86_cpuid_1 in
*5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
*5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
*5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
*60?:*:*:*) ax_gcc_arch=k7 ;;
*6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
*6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
*67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
*6[[68a]]?:*:*:*)
AX_GCC_X86_CPUID(0x80000006) # L2 cache size
case $ax_cv_gcc_x86_cpuid_0x80000006 in
*:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
*) ax_gcc_arch="athlon-4 athlon k7" ;;
esac ;;
*f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
*f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
*f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
*f??:*:*:*) ax_gcc_arch="k8" ;;
esac ;;
*:746e6543:*:*) # IDT
case $ax_cv_gcc_x86_cpuid_1 in
*54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
*58?:*:*:*) ax_gcc_arch=winchip2 ;;
*6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
*69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
esac ;;
esac
if test x"$ax_gcc_arch" = x; then # fallback
case $host_cpu in
i586*) ax_gcc_arch=pentium ;;
i686*) ax_gcc_arch=pentiumpro ;;
esac
fi
;;
sparc*)
AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
case $cputype in
*ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
*ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
*ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
*supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
*hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
*cypress*) ax_gcc_arch=cypress ;;
esac ;;
alphaev5) ax_gcc_arch=ev5 ;;
alphaev56) ax_gcc_arch=ev56 ;;
alphapca56) ax_gcc_arch="pca56 ev56" ;;
alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
alphaev6) ax_gcc_arch=ev6 ;;
alphaev67) ax_gcc_arch=ev67 ;;
alphaev68) ax_gcc_arch="ev68 ev67" ;;
alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
powerpc*)
cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
case $cputype in
*750*) ax_gcc_arch="750 G3" ;;
*740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
*74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
*74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
*970*) ax_gcc_arch="970 G5 power4";;
*POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
*POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
603ev|8240) ax_gcc_arch="$cputype 603e 603";;
*) ax_gcc_arch=$cputype ;;
esac
ax_gcc_arch="$ax_gcc_arch powerpc"
;;
esac
fi # not cross-compiling
fi # guess arch
if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
for arch in $ax_gcc_arch; do
if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
flags="-mtune=$arch"
# -mcpu=$arch and m$arch generate nonportable code on every arch except
# x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
else
flags="-march=$arch -mcpu=$arch -m$arch"
fi
for flag in $flags; do
AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
done
test "x$ax_cv_gcc_archflag" = xunknown || break
done
fi
fi # $GCC=yes
])
AC_MSG_CHECKING([for gcc architecture flag])
AC_MSG_RESULT($ax_cv_gcc_archflag)
if test "x$ax_cv_gcc_archflag" = xunknown; then
m4_default([$3],:)
else
m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
fi
])

View File

@ -1,21 +0,0 @@
AC_DEFUN([AX_GCC_X86_CPUID],
[AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int op = $1, eax, ebx, ecx, edx;
FILE *f;
__asm__("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (op));
f = fopen("conftest_cpuid", "w"); if (!f) return 1;
fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
fclose(f);
return 0;
])],
[ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown])])
AC_LANG_POP([C])
])

View File

@ -1,9 +0,0 @@
AC_DEFUN([AC_PROG_GZIP],[
AC_CHECK_PROGS(gzip,[gzip],no)
export gzip;
if test $gzip = "no" ;
then
AC_MSG_ERROR([Unable to find the gzip application]);
fi
AC_SUBST(gzip)
])

View File

@ -1,9 +0,0 @@
AC_DEFUN([AC_PROG_WGET],[
AC_CHECK_PROGS(wget,[wget],no)
export wget;
if test $wget = "no" ;
then
AC_MSG_ERROR([Unable to find the wget application]);
fi
AC_SUBST(wget)
])

View File

@ -1,120 +0,0 @@
AC_DEFUN([AX_CC_MAXOPT],
[
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AX_COMPILER_VENDOR])
AC_ARG_ENABLE(portable-binary, [AC_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
acx_maxopt_portable=$withval, acx_maxopt_portable=no)
# Try to determine "good" native compiler flags if none specified via CFLAGS
if test "$ac_test_CFLAGS" != "set"; then
CFLAGS=""
case $ax_cv_c_compiler_vendor in
dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
if test "x$acx_maxopt_portable" = xno; then
CFLAGS="$CFLAGS -arch host"
fi;;
sun) CFLAGS="-native -fast -xO5 -dalign -xc99=all"
if test "x$acx_maxopt_portable" = xyes; then
CFLAGS="$CFLAGS -xarch=generic"
fi;;
hp) CFLAGS="+Oall +Optrs_ansi +DSnative"
if test "x$acx_maxopt_portable" = xyes; then
CFLAGS="$CFLAGS +DAportable"
fi;;
ibm) if test "x$acx_maxopt_portable" = xno; then
xlc_opt="-qarch=auto -qtune=auto"
else
xlc_opt="-qtune=auto"
fi
AX_CHECK_COMPILER_FLAGS($xlc_opt,
CFLAGS="-O3 -qansialias -w $xlc_opt",
[CFLAGS="-O3 -qansialias -w"
echo "******************************************************"
echo "* You seem to have the IBM C compiler. It is *"
echo "* recommended for best performance that you use: *"
echo "* *"
echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
echo "* ^^^ ^^^ *"
echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *"
echo "* CPU you have. (Set the CFLAGS environment var. *"
echo "* and re-run configure.) For more info, man cc. *"
echo "******************************************************"])
;;
intel) CFLAGS="-O3 -ansi_alias"
if test "x$acx_maxopt_portable" = xno; then
icc_archflag=unknown
icc_flags=""
case $host_cpu in
i686*|x86_64*)
# icc accepts gcc assembly syntax, so these should work:
AX_GCC_X86_CPUID(0)
AX_GCC_X86_CPUID(1)
case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
*:756e6547:*:*) # Intel
case $ax_cv_gcc_x86_cpuid_1 in
*6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
*f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
*f??:*:*:*) icc_flags="-xN -xW -xK";;
esac ;;
esac ;;
esac
if test "x$icc_flags" != x; then
for flag in $icc_flags; do
AX_CHECK_COMPILER_FLAGS($flag, [icc_archflag=$flag; break])
done
fi
AC_MSG_CHECKING([for icc architecture flag])
AC_MSG_RESULT($icc_archflag)
if test "x$icc_archflag" != xunknown; then
CFLAGS="$CFLAGS $icc_archflag"
fi
fi
;;
gnu)
# default optimization flags for gcc on all systems
CFLAGS="-O3 -fomit-frame-pointer"
# -malign-double for x86 systems
AX_CHECK_COMPILER_FLAGS(-malign-double, CFLAGS="$CFLAGS -malign-double")
# -fstrict-aliasing for gcc-2.95+
AX_CHECK_COMPILER_FLAGS(-fstrict-aliasing,
CFLAGS="$CFLAGS -fstrict-aliasing")
# note that we enable "unsafe" fp optimization with other compilers, too
AX_CHECK_COMPILER_FLAGS(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
AX_GCC_ARCHFLAG($acx_maxopt_portable)
;;
esac
if test -z "$CFLAGS"; then
echo ""
echo "********************************************************"
echo "* WARNING: Don't know the best CFLAGS for this system *"
echo "* Use ./configure CFLAGS=... to specify your own flags *"
echo "* (otherwise, a default of CFLAGS=-O3 will be used) *"
echo "********************************************************"
echo ""
CFLAGS="-O3"
fi
AX_CHECK_COMPILER_FLAGS($CFLAGS, [], [
echo ""
echo "********************************************************"
echo "* WARNING: The guessed CFLAGS don't seem to work with *"
echo "* your compiler. *"
echo "* Use ./configure CFLAGS=... to specify your own flags *"
echo "********************************************************"
echo ""
CFLAGS=""
])
fi
])

View File

@ -1,94 +0,0 @@
AC_DEFUN([AX_CFLAGS_WARN_ALL_ANSI],[dnl
AS_VAR_PUSHDEF([FLAGS],[AM_CFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_warn_all_ansi])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum ansi warnings],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
ac_save_[]FLAGS="$[]FLAGS"
# IRIX C compiler:
# -use_readonly_const is the default for IRIX C,
# puts them into .rodata, but they are copied later.
# need to be "-G0 -rdatashared" for strictmode but
# I am not sure what effect that has really. - guidod
for ac_arg dnl
in "-pedantic % -Wall -std=c99 -pedantic" dnl GCC
"-xstrconst % -v -xc99=all" dnl Solaris C
"-std1 % -verbose -w0 -warnprotos -std1" dnl Digital Unix
" % -qlanglvl=ansi -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
" % -ansi -ansiE -fullwarn" dnl IRIX
"+ESlit % +w1 -Aa" dnl HP-UX C
"-Xc % -pvctl[,]fullmsg -Xc" dnl NEC SX-5 (Super-UX 10)
"-h conform % -h msglevel 2 -h conform" dnl Cray C (Unicos)
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])
dnl the only difference - the LANG selection... and the default FLAGS
AC_DEFUN([AX_CXXFLAGS_WARN_ALL_ANSI],[dnl
AS_VAR_PUSHDEF([FLAGS],[AM_CXXFLAGS])dnl
AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_warn_all_ansi])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum ansi warnings],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CXX
ac_save_[]FLAGS="$[]FLAGS"
# IRIX C compiler:
# -use_readonly_const is the default for IRIX C,
# puts them into .rodata, but they are copied later.
# need to be "-G0 -rdatashared" for strictmode but
# I am not sure what effect that has really. - guidod
for ac_arg dnl
in "-pedantic % -Wall -ansi -pedantic" dnl GCC
"-xstrconst % -v -Xc" dnl Solaris C
"-std1 % -verbose -w0 -warnprotos -std1" dnl Digital Unix
" % -qlanglvl=ansi -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
" % -ansi -ansiE -fullwarn" dnl IRIX
"+ESlit % +w1 -Aa" dnl HP-UX C
"-Xc % -pvctl[,]fullmsg -Xc" dnl NEC SX-5 (Super-UX 10)
"-h conform % -h msglevel 2 -h conform" dnl Cray C (Unicos)
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
AC_LANG_RESTORE
])
case ".$VAR" in
.ok|.ok,*) m4_ifvaln($3,$3) ;;
.|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
*) m4_ifvaln($3,$3,[
if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
fi ]) ;;
esac
AS_VAR_POPDEF([VAR])dnl
AS_VAR_POPDEF([FLAGS])dnl
])

View File

@ -1,26 +0,0 @@
AC_DEFUN([AX_CHECK_COMPILER_FLAGS],
[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1])
dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
AS_LITERAL_IF([$1],
[AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1), [
ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$1"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes,
AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no)
_AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])],
[ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$1"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes,
eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no)
_AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])
eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)
AC_MSG_RESULT($ax_check_compiler_flags)
if test "x$ax_check_compiler_flags" = xyes; then
m4_default([$2], :)
else
m4_default([$3], :)
fi
])dnl AX_CHECK_COMPILER_FLAG

View File

@ -1,15 +0,0 @@
AC_DEFUN([AX_COMPILER_VENDOR],
[
AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
[ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
# note: don't check for gcc first since some other compilers define __GNUC__
for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
#if !($vencpp)
thisisanerror;
#endif
])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
done
])
])

View File

@ -1,49 +0,0 @@
dnl ======================================================================
dnl SAC_OPENSSL
dnl ======================================================================
AC_DEFUN([SAC_OPENSSL], [
AC_ARG_WITH(openssl,
[ --with-openssl use OpenSSL [[enabled]]],, with_openssl=pkg-config)
dnl SOSXXX:SAC_ASSERT_DEF([openssl libraries])
if test "$with_openssl" = no ;then
: # No openssl
else
if test "$with_openssl" = "pkg-config" ; then
PKG_CHECK_MODULES(openssl, openssl,
[HAVE_TLS=1 HAVE_OPENSSL=1 LIBS="$openssl_LIBS $LIBS"],
[HAVE_OPENSSL=0])
fi
if test x$HAVE_OPENSSL = x1 ; then
AC_DEFINE([HAVE_LIBCRYPTO], 1, [Define to 1 if you have the `crypto' library (-lcrypto).])
AC_DEFINE([HAVE_LIBSSL], 1, [Define to 1 if you have the `ssl' library (-lssl).])
else
AC_CHECK_HEADERS([openssl/tls1.h], [
HAVE_OPENSSL=1 HAVE_TLS=1
AC_CHECK_LIB(crypto, BIO_new,,
HAVE_OPENSSL=0
AC_MSG_WARN(OpenSSL crypto library was not found))
AC_CHECK_LIB(ssl, TLSv1_method,,
HAVE_TLS=0
AC_MSG_WARN(OpenSSL protocol library was not found))
],[AC_MSG_WARN(OpenSSL include files were not found)],[#include <openssl/safestack.h>])
fi
if test x$HAVE_OPENSSL = x1; then
AC_DEFINE([HAVE_OPENSSL], 1, [Define to 1 if you have OpenSSL])
fi
if test x$HAVE_TLS = x1; then
AC_DEFINE([HAVE_TLS], 1, [Define to 1 if you have TLS])
fi
fi
AM_CONDITIONAL(HAVE_TLS, test x$HAVE_TLS = x1)
])

View File

@ -1,302 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(libblade, 0.1, bugs@freeswitch.org)
AC_CONFIG_AUX_DIR(build)
AC_CONFIG_MACRO_DIR([build])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src])
# disable checks
m4_defun([_LT_AC_LANG_CXX_CONFIG], [:])
m4_defun([_LT_AC_LANG_F77_CONFIG], [:])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Absolute source/build directory
blade_srcdir=`(cd $srcdir && pwd)`
blade_builddir=`pwd`
AC_SUBST(blade_srcdir)
AC_SUBST(blade_builddir)
case $host in
*-openbsd*)
# OpenBSD's gunzip and friends don't like -d because its redundant, only gzip does
AC_PATH_PROGS(ZCAT, gzip)
;;
*)
AC_PATH_PROGS(ZCAT, gunzip gzcat gzip zcat)
;;
esac
AC_PATH_PROGS(BZIP, bzip2)
AC_PATH_PROGS(XZ, xz)
AC_PATH_PROGS(TAR, gtar tar)
AC_PATH_PROGS(WGET, wget)
AC_PATH_PROGS(CURL, curl)
GETLIB="cd $blade_builddir/.. && ${SHELL} $blade_builddir/../../build/getlib.sh"
AC_SUBST(GETLIB)
# Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
AC_PROG_INSTALL
# Optimize
AC_ARG_ENABLE(optimization,
[AC_HELP_STRING([--enable-optimization],[Set if you want us to add max optimising compiler flags])],[enable_optimizer="$enableval"],[enable_optimizer="no"])
if test "${enable_optimizer}" = "yes" ; then
AC_DEFINE([OPTIMZER],[],[Enable Optimization.])
AX_CC_MAXOPT
fi
# Enable debugging
AC_ARG_ENABLE(debug,
[AC_HELP_STRING([--enable-debug],[build with debug information])],[enable_debug="$enable_debug"],[enable_debug="no"])
if test "${enable_debug}" = "yes"; then
AC_DEFINE([DEBUG],[],[Enable extra debugging.])
fi
AM_CONDITIONAL([WANT_DEBUG],[test "${enable_debug}" = "yes"])
dnl check for the compiler used
AX_COMPILER_VENDOR
case "$host" in
*-solaris2*)
if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
AM_CFLAGS="-KPIC -DPIC"
AM_LDFLAGS="-R${prefix}/lib"
fi
;;
*-darwin*)
if test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
AM_CFLAGS="-DMACOSX"
fi
;;
x86_64-unknown-linux-gnu)
AM_CFLAGS="-fPIC"
AM_LDFLAGS=""
;;
i*6-unknown-linux-gnu)
AM_CFLAGS="-fpic"
AM_LDFLAGS=""
;;
x86_64-*-freebsd*|amd64-*-freebsd*)
AM_CFLAGS="-fpic"
AM_LDFLAGS=""
;;
i*6-*-freebsd*)
AM_CFLAGS="-fpic"
AM_LDFLAGS=""
;;
esac
AX_CFLAGS_WARN_ALL_ANSI
AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
AC_CHECK_LIB(rt, clock_getres, [AC_DEFINE(HAVE_CLOCK_GETRES, 1, [Define if you have clock_getres()])])
AC_CHECK_LIB(rt, clock_nanosleep, [AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1, [Define if you have clock_nanosleep()])])
AC_CHECK_FUNCS([usleep])
#
# sched_setcheduler + round-robin scheduler prerequisites
#
AC_CHECK_HEADERS([sched.h byteswap.h sys/endian.h])
AC_CHECK_DECL([SCHED_RR],
[AC_DEFINE([HAVE_SCHED_RR],[1],[SCHED_RR constant for sched_setscheduler])],,
[#ifdef HAVE_SCHED_H
#include <sched.h>
#endif])
AC_CHECK_FUNCS([sched_setscheduler memmem])
if test "x${ac_cv_func_sched_setscheduler}" = "xyes" -a \
"x${ac_cv_have_decl_SCHED_RR}" = "xyes"
then
AC_DEFINE([USE_SCHED_SETSCHEDULER],[1],[Enable round-robin scheduler using sched_setscheduler])
AM_CFLAGS="${AM_CFLAGS} -DUSE_SCHED_SETSCHEDULER=1"
fi
#
# gcc visibility cflag checks
#
AC_ARG_ENABLE([visibility],
[AS_HELP_STRING([--disable-visibility], [Disable or enable API visibility support (default: use if available)])],
[enable_visibility="${enableval}"],
[enable_visibility="detect"]
)
HAVE_VISIBILITY="no"
if test "x${enable_visibility}" != "xno" ; then
case "${ax_cv_c_compiler_vendor}" in
gnu)
save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} -fvisibility=hidden"
AC_MSG_CHECKING([whether the compiler supports -fvisibility=hidden])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[int foo __attribute__ ((visibility("default")));],
[;]
)],
[AC_MSG_RESULT([yes])
AM_CFLAGS="${AM_CFLAGS} -DKS_API_VISIBILITY=1 -fvisibility=hidden"
AC_DEFINE([HAVE_VISIBILITY], [1], [GCC visibility support available])
HAVE_VISIBILITY="yes"],
[AC_MSG_RESULT([no])]
)
CFLAGS="${save_CFLAGS}"
;;
sun)
save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} -xldscope=hidden"
AC_MSG_CHECKING([whether the compiler supports -xldscope=hidden])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[int foo __attribute__ ((visibility("default")));],
[;]
)],
[AC_MSG_RESULT([yes])
AM_CFLAGS="${AM_CFLAGS} -DKS_API_VISIBILITY=1 -xldscope=hidden"
AC_DEFINE([HAVE_VISIBILITY], [1], [SUNCC visibility support available])
HAVE_VISIBILITY="yes"],
[AC_MSG_RESULT([no])]
)
CFLAGS="${save_CFLAGS}"
;;
*)
if test "x${enable_visibility}" = "xyes" ; then
AC_MSG_ERROR([Non-GNU / SUN compilers are currently unsupported])
else
AC_MSG_WARN([Non-GNU / SUN compilers are currently unsupported])
fi
;;
esac
#
# visibility explicitly requested but not supported by this compiler => error
#
if test "x${enable_visibility}" = "xyes" -a "x${HAVE_VISIBILITY}" = "xno" ; then
AC_MSG_ERROR([API visibility not supported by this compiler])
fi
fi
AM_CFLAGS="${AM_CFLAGS} -Werror"
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_CHECK_LIB(pthread, pthread_setschedparam, [
AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])
AM_CFLAGS="${AM_CFLAGS} -DHAVE_PTHREAD_SETSCHEDPARAM=1"
])
AC_C_BIGENDIAN(AC_DEFINE([__BYTE_ORDER],__BIG_ENDIAN,[Big Endian]),AC_DEFINE([__BYTE_ORDER],__LITTLE_ENDIAN,[Little Endian]))
AC_DEFINE([__LITTLE_ENDIAN],1234,[for the places where it is not defined])
AC_DEFINE([__BIG_ENDIAN],4321,[for the places where it is not defined])
path_remove () {
echo "$1" | tr ':' '\n' | grep -Fxv "$2" | tr '\n' ':' | sed 's/:$//'
}
path_push_unique () {
x="$(eval echo \$$1)"
x="$(path_remove "$x" "$2")"
if test -z "$x"; then
eval export $1="$2"
else
eval export $1="$2:$x"
fi
}
case $host in
*-darwin*)
path_push_unique PKG_CONFIG_PATH /usr/local/opt/openssl/lib/pkgconfig
;;
esac
SAC_OPENSSL
if test x$HAVE_OPENSSL = x1; then
openssl_CFLAGS="$openssl_CFLAGS -DHAVE_OPENSSL";
AM_CFLAGS="${AM_CFLAGS} -DHAVE_OPENSSL"
else
AC_MSG_ERROR([OpenSSL and associated developement headers required])
fi
PKG_CHECK_MODULES([SODIUM], [libsodium >= 1.0.0],[AC_MSG_RESULT([yes])],[AC_MSG_ERROR([libsodium is required])])
PKG_CHECK_MODULES([LIBKS], [libks >= 0.1],[AC_MSG_RESULT([yes])],[AC_MSG_WARN([libks is required, but not found.])])
PKG_CHECK_MODULES([PCRE], [libpcre >= 7.8])
# Enable clang address sanitizer bit build
AC_ARG_ENABLE(address_sanitizer,
[AC_HELP_STRING([--enable-address-sanitizer],[build with address sanitizer])],
[enable_address_sanitizer="$enable_address_sanitizer"],
[enable_address_sanitizer="no"])
if test "${enable_address_sanitizer}" = "yes"; then
AM_CFLAGS="${AM_CFLAGS} -fsanitize=address -fno-omit-frame-pointer"
AM_CXXFLAGS="${AM_CXXFLAGS} -fsanitize=address -fno-omit-frame-pointer"
AM_LDFLAGS="${AM_LDFLAGS} -fsanitize=address"
fi
AC_ARG_WITH([libks],
AS_HELP_STRING([--with-libks=DIR],[libks location @<:@/usr/src/freeswitch/libs/libks/@:>@]),
[with_libks="$withval"])
if test "x$with_libks" != "x"; then
LIBKS_LIBS="-L${with_libks} -L${with_libks}/.libs/ -lks"
LIBKS_CFLAGS="-I${with_libks}/src/include"
fi
#TODO: If LIBKS_CFLAGS is not defined and --with-libks is not defined, then check if ../libks/libks.la exists, and if so then use that path as a fallback
if test "${LIBKS_CFLAGS}" = ""; then
AC_CHECK_FILE([../libks/libks.la],
AC_MSG_WARN([local development version of libks is being used. This is probably not portable.])
LIBKS_CFLAGS="-I`pwd`/../libks/src/include"
LIBKS_LIBS="-L`pwd`/../libks/.libs/ -lks",
AC_MSG_WARN([libks cannot be found.]))
fi
AM_CPPFLAGS="-I./src -I./src/include ${LIBKS_CFLAGS} ${openssl_CFLAGS} ${SODIUM_CFLAGS}"
AM_LDFLAGS="${AM_LDFLAGS} ${LIBKS_LIBS} ${openssl_LIBS} ${SODIUM_LIBS}"
AC_SUBST([AM_CFLAGS])
AC_SUBST([AM_CPPFLAGS])
AC_SUBST([AM_CXXDFLAGS])
AC_SUBST([AM_LDFLAGS])
AC_CONFIG_FILES([Makefile
test/Makefile
switchblade/Makefile
libblade.pc
../../build/getlib.sh
])
AC_OUTPUT

View File

@ -1,227 +0,0 @@
--->
GET /login HTTP/1.1
Host: master.freeswitch.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: blade-1.0
Sec-WebSocket-Version: 13
<---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: blade-1.0
---> CONNECT TO THE MASTER NODE
{
"jsonrpc": "2.0",
"method": "BLADE.connect",
"params": {
"blade": "1.0",
"session-id": "", // optional, hint to reconnect to existing session
},
"id": 1
}
<--- SUCCESS (TBD FAIL CASE)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"blade": "1.0",
"connection-state": "connected",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
"realm-list": [{"realm": "ls1.mydomain.com"}]
"allowed-protocol": ["BLADE"],
}
}
---> REGISTER ADDITIONAL IDENTITY "foobar@ls1.mydomain.com/blah"
{
"jsonrpc": "2.0",
"method": "BLADE.register",
"params": {
"identity": "foobar",
"realm": "ls1.mydomain.com",
"resource": "blah",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 2
}
<--- SUCCESS (TBD FAIL CASE) messages for this foobar IDENTITY will now go to this node.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"identity": "foobar",
"realm": "ls1.mydomain.com",
"resource": "blah",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
}
}
---> REGISTER SUBDOMAIN "myspace.ls1.mydomain.com"
{
"jsonrpc": "2.0",
"method": "BLADE.register",
"params": {
"sub-realm": "myspace",
"realm": "ls1.mydomain.com",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 3
}
<--- SUCCESS (TBD FAIL CASE) messages for any IDENTITY at "myspace.ls1.mydomain.com" will now go to this node.
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"sub-realm": "myspace",
"realm": "ls1.mydomain.com",
"realm-list": [{"realm": "ls1.mydomain.com", "sub-realms": ["myspace"]}],
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
}
}
---> PUBLISH API LSAPI "A single node must have exclusive access to the PROTOCOL's namespace with the master to publish"
// MAYBE ADD SCHEMA and method to fetch it.
{
"jsonrpc": "2.0",
"method": "BLADE.publish",
"params": {
"protocol": "LSAPI",
"exclusive": true,
"realm": "ls1.mydomain.com",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 4
}
<--- SUCCESS (TBD FAIL CASE)
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"protocol": "LSAPI",
"allowed-protocol": ["BLADE", "LSAPI"],
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
}
}
---> Locate identities holding an api
// MAYBE ADD SCHEMA and method to fetch it.
{
"jsonrpc": "2.0",
"method": "BLADE.locate",
"params": {
"protocol": "LSAPI",
"realm": "ls1.mydomain.com",
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 4.1
}
<--- SUCCESS (TBD FAIL CASE)
{
"jsonrpc": "2.0",
"id": 4.1,
"result": {
"protocol": "LSAPI",
"realm": "ls1.mydomain.com",
"sub-realm": null,
"targets": ["b9acdce6-3ce6-42db-82fc-39bf37c7a2b1", "5b696e8d-9875-45a5-b347-3b9fc288bad3"],
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
}
}
---> EXECUTE API
{
"jsonrpc": "2.0",
"method": "BLADE.execute",
"params": {
"realm": "ls1.mydomain.com",
"protocol": "LSAPI",
"method": "LSAPI.ls",
"params": {
"path": "/tmp/testing"
}
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 5
}
<--- SUCCESS (TBD FAIL CASE)
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"realm": "ls1.mydomain.com",
"protocol": "LSAPI",
"result": {
"listing": "-rw-r--r-- 1 root root 33881 May 3 17:22 blank_avatar.png\ndrwxr-xr-x 6 root root 4096 Oct 26 2016 dash.js\n-rw-r--r-- 1 root root 5266 May 3 17:20 foo.diff\n-rw-r--r-- 1 root root 485 May 3 17:22 ks.diff"
},
}
}
Endpoints subscribe to event channels on their Master.
If that Master is not the top tier Master, it in turn subscribes all of its distinct events to it's Master until it reaches the top tier.
When the Master is encounterd who holds a connection to the Controller for a particular protocol, the Master subscribes to that Controller.
---> EVENT SUB
{
"jsonrpc": "2.0",
"method": "BLADE.subscribe",
"params": {
"realm": "ls1.mydomain.com",
"protocol": "LSAPI",
"event-space": "LSAPI",
"params": {
"eventChannel": "someEvent",
"subParams": {"foo": "bar"}
}
"session-id": "5b696e8d-9875-45a5-b347-3b9fc288bad3",
"master-id": "5164f7f8-a6ca-4dd4-8f36-33db1dc9c35d",
},
"id": 6
}
<--- SUCCESS (TBD FAIL CASE)
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"realm": "ls1.mydomain.com",
"protocol": "LSAPI",
"event-space": "LSAPI",
"result": {
"subscribedChannels": ["someEvent"],
"unauthorizedChannels": [],
"alreadySubscribedChannels": []
},
}
}

View File

@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Version: @PACKAGE_VERSION@
Description: The switchblade library.
Cflags: -I${includedir}
Libs: -L${libdir} -lblade

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>UNICODE;SIMCLIST_NO_DUMPRESTORE;_CRT_SECURE_NO_WARNINGS;KS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4711;4574;4100;4127;4668;4255;4706;4710;4820</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@ -1,552 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download OPENSSL", "..\win32\Download OPENSSL.2015.vcxproj", "{D578E676-7EC8-4548-BD8B-845C635F14AD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay32", "..\win32\openssl\libeay32.2015.vcxproj", "{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay32", "..\win32\openssl\ssleay32.2015.vcxproj", "{B4B62169-5AD4-4559-8707-3D933AC5DB39}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libks", "..\libks\libks.vcxproj", "{70D178D8-1100-4152-86C0-809A91CFF832}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libblade", "libblade.vcxproj", "{A89D6D18-6203-4149-9051-F8E798E7A3E7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "..\win32\libsodium\libsodium.2015.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig", "..\win32\libconfig\libconfig.2015.vcxproj", "{1A234565-926D-49B2-83E4-D56E0C38C9F2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "switchblade", "switchblade\switchblade.vcxproj", "{8330E669-77F3-4F70-A275-6F7BABE050A7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testcli", "test\testcli.vcxproj", "{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testcon", "test\testcon.vcxproj", "{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openssl", "..\win32\openssl\openssl.2015.vcxproj", "{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "civetweb", "..\win32\civetweb\civetweb.2015.vcxproj", "{1FAAE8B0-C134-436D-9B13-74C16517FC03}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duktape_lib", "..\win32\civetweb\duktape_lib.vcxproj", "{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}"
ProjectSection(ProjectDependencies) = postProject
{B9B7455D-F109-42BD-AD0A-98489B53FCF3} = {B9B7455D-F109-42BD-AD0A-98489B53FCF3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua_lib", "..\win32\civetweb\lua_lib.vcxproj", "{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}"
ProjectSection(ProjectDependencies) = postProject
{B9B7455D-F109-42BD-AD0A-98489B53FCF3} = {B9B7455D-F109-42BD-AD0A-98489B53FCF3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download libconfig", "..\win32\Download libconfig.2015.vcxproj", "{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download libsodium", "..\win32\Download libsodium.2015.vcxproj", "{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download civetweb", "..\win32\Download civetweb.2015.vcxproj", "{B9B7455D-F109-42BD-AD0A-98489B53FCF3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download PCRE", "..\win32\Download PCRE.2015.vcxproj", "{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpcre", "..\win32\pcre\libpcre.2015.vcxproj", "{8D04B550-D240-4A44-8A18-35DA3F7038D9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpcre Generate pcre_chartables.c", "..\win32\pcre\pcre_chartables.c.2015.vcxproj", "{1CED5987-A529-46DC-B30F-870D85FF9C94}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug DLL|x64 = Debug DLL|x64
Debug DLL|x86 = Debug DLL|x86
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
DebugDLL|x64 = DebugDLL|x64
DebugDLL|x86 = DebugDLL|x86
Release DLL|x64 = Release DLL|x64
Release DLL|x86 = Release DLL|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
ReleaseDLL|x64 = ReleaseDLL|x64
ReleaseDLL|x86 = ReleaseDLL|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug DLL|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug DLL|x64.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug DLL|x86.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug DLL|x86.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x64.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x64.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x86.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x86.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.DebugDLL|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.DebugDLL|x64.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.DebugDLL|x86.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.DebugDLL|x86.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release DLL|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release DLL|x64.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release DLL|x86.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release DLL|x86.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x64.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x86.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x86.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.ReleaseDLL|x64.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.ReleaseDLL|x86.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug DLL|x64.ActiveCfg = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug DLL|x64.Build.0 = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug DLL|x86.ActiveCfg = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug DLL|x86.Build.0 = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x64.ActiveCfg = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x64.Build.0 = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x86.ActiveCfg = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x86.Build.0 = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.DebugDLL|x64.ActiveCfg = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.DebugDLL|x64.Build.0 = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.DebugDLL|x86.ActiveCfg = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.DebugDLL|x86.Build.0 = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release DLL|x64.ActiveCfg = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release DLL|x64.Build.0 = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release DLL|x86.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release DLL|x86.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x64.ActiveCfg = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x64.Build.0 = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x86.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x86.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.ReleaseDLL|x64.ActiveCfg = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.ReleaseDLL|x64.Build.0 = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.ReleaseDLL|x86.Build.0 = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug DLL|x64.ActiveCfg = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug DLL|x64.Build.0 = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug DLL|x86.ActiveCfg = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug DLL|x86.Build.0 = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x64.ActiveCfg = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x64.Build.0 = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x86.ActiveCfg = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x86.Build.0 = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.DebugDLL|x64.ActiveCfg = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.DebugDLL|x64.Build.0 = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.DebugDLL|x86.ActiveCfg = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.DebugDLL|x86.Build.0 = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release DLL|x64.ActiveCfg = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release DLL|x64.Build.0 = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release DLL|x86.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release DLL|x86.Build.0 = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x64.ActiveCfg = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x64.Build.0 = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x86.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x86.Build.0 = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.ReleaseDLL|x64.ActiveCfg = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.ReleaseDLL|x64.Build.0 = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.ReleaseDLL|x86.Build.0 = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug DLL|x64.ActiveCfg = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug DLL|x64.Build.0 = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug DLL|x86.ActiveCfg = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug DLL|x86.Build.0 = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x64.ActiveCfg = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x64.Build.0 = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x86.ActiveCfg = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x86.Build.0 = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.DebugDLL|x64.ActiveCfg = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.DebugDLL|x64.Build.0 = Debug|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.DebugDLL|x86.ActiveCfg = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.DebugDLL|x86.Build.0 = Debug|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Release DLL|x64.ActiveCfg = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Release DLL|x64.Build.0 = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Release DLL|x86.ActiveCfg = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Release DLL|x86.Build.0 = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Release|x64.ActiveCfg = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Release|x64.Build.0 = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.Release|x86.ActiveCfg = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.Release|x86.Build.0 = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.ReleaseDLL|x64.ActiveCfg = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.ReleaseDLL|x64.Build.0 = Release|x64
{70D178D8-1100-4152-86C0-809A91CFF832}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{70D178D8-1100-4152-86C0-809A91CFF832}.ReleaseDLL|x86.Build.0 = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug DLL|x64.ActiveCfg = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug DLL|x64.Build.0 = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug DLL|x86.ActiveCfg = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug DLL|x86.Build.0 = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug|x64.ActiveCfg = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug|x64.Build.0 = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug|x86.ActiveCfg = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Debug|x86.Build.0 = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.DebugDLL|x64.ActiveCfg = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.DebugDLL|x64.Build.0 = Debug|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.DebugDLL|x86.ActiveCfg = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.DebugDLL|x86.Build.0 = Debug|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release DLL|x64.ActiveCfg = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release DLL|x64.Build.0 = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release DLL|x86.ActiveCfg = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release DLL|x86.Build.0 = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release|x64.ActiveCfg = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release|x64.Build.0 = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release|x86.ActiveCfg = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.Release|x86.Build.0 = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.ReleaseDLL|x64.ActiveCfg = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.ReleaseDLL|x64.Build.0 = Release|x64
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{A89D6D18-6203-4149-9051-F8E798E7A3E7}.ReleaseDLL|x86.Build.0 = Release|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x64.ActiveCfg = Debug|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x64.Build.0 = Debug|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x86.ActiveCfg = DebugDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x86.Build.0 = DebugDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = Debug|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = Debug|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.ActiveCfg = Debug|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.Build.0 = Debug|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.Build.0 = DebugDLL|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x64.ActiveCfg = Release|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x64.Build.0 = Release|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x86.ActiveCfg = ReleaseDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x86.Build.0 = ReleaseDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = Release|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = Release|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.ActiveCfg = Release|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.Build.0 = Release|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x64.ActiveCfg = Debug|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x64.Build.0 = Debug|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x86.ActiveCfg = DebugDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x86.Build.0 = DebugDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.ActiveCfg = Debug|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.Build.0 = Debug|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x86.ActiveCfg = Debug|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x86.Build.0 = Debug|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.DebugDLL|x64.Build.0 = DebugDLL|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x64.ActiveCfg = Release|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x64.Build.0 = Release|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x86.ActiveCfg = ReleaseDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x86.Build.0 = ReleaseDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.ActiveCfg = Release|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.Build.0 = Release|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x86.ActiveCfg = Release|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x86.Build.0 = Release|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x64.ActiveCfg = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x64.Build.0 = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x86.ActiveCfg = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x86.Build.0 = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug|x64.ActiveCfg = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug|x64.Build.0 = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug|x86.ActiveCfg = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug|x86.Build.0 = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.DebugDLL|x64.ActiveCfg = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.DebugDLL|x64.Build.0 = Debug|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.DebugDLL|x86.ActiveCfg = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.DebugDLL|x86.Build.0 = Debug|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release DLL|x64.ActiveCfg = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release DLL|x64.Build.0 = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release DLL|x86.ActiveCfg = Release|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release DLL|x86.Build.0 = Release|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release|x64.ActiveCfg = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release|x64.Build.0 = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release|x86.ActiveCfg = Release|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.Release|x86.Build.0 = Release|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.ReleaseDLL|x64.ActiveCfg = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.ReleaseDLL|x64.Build.0 = Release|x64
{8330E669-77F3-4F70-A275-6F7BABE050A7}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{8330E669-77F3-4F70-A275-6F7BABE050A7}.ReleaseDLL|x86.Build.0 = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug DLL|x64.ActiveCfg = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug DLL|x64.Build.0 = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug DLL|x86.ActiveCfg = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug DLL|x86.Build.0 = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug|x64.ActiveCfg = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug|x64.Build.0 = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug|x86.ActiveCfg = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Debug|x86.Build.0 = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.DebugDLL|x64.ActiveCfg = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.DebugDLL|x64.Build.0 = Debug|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.DebugDLL|x86.ActiveCfg = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.DebugDLL|x86.Build.0 = Debug|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release DLL|x64.ActiveCfg = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release DLL|x64.Build.0 = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release DLL|x86.ActiveCfg = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release DLL|x86.Build.0 = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release|x64.ActiveCfg = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release|x64.Build.0 = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release|x86.ActiveCfg = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.Release|x86.Build.0 = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.ReleaseDLL|x64.ActiveCfg = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.ReleaseDLL|x64.Build.0 = Release|x64
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}.ReleaseDLL|x86.Build.0 = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug DLL|x64.ActiveCfg = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug DLL|x64.Build.0 = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug DLL|x86.ActiveCfg = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug DLL|x86.Build.0 = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug|x64.ActiveCfg = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug|x64.Build.0 = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug|x86.ActiveCfg = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Debug|x86.Build.0 = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.DebugDLL|x64.ActiveCfg = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.DebugDLL|x64.Build.0 = Debug|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.DebugDLL|x86.ActiveCfg = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.DebugDLL|x86.Build.0 = Debug|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release DLL|x64.ActiveCfg = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release DLL|x64.Build.0 = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release DLL|x86.ActiveCfg = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release DLL|x86.Build.0 = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release|x64.ActiveCfg = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release|x64.Build.0 = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release|x86.ActiveCfg = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.Release|x86.Build.0 = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.ReleaseDLL|x64.ActiveCfg = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.ReleaseDLL|x64.Build.0 = Release|x64
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{D67EEF66-B323-4BCF-9E3C-3A640B9949B7}.ReleaseDLL|x86.Build.0 = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug DLL|x64.ActiveCfg = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug DLL|x64.Build.0 = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug DLL|x86.ActiveCfg = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug DLL|x86.Build.0 = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x64.ActiveCfg = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x64.Build.0 = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x86.ActiveCfg = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x86.Build.0 = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.DebugDLL|x64.ActiveCfg = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.DebugDLL|x64.Build.0 = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.DebugDLL|x86.ActiveCfg = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.DebugDLL|x86.Build.0 = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release DLL|x64.ActiveCfg = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release DLL|x64.Build.0 = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release DLL|x86.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release DLL|x86.Build.0 = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x64.ActiveCfg = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x64.Build.0 = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x86.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x86.Build.0 = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.ReleaseDLL|x64.ActiveCfg = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.ReleaseDLL|x64.Build.0 = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.ReleaseDLL|x86.Build.0 = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug DLL|x64.ActiveCfg = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug DLL|x64.Build.0 = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug DLL|x86.ActiveCfg = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug DLL|x86.Build.0 = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug|x64.ActiveCfg = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug|x64.Build.0 = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug|x86.ActiveCfg = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Debug|x86.Build.0 = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.DebugDLL|x64.ActiveCfg = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.DebugDLL|x64.Build.0 = Debug|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.DebugDLL|x86.ActiveCfg = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.DebugDLL|x86.Build.0 = Debug|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release DLL|x64.ActiveCfg = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release DLL|x64.Build.0 = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release DLL|x86.ActiveCfg = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release DLL|x86.Build.0 = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release|x64.ActiveCfg = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release|x64.Build.0 = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release|x86.ActiveCfg = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.Release|x86.Build.0 = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.ReleaseDLL|x64.ActiveCfg = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.ReleaseDLL|x64.Build.0 = Release|x64
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{1FAAE8B0-C134-436D-9B13-74C16517FC03}.ReleaseDLL|x86.Build.0 = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug DLL|x64.ActiveCfg = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug DLL|x64.Build.0 = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug DLL|x86.ActiveCfg = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug DLL|x86.Build.0 = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug|x64.ActiveCfg = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug|x64.Build.0 = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug|x86.ActiveCfg = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Debug|x86.Build.0 = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.DebugDLL|x64.ActiveCfg = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.DebugDLL|x64.Build.0 = Debug|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.DebugDLL|x86.ActiveCfg = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.DebugDLL|x86.Build.0 = Debug|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release DLL|x64.ActiveCfg = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release DLL|x64.Build.0 = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release DLL|x86.ActiveCfg = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release DLL|x86.Build.0 = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release|x64.ActiveCfg = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release|x64.Build.0 = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release|x86.ActiveCfg = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.Release|x86.Build.0 = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.ReleaseDLL|x64.ActiveCfg = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.ReleaseDLL|x64.Build.0 = Release|x64
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{0A11689C-DB6A-4BF6-97B2-AD32DB863FBD}.ReleaseDLL|x86.Build.0 = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug DLL|x64.ActiveCfg = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug DLL|x64.Build.0 = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug DLL|x86.ActiveCfg = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug DLL|x86.Build.0 = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug|x64.ActiveCfg = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug|x64.Build.0 = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug|x86.ActiveCfg = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Debug|x86.Build.0 = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.DebugDLL|x64.ActiveCfg = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.DebugDLL|x64.Build.0 = Debug|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.DebugDLL|x86.ActiveCfg = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.DebugDLL|x86.Build.0 = Debug|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release DLL|x64.ActiveCfg = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release DLL|x64.Build.0 = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release DLL|x86.ActiveCfg = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release DLL|x86.Build.0 = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release|x64.ActiveCfg = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release|x64.Build.0 = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release|x86.ActiveCfg = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.Release|x86.Build.0 = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.ReleaseDLL|x64.ActiveCfg = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.ReleaseDLL|x64.Build.0 = Release|x64
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{8F5E5D77-D269-4665-9E27-1045DA6CF0D8}.ReleaseDLL|x86.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug DLL|x64.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug DLL|x64.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug DLL|x86.ActiveCfg = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug DLL|x86.Build.0 = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug|x64.ActiveCfg = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug|x64.Build.0 = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug|x86.ActiveCfg = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Debug|x86.Build.0 = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.DebugDLL|x64.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.DebugDLL|x64.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.DebugDLL|x86.ActiveCfg = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.DebugDLL|x86.Build.0 = Debug|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release DLL|x64.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release DLL|x64.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release DLL|x86.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release DLL|x86.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release|x64.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release|x64.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release|x86.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.Release|x86.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.ReleaseDLL|x64.Build.0 = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{4AB0A14F-F65F-4C18-AAEC-AC76E2BE07DA}.ReleaseDLL|x86.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug DLL|x64.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug DLL|x64.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug DLL|x86.ActiveCfg = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug DLL|x86.Build.0 = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug|x64.ActiveCfg = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug|x64.Build.0 = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug|x86.ActiveCfg = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Debug|x86.Build.0 = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.DebugDLL|x64.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.DebugDLL|x64.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.DebugDLL|x86.ActiveCfg = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.DebugDLL|x86.Build.0 = Debug|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release DLL|x64.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release DLL|x64.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release DLL|x86.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release DLL|x86.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release|x64.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release|x64.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release|x86.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.Release|x86.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.ReleaseDLL|x64.Build.0 = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{96848DD5-1451-4A88-87FA-FC6B7C7D1E1D}.ReleaseDLL|x86.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug DLL|x64.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug DLL|x64.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug DLL|x86.ActiveCfg = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug DLL|x86.Build.0 = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug|x64.ActiveCfg = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug|x64.Build.0 = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug|x86.ActiveCfg = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Debug|x86.Build.0 = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.DebugDLL|x64.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.DebugDLL|x64.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.DebugDLL|x86.ActiveCfg = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.DebugDLL|x86.Build.0 = Debug|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release DLL|x64.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release DLL|x64.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release DLL|x86.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release DLL|x86.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release|x64.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release|x64.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release|x86.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.Release|x86.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.ReleaseDLL|x64.Build.0 = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{B9B7455D-F109-42BD-AD0A-98489B53FCF3}.ReleaseDLL|x86.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x64.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x64.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x86.ActiveCfg = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x86.Build.0 = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x64.ActiveCfg = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x64.Build.0 = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x86.ActiveCfg = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x86.Build.0 = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.DebugDLL|x64.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.DebugDLL|x64.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.DebugDLL|x86.ActiveCfg = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.DebugDLL|x86.Build.0 = Debug|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x64.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x64.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x86.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x86.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x64.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x64.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x86.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x86.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.ReleaseDLL|x64.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.ReleaseDLL|x64.Build.0 = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.ReleaseDLL|x86.Build.0 = Release|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug DLL|x64.Build.0 = Debug DLL|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug DLL|x86.ActiveCfg = Debug DLL|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug DLL|x86.Build.0 = Debug DLL|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug|x64.ActiveCfg = Debug|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug|x64.Build.0 = Debug|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug|x86.ActiveCfg = Debug|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Debug|x86.Build.0 = Debug|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.DebugDLL|x64.ActiveCfg = Debug|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.DebugDLL|x64.Build.0 = Debug|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.DebugDLL|x86.ActiveCfg = Debug|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.DebugDLL|x86.Build.0 = Debug|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release DLL|x64.ActiveCfg = Release DLL|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release DLL|x64.Build.0 = Release DLL|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release DLL|x86.ActiveCfg = Release DLL|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release DLL|x86.Build.0 = Release DLL|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release|x64.ActiveCfg = Release|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release|x64.Build.0 = Release|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release|x86.ActiveCfg = Release|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.Release|x86.Build.0 = Release|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.ReleaseDLL|x64.ActiveCfg = Release|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.ReleaseDLL|x64.Build.0 = Release|x64
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{8D04B550-D240-4A44-8A18-35DA3F7038D9}.ReleaseDLL|x86.Build.0 = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug DLL|x64.ActiveCfg = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug DLL|x64.Build.0 = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug DLL|x86.ActiveCfg = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug DLL|x86.Build.0 = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|x64.ActiveCfg = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|x64.Build.0 = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|x86.ActiveCfg = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|x86.Build.0 = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.DebugDLL|x64.ActiveCfg = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.DebugDLL|x64.Build.0 = Debug|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.DebugDLL|x86.ActiveCfg = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.DebugDLL|x86.Build.0 = Debug|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release DLL|x64.ActiveCfg = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release DLL|x64.Build.0 = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release DLL|x86.ActiveCfg = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release DLL|x86.Build.0 = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|x64.ActiveCfg = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|x64.Build.0 = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|x86.ActiveCfg = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|x86.Build.0 = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.ReleaseDLL|x64.ActiveCfg = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.ReleaseDLL|x64.Build.0 = Release|x64
{1CED5987-A529-46DC-B30F-870D85FF9C94}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.ReleaseDLL|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,246 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{A89D6D18-6203-4149-9051-F8E798E7A3E7}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\..\w32\openssl.props" />
<Import Project="libblade.props" />
<Import Project="..\..\w32\sodium.props" />
<Import Project="..\..\w32\config.props" />
<Import Project="..\..\w32\civetweb.props" />
<Import Project="..\..\w32\pcre.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<CodeAnalysisRuleSet>C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>
</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<CodeAnalysisRuleSet>C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702;4456;4242;4457;4459;4244;4324;4204;4388;4245;4267</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>Rpcrt4.lib;Crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>EnableAllWarnings</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702;4456;4242;4457;4459;4244;4324;4204;4388;4245;4267</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Rpcrt4.lib;Crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702;4456;4242;4457;4459;4244;4324;4204;4388;4245;4267</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<EnablePREfast>true</EnablePREfast>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>Debug</GenerateDebugInformation>
<AdditionalDependencies>Rpcrt4.lib;Crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>EnableAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702;4456;4242;4457;4459;4244;4324;4204;4388;4245;4267</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>Rpcrt4.lib;Crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\blade.c" />
<ClCompile Include="src\blade_channel.c" />
<ClCompile Include="src\blade_connection.c" />
<ClCompile Include="src\blade_connectionmgr.c" />
<ClCompile Include="src\blade_identity.c" />
<ClCompile Include="src\blade_mastermgr.c" />
<ClCompile Include="src\blade_restmgr.c" />
<ClCompile Include="src\blade_routemgr.c" />
<ClCompile Include="src\blade_rpc.c" />
<ClCompile Include="src\blade_protocol.c" />
<ClCompile Include="src\blade_rpcmgr.c" />
<ClCompile Include="src\blade_sessionmgr.c" />
<ClCompile Include="src\blade_subscription.c" />
<ClCompile Include="src\blade_subscriptionmgr.c" />
<ClCompile Include="src\blade_transportmgr.c" />
<ClCompile Include="src\blade_transport_wss.c" />
<ClCompile Include="src\blade_session.c" />
<ClCompile Include="src\blade_stack.c" />
<ClCompile Include="src\blade_transport.c" />
<ClCompile Include="src\blade_tuple.c" />
<ClCompile Include="src\blade_web.c" />
<ClCompile Include="src\unqlite.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\include\blade.h" />
<ClInclude Include="src\include\blade_channel.h" />
<ClInclude Include="src\include\blade_connection.h" />
<ClInclude Include="src\include\blade_connectionmgr.h" />
<ClInclude Include="src\include\blade_identity.h" />
<ClInclude Include="src\include\blade_mastermgr.h" />
<ClInclude Include="src\include\blade_restmgr.h" />
<ClInclude Include="src\include\blade_routemgr.h" />
<ClInclude Include="src\include\blade_rpc.h" />
<ClInclude Include="src\include\blade_protocol.h" />
<ClInclude Include="src\include\blade_rpcmgr.h" />
<ClInclude Include="src\include\blade_sessionmgr.h" />
<ClInclude Include="src\include\blade_subscription.h" />
<ClInclude Include="src\include\blade_subscriptionmgr.h" />
<ClInclude Include="src\include\blade_transportmgr.h" />
<ClInclude Include="src\include\blade_transport_wss.h" />
<ClInclude Include="src\include\blade_session.h" />
<ClInclude Include="src\include\blade_stack.h" />
<ClInclude Include="src\include\blade_transport.h" />
<ClInclude Include="src\include\blade_tuple.h" />
<ClInclude Include="src\include\blade_types.h" />
<ClInclude Include="src\include\blade_web.h" />
<ClInclude Include="src\include\unqlite.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libks\libks.vcxproj">
<Project>{70d178d8-1100-4152-86c0-809a91cff832}</Project>
</ProjectReference>
<ProjectReference Include="..\win32\civetweb\civetweb.2015.vcxproj">
<Project>{1faae8b0-c134-436d-9b13-74c16517fc03}</Project>
</ProjectReference>
<ProjectReference Include="..\win32\libconfig\libconfig.2015.vcxproj">
<Project>{1a234565-926d-49b2-83e4-d56e0c38c9f2}</Project>
</ProjectReference>
<ProjectReference Include="..\win32\libsodium\libsodium.2015.vcxproj">
<Project>{a185b162-6cb6-4502-b03f-b56f7699a8d9}</Project>
</ProjectReference>
<ProjectReference Include="..\win32\pcre\libpcre.2015.vcxproj">
<Project>{8d04b550-d240-4a44-8a18-35da3f7038d9}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,156 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\unqlite.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_connection.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_identity.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_session.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_stack.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_transport.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_transport_wss.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_protocol.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_rpc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_subscription.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_transportmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_rpcmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_routemgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_subscriptionmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_mastermgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_connectionmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_sessionmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_tuple.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_channel.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_restmgr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\blade_web.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\include\unqlite.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_connection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_identity.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_session.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_stack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_transport.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_transport_wss.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_protocol.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_rpc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_subscription.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_transportmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_rpcmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_routemgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_subscriptionmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_mastermgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_connectionmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_sessionmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_tuple.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_channel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_restmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\blade_web.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
KS_DECLARE(ks_status_t) blade_init(void)
{
ks_status_t ret = ks_init();
if (ret == KS_STATUS_SUCCESS && mg_init_library(0xFFu) == 0) ret = KS_STATUS_FAIL;
return ret;
}
KS_DECLARE(ks_status_t) blade_shutdown(void)
{
ks_status_t ret = ks_shutdown();
mg_exit_library();
#ifdef _WINDOWS_
_CrtDumpMemoryLeaks();
#endif
return ret;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,181 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_channel_s {
const char *name;
blade_channel_flags_t flags;
ks_rwl_t *lock;
ks_hash_t *authorizations;
};
static void blade_channel_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_channel_t *bc = (blade_channel_t *)ptr;
ks_assert(bc);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
if (bc->name) ks_pool_free(&bc->name);
if (bc->lock) ks_rwl_destroy(&bc->lock);
if (bc->authorizations) ks_hash_destroy(&bc->authorizations);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name, blade_channel_flags_t flags)
{
blade_channel_t *bc = NULL;
ks_assert(bcP);
ks_assert(pool);
ks_assert(name);
bc = ks_pool_alloc(pool, sizeof(blade_channel_t));
bc->name = ks_pstrdup(pool, name);
bc->flags = flags;
ks_rwl_create(&bc->lock, pool);
ks_assert(bc->lock);
ks_hash_create(&bc->authorizations, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bc->authorizations);
ks_pool_set_cleanup(bc, NULL, blade_channel_cleanup);
*bcP = bc;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_channel_destroy(blade_channel_t **bcP)
{
ks_assert(bcP);
ks_assert(*bcP);
ks_pool_free(bcP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_channel_name_get(blade_channel_t *bc)
{
ks_assert(bc);
return bc->name;
}
KS_DECLARE(blade_channel_flags_t) blade_channel_flags_get(blade_channel_t *bc)
{
ks_assert(bc);
return bc->flags;
}
KS_DECLARE(ks_status_t) blade_channel_read_lock(blade_channel_t *bc)
{
ks_assert(bc);
return ks_rwl_read_lock(bc->lock);
}
KS_DECLARE(ks_status_t) blade_channel_read_unlock(blade_channel_t *bc)
{
ks_assert(bc);
return ks_rwl_read_unlock(bc->lock);
}
KS_DECLARE(ks_status_t) blade_channel_write_lock(blade_channel_t *bc)
{
ks_assert(bc);
return ks_rwl_write_lock(bc->lock);
}
KS_DECLARE(ks_status_t) blade_channel_write_unlock(blade_channel_t *bc)
{
ks_assert(bc);
return ks_rwl_write_unlock(bc->lock);
}
KS_DECLARE(ks_bool_t) blade_channel_authorization_verify(blade_channel_t *bc, const char *target)
{
ks_bool_t authorized = KS_FALSE;
ks_assert(bc);
ks_assert(target);
authorized = (ks_bool_t)(uintptr_t)ks_hash_search(bc->authorizations, (void *)target, KS_READLOCKED);
ks_hash_read_unlock(bc->authorizations);
return authorized;
}
KS_DECLARE(ks_status_t) blade_channel_authorization_add(blade_channel_t *bc, const char *target)
{
ks_assert(bc);
ks_assert(target);
ks_hash_insert(bc->authorizations, (void *)ks_pstrdup(ks_pool_get(bc), target), (void *)KS_TRUE);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_channel_authorization_remove(blade_channel_t *bc, const char *target)
{
ks_bool_t ret = KS_FALSE;
ks_assert(bc);
ks_assert(target);
if (ks_hash_remove(bc->authorizations, (void *)target)) {
ret = KS_TRUE;
}
return ret;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,481 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_connection_s {
blade_handle_t *handle;
void *transport_data;
blade_transport_callbacks_t *transport_callbacks;
blade_connection_direction_t direction;
volatile blade_connection_state_t state;
ks_cond_t *cond;
const char *id;
ks_rwl_t *lock;
ks_q_t *sending;
const char *session;
};
void *blade_connection_state_thread(ks_thread_t *thread, void *data);
ks_status_t blade_connection_onstate_startup(blade_connection_t *bc);
ks_status_t blade_connection_onstate_shutdown(blade_connection_t *bc);
ks_status_t blade_connection_onstate_run(blade_connection_t *bc);
static void blade_connection_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_connection_t *bc = (blade_connection_t *)ptr;
ks_assert(bc);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
blade_connection_shutdown(bc);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP, blade_handle_t *bh)
{
blade_connection_t *bc = NULL;
ks_pool_t *pool = NULL;
uuid_t id;
ks_assert(bcP);
ks_assert(bh);
ks_pool_open(&pool);
ks_assert(pool);
bc = ks_pool_alloc(pool, sizeof(blade_connection_t));
bc->handle = bh;
ks_cond_create(&bc->cond, pool);
ks_assert(bc->cond);
ks_uuid(&id);
bc->id = ks_uuid_str(pool, &id);
ks_assert(bc->id);
ks_rwl_create(&bc->lock, pool);
ks_assert(bc->lock);
ks_q_create(&bc->sending, pool, 0);
ks_assert(bc->sending);
ks_pool_set_cleanup(bc, NULL, blade_connection_cleanup);
ks_log(KS_LOG_DEBUG, "Created\n");
*bcP = bc;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP)
{
blade_connection_t *bc = NULL;
ks_pool_t *pool = NULL;
ks_assert(bcP);
ks_assert(*bcP);
bc = *bcP;
*bcP = NULL;
pool = ks_pool_get(bc);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc, blade_connection_direction_t direction)
{
blade_handle_t *bh = NULL;
ks_assert(bc);
bh = blade_connection_handle_get(bc);
bc->direction = direction;
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_NONE);
if (ks_thread_pool_add_job(blade_handle_tpool_get(bh), blade_connection_state_thread, bc) != KS_STATUS_SUCCESS) {
// @todo error logging
return KS_STATUS_FAIL;
}
ks_log(KS_LOG_DEBUG, "Started\n");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc)
{
cJSON *json = NULL;
ks_assert(bc);
blade_connectionmgr_connection_remove(blade_handle_connectionmgr_get(bc->handle), bc);
while (ks_q_trypop(bc->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
ks_log(KS_LOG_DEBUG, "Stopped\n");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_connection_handle_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->handle;
}
KS_DECLARE(const char *) blade_connection_id_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->id;
}
KS_DECLARE(ks_status_t) blade_connection_read_lock(blade_connection_t *bc, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bc);
if (block) ret = ks_rwl_read_lock(bc->lock);
else ret = ks_rwl_try_read_lock(bc->lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_connection_read_unlock(blade_connection_t *bc)
{
ks_assert(bc);
return ks_rwl_read_unlock(bc->lock);
}
KS_DECLARE(ks_status_t) blade_connection_write_lock(blade_connection_t *bc, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bc);
if (block) ret = ks_rwl_write_lock(bc->lock);
else ret = ks_rwl_try_write_lock(bc->lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_connection_write_unlock(blade_connection_t *bc)
{
ks_assert(bc);
return ks_rwl_write_unlock(bc->lock);
}
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->transport_data;
}
KS_DECLARE(void) blade_connection_transport_set(blade_connection_t *bc, void *transport_data, blade_transport_callbacks_t *transport_callbacks)
{
ks_assert(bc);
ks_assert(transport_data);
ks_assert(transport_callbacks);
bc->transport_data = transport_data;
bc->transport_callbacks = transport_callbacks;
}
blade_transport_state_callback_t blade_connection_state_callback_lookup(blade_connection_t *bc, blade_connection_state_t state)
{
blade_transport_state_callback_t callback = NULL;
ks_assert(bc);
switch (state) {
case BLADE_CONNECTION_STATE_SHUTDOWN:
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_shutdown_inbound;
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_shutdown_outbound;
break;
case BLADE_CONNECTION_STATE_STARTUP:
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_startup_inbound;
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_startup_outbound;
break;
case BLADE_CONNECTION_STATE_RUN:
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_run_inbound;
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_run_outbound;
break;
default: break;
}
return callback;
}
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state)
{
blade_transport_state_callback_t callback = NULL;
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
ks_assert(bc);
ks_cond_lock(bc->cond);
callback = blade_connection_state_callback_lookup(bc, state);
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_PRE);
bc->state = state;
ks_cond_unlock(bc->cond);
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
ks_cond_try_signal(bc->cond);
}
KS_DECLARE(blade_connection_state_t) blade_connection_state_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->state;
}
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc)
{
ks_assert(bc);
if (bc->state != BLADE_CONNECTION_STATE_SHUTDOWN && bc->state != BLADE_CONNECTION_STATE_CLEANUP) {
ks_log(KS_LOG_DEBUG, "Connection (%s) disconnecting\n", bc->id);
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_SHUTDOWN);
}
}
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, cJSON *json)
{
cJSON *json_copy = NULL;
ks_assert(bc);
ks_assert(json);
json_copy = cJSON_Duplicate(json, 1);
return ks_q_push(bc->sending, json_copy);
}
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, cJSON **json)
{
ks_assert(bc);
ks_assert(json);
return ks_q_trypop(bc->sending, (void **)json);
}
KS_DECLARE(const char *) blade_connection_session_get(blade_connection_t *bc)
{
ks_assert(bc);
return bc->session;
}
KS_DECLARE(void) blade_connection_session_set(blade_connection_t *bc, const char *id)
{
ks_assert(bc);
if (bc->session) ks_pool_free(&bc->session);
bc->session = ks_pstrdup(ks_pool_get(bc), id);
}
void *blade_connection_state_thread(ks_thread_t *thread, void *data)
{
blade_connection_t *bc = NULL;
blade_connection_state_t state;
ks_bool_t shutdown = KS_FALSE;
ks_assert(thread);
ks_assert(data);
bc = (blade_connection_t *)data;
ks_cond_lock(bc->cond);
while (!shutdown) {
// Entering the call below, the mutex is expected to be locked and will be unlocked by the call
ks_cond_timedwait(bc->cond, 100);
// Leaving the call above, the mutex will be locked after being signalled, timing out, or woken up for any reason
state = bc->state;
switch (state) {
case BLADE_CONNECTION_STATE_SHUTDOWN:
blade_connection_onstate_shutdown(bc);
shutdown = KS_TRUE;
break;
case BLADE_CONNECTION_STATE_STARTUP:
blade_connection_onstate_startup(bc);
break;
case BLADE_CONNECTION_STATE_RUN:
blade_connection_onstate_run(bc);
break;
default: break;
}
}
ks_cond_unlock(bc->cond);
blade_connection_destroy(&bc);
return NULL;
}
ks_status_t blade_connection_onstate_startup(blade_connection_t *bc)
{
blade_transport_state_callback_t callback = NULL;
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
ks_assert(bc);
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_STARTUP);
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
else if (hook == BLADE_CONNECTION_STATE_HOOK_SUCCESS) {
// @todo this is adding a second lock, since we keep it locked in the callback to allow finishing, we don't want get locking here...
// or just unlock twice...
blade_session_t *bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bc->handle), bc->session);
ks_assert(bs); // should not happen because bs should still be locked
blade_session_connection_set(bs, bc->id);
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_RUN);
blade_session_state_set(bs, BLADE_SESSION_STATE_STARTUP); // if reconnecting, we go from RUN back to STARTUP for the purpose of the reconnect which will return to RUN
blade_session_read_unlock(bs); // unlock the session we locked obtaining it above
blade_session_read_unlock(bs); // unlock the session we expect to be locked during the callback to ensure we can finish attaching
}
return KS_STATUS_SUCCESS;
}
ks_status_t blade_connection_onstate_shutdown(blade_connection_t *bc)
{
blade_transport_state_callback_t callback = NULL;
ks_assert(bc);
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_SHUTDOWN);
if (callback) callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
if (bc->session) {
blade_session_t *bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bc->handle), bc->session);
ks_assert(bs);
blade_session_connection_set(bs, NULL);
blade_session_read_unlock(bs);
// keep bc->session for later in case something triggers a reconnect later and needs the old session id for a hint
}
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_CLEANUP);
return KS_STATUS_SUCCESS;
}
ks_status_t blade_connection_onstate_run(blade_connection_t *bc)
{
blade_transport_state_callback_t callback = NULL;
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
cJSON *json = NULL;
blade_session_t *bs = NULL;
ks_bool_t done = KS_FALSE;
ks_assert(bc);
while (blade_connection_sending_pop(bc, &json) == KS_STATUS_SUCCESS && json) {
ks_status_t ret = bc->transport_callbacks->onsend(bc, json);
cJSON_Delete(json);
if (ret != KS_STATUS_SUCCESS) {
blade_connection_disconnect(bc);
break;
}
}
while (!done) {
if (bc->transport_callbacks->onreceive(bc, &json) != KS_STATUS_SUCCESS) {
blade_connection_disconnect(bc);
break;
}
if (!(done = (json == NULL))) {
if (!bs) {
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bc->handle), bc->session);
ks_assert(bs);
}
blade_session_receiving_push(bs, json);
cJSON_Delete(json);
json = NULL;
}
}
if (bs) blade_session_read_unlock(bs);
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_RUN);
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,183 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_connectionmgr_s {
blade_handle_t *handle;
ks_hash_t *connections; // id, blade_connection_t*
};
static void blade_connectionmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_connectionmgr_t *bcmgr = (blade_connectionmgr_t *)ptr;
//ks_assert(bcmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_connectionmgr_create(blade_connectionmgr_t **bcmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_connectionmgr_t *bcmgr = NULL;
ks_assert(bcmgrP);
ks_pool_open(&pool);
ks_assert(pool);
bcmgr = ks_pool_alloc(pool, sizeof(blade_connectionmgr_t));
bcmgr->handle = bh;
ks_hash_create(&bcmgr->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bcmgr->connections);
ks_pool_set_cleanup(bcmgr, NULL, blade_connectionmgr_cleanup);
*bcmgrP = bcmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connectionmgr_destroy(blade_connectionmgr_t **bcmgrP)
{
blade_connectionmgr_t *bcmgr = NULL;
ks_pool_t *pool;
ks_assert(bcmgrP);
ks_assert(*bcmgrP);
bcmgr = *bcmgrP;
*bcmgrP = NULL;
pool = ks_pool_get(bcmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_connectionmgr_handle_get(blade_connectionmgr_t *bcmgr)
{
ks_assert(bcmgr);
return bcmgr->handle;
}
KS_DECLARE(ks_status_t) blade_connectionmgr_shutdown(blade_connectionmgr_t *bcmgr)
{
ks_hash_iterator_t *it = NULL;
ks_assert(bcmgr);
ks_hash_read_lock(bcmgr->connections);
for (it = ks_hash_first(bcmgr->connections, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_connection_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
blade_connection_disconnect(value);
}
ks_hash_read_unlock(bcmgr->connections);
while (ks_hash_count(bcmgr->connections) > 0) ks_sleep_ms(100);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_connection_t *) blade_connectionmgr_connection_lookup(blade_connectionmgr_t *bcmgr, const char *id)
{
blade_connection_t *bc = NULL;
ks_assert(bcmgr);
ks_assert(id);
bc = ks_hash_search(bcmgr->connections, (void *)id, KS_READLOCKED);
if (bc) blade_connection_read_lock(bc, KS_TRUE);
ks_hash_read_unlock(bcmgr->connections);
return bc;
}
KS_DECLARE(ks_status_t) blade_connectionmgr_connection_add(blade_connectionmgr_t *bcmgr, blade_connection_t *bc)
{
char *key = NULL;
ks_assert(bcmgr);
ks_assert(bc);
key = ks_pstrdup(ks_pool_get(bcmgr), blade_connection_id_get(bc));
ks_hash_insert(bcmgr->connections, (void *)key, bc);
ks_log(KS_LOG_DEBUG, "Connection Added: %s\n", key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_connectionmgr_connection_remove(blade_connectionmgr_t *bcmgr, blade_connection_t *bc)
{
const char *id = NULL;
ks_assert(bcmgr);
ks_assert(bc);
blade_connection_write_lock(bc, KS_TRUE);
id = blade_connection_id_get(bc);
ks_hash_remove(bcmgr->connections, (void *)id);
blade_connection_write_unlock(bc);
ks_log(KS_LOG_DEBUG, "Connection Removed: %s\n", id);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,357 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_identity_s {
const char *uri;
const char *components;
const char *scheme;
const char *user;
const char *host;
const char *port;
ks_port_t portnum;
const char *path;
ks_hash_t *parameters;
};
// @todo missed a structure to use cleanup callbacks
static void blade_identity_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_identity_t *bi = (blade_identity_t *)ptr;
ks_assert(bi);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
if (bi->uri) ks_pool_free(&bi->uri);
if (bi->components) ks_pool_free(&bi->components);
if (bi->parameters) ks_hash_destroy(&bi->parameters);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool)
{
blade_identity_t *bi = NULL;
ks_assert(biP);
ks_assert(pool);
bi = ks_pool_alloc(pool, sizeof(blade_identity_t));
ks_pool_set_cleanup(bi, NULL, blade_identity_cleanup);
*biP = bi;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP)
{
ks_assert(biP);
ks_assert(*biP);
ks_pool_free(biP);
return KS_STATUS_SUCCESS;
}
void blade_identity_reset(blade_identity_t *bi)
{
ks_assert(bi);
bi->scheme = NULL;
bi->user = NULL;
bi->host = NULL;
bi->port = NULL;
bi->portnum = 0;
bi->path = NULL;
if (bi->uri) {
ks_pool_free(&bi->uri);
ks_pool_free(&bi->components);
}
if (bi->parameters) ks_hash_destroy(&bi->parameters);
}
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri)
{
ks_status_t ret = KS_STATUS_SUCCESS;
char *tmp = NULL;
char *tmp2 = NULL;
char terminator = '\0';
ks_pool_t *pool = NULL;
ks_assert(bi);
ks_assert(uri);
ks_log(KS_LOG_DEBUG, "Parsing URI: %s\n", uri);
pool = ks_pool_get(bi);
blade_identity_reset(bi);
bi->uri = ks_pstrdup(pool, uri);
bi->components = tmp = ks_pstrdup(pool, uri);
// Supported components with pseudo regex
// <scheme:[//]> [user@] <host> [:port] [/path] [;param1=value1] [;param2=value2]
// scheme is mandatory to simplify the parser for now, it must start with mandatory: <scheme>:
bi->scheme = tmp;
if (!(tmp = strchr(tmp, ':'))) {
ret = KS_STATUS_FAIL;
goto done;
}
// if found, null terminate scheme portion
*tmp++ = '\0';
// may have trailing '/' characters which are optional, this is not perfect it should probably only match a count of 0 or 2 explicitly
while (*tmp && *tmp == '/') ++tmp;
// must have more data to define at least a host
if (!*tmp) {
ret = KS_STATUS_FAIL;
goto done;
}
if (!(*bi->scheme)) {
ret = KS_STATUS_FAIL;
goto done;
}
// next component may be the user or the host, so it may start with optional: <user>@
// or it may skip to the host, which may be terminated by an optional port, optional path, optional parameters, or the end of the uri
// which means checking if an '@' appears before the next ':' for port, '/' for path, or ';' for parameters, if @ appears at all then it appears before end of the uri
// @todo need to account for host being encapsulated by '[' and ']' as in the case of an IPV6 host to distinguish from the port, but for simplicity allow any
// host to be encapsulated in which case if the string starts with a '[' here, then it MUST be the host and it MUST be terminated with the matching ']' rather than other
// optional component terminators
if (!(tmp2 = strpbrk(tmp, "@:/;"))) {
// none of the terminators are found, treat the remaining string as a host
bi->host = tmp;
goto done;
}
// grab the terminator and null terminate for the next component
terminator = *tmp2;
*tmp2++ = '\0';
if (terminator == '@') {
// if the terminator was an '@', then we have a user component before the host
bi->user = tmp;
tmp = tmp2;
if (!(*bi->user)) {
ret = KS_STATUS_FAIL;
goto done;
}
// repeat the same as above, except without looking for '@', to find only the end of the host, parsing to the same point as above if user was not found
if (!(tmp2 = strpbrk(tmp, ":/;"))) {
// none of the terminators are found, treat the remaining string as a host
bi->host = tmp;
goto done;
}
// grab the terminator and null terminate for the next component
terminator = *tmp2;
*tmp2++ = '\0';
}
// at this point the user portion has been parsed if it exists, the host portion has been terminated, and there is still data remaining to parse
// @todo need to account for host being encapsulated by '[' and ']' as in the case of an IPV6 host to distinguish from the port, but for simplicity allow any
// host to be encapsulated in which case the terminator MUST be the closing ']'
bi->host = tmp;
tmp = tmp2;
if (!(*bi->host)) {
ret = KS_STATUS_FAIL;
goto done;
}
if (terminator == ':') {
// port terminator
bi->port = tmp;
// next component must be the port, which may be terminated by an optional path, optional parameters, or the end of the uri
// which means checking if a '/' for path, or ';' for parameters
if (!(tmp2 = strpbrk(tmp, "/;"))) {
// none of the terminators are found, treat the remaining string as a port
goto done;
}
terminator = *tmp2;
*tmp2++ = '\0';
tmp = tmp2;
if (!(*bi->port)) {
ret = KS_STATUS_FAIL;
goto done;
}
// @todo sscanf bi->port into bi->portnum and validate that it is a valid port number
}
if (terminator == '/') {
// path terminator
bi->path = tmp;
// next component must be the path, which may be terminated by optional parameters, or the end of the uri
// which means checking ';' for parameters
if (!(tmp2 = strpbrk(tmp, ";"))) {
// none of the terminators are found, treat the remaining string as a path
goto done;
}
terminator = *tmp2;
*tmp2++ = '\0';
tmp = tmp2;
if (!(*bi->path)) {
ret = KS_STATUS_FAIL;
goto done;
}
}
if (terminator == ';') {
// parameter terminator
do {
char *key = NULL;
char *value = NULL;
// next component must be the parameter key, which must be terminated by mandatory '=', end of the uri is an error
// which means checking '=' for key terminator
key = tmp;
if (!(tmp = strpbrk(tmp, "="))) {
ret = KS_STATUS_FAIL;
goto done;
}
*tmp++ = '\0';
// next component must be the parameter value, which may be terminated by another parameter terminator ';', or the end of the uri
// if it is the end of the uri, then the parameter loop will be exited
value = tmp;
if ((tmp = strpbrk(tmp, ";"))) {
*tmp++ = '\0';
}
// create th parameters hash if it does not already exist and add the parameter entry to it, note the key and value are both actually part
// of the duplicated uri for components and will be cleaned up with the single string so the hash must not free the key or value itself
if (!bi->parameters) ks_hash_create(&bi->parameters, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_hash_insert(bi->parameters, (void *)key, (void *)value);
} while (tmp);
}
done:
if (ret != KS_STATUS_SUCCESS) blade_identity_reset(bi);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_identity_uri_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->uri;
}
KS_DECLARE(const char *) blade_identity_scheme_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->scheme;
}
KS_DECLARE(const char *) blade_identity_user_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->user;
}
KS_DECLARE(const char *) blade_identity_host_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->host;
}
KS_DECLARE(const char *) blade_identity_port_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->port;
}
KS_DECLARE(ks_port_t) blade_identity_portnum_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->portnum;
}
KS_DECLARE(const char *) blade_identity_path_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->path;
}
KS_DECLARE(const char *) blade_identity_parameter_lookup(blade_identity_t *bi, const char *key)
{
ks_assert(bi);
ks_assert(key);
if (!bi->parameters) return NULL;
return (const char *)ks_hash_search(bi->parameters, (void *)key, KS_UNLOCKED);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,505 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_mastermgr_s {
blade_handle_t *handle;
// @todo use a blade_mastermgr_config_t to store configuration, inline variable, with sane defaults for as much configuration as is possible
// then reuse this same pattern across all the manager types that invoke startup configuration processing
const char *master_nodeid;
// @todo how does "exclusive" play into the controllers, does "exclusive" mean only one provider can exist for a given protocol? what does non exclusive mean?
ks_hash_t *protocols;
};
static void blade_mastermgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_mastermgr_t *bmmgr = (blade_mastermgr_t *)ptr;
//ks_assert(bmmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_mastermgr_create(blade_mastermgr_t **bmmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_mastermgr_t *bmmgr = NULL;
ks_assert(bmmgrP);
ks_pool_open(&pool);
ks_assert(pool);
bmmgr = ks_pool_alloc(pool, sizeof(blade_mastermgr_t));
bmmgr->handle = bh;
ks_hash_create(&bmmgr->protocols, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bmmgr->protocols);
ks_pool_set_cleanup(bmmgr, NULL, blade_mastermgr_cleanup);
*bmmgrP = bmmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_mastermgr_destroy(blade_mastermgr_t **bmmgrP)
{
blade_mastermgr_t *bmmgr = NULL;
ks_pool_t *pool;
ks_assert(bmmgrP);
ks_assert(*bmmgrP);
bmmgr = *bmmgrP;
*bmmgrP = NULL;
pool = ks_pool_get(bmmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_mastermgr_handle_get(blade_mastermgr_t *bmmgr)
{
ks_assert(bmmgr);
return bmmgr->handle;
}
ks_status_t blade_mastermgr_config(blade_mastermgr_t *bmmgr, config_setting_t *config)
{
ks_pool_t *pool = NULL;
config_setting_t *master = NULL;
config_setting_t *master_nodeid = NULL;
const char *nodeid = NULL;
ks_assert(bmmgr);
pool = ks_pool_get(bmmgr);
if (!config_setting_is_group(config)) {
ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
return KS_STATUS_FAIL;
}
master = config_setting_get_member(config, "master");
if (master) {
master_nodeid = config_setting_lookup(master, "nodeid");
if (!master_nodeid) return KS_STATUS_FAIL;
if (config_setting_type(master_nodeid) != CONFIG_TYPE_STRING) return KS_STATUS_FAIL;
nodeid = config_setting_get_string(master_nodeid);
}
if (master) {
bmmgr->master_nodeid = ks_pstrdup(pool, nodeid);
ks_log(KS_LOG_DEBUG, "Configured\n");
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config_setting_t *config)
{
ks_assert(bmmgr);
if (blade_mastermgr_config(bmmgr, config) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_mastermgr_config failed\n");
return KS_STATUS_FAIL;
}
if (bmmgr->master_nodeid) {
blade_routemgr_local_set(blade_handle_routemgr_get(bmmgr->handle), bmmgr->master_nodeid);
blade_routemgr_master_set(blade_handle_routemgr_get(bmmgr->handle), bmmgr->master_nodeid);
blade_mastermgr_protocol_controller_add(bmmgr, "blade.presence", bmmgr->master_nodeid);
blade_mastermgr_protocol_channel_add(bmmgr, "blade.presence", "join", BLADE_CHANNEL_FLAGS_PUBLIC);
blade_mastermgr_protocol_channel_add(bmmgr, "blade.presence", "leave", BLADE_CHANNEL_FLAGS_PUBLIC);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_mastermgr_shutdown(blade_mastermgr_t *bmmgr)
{
ks_assert(bmmgr);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const char *nodeid)
{
ks_pool_t *pool = NULL;
ks_hash_t *cleanup = NULL;
ks_assert(bmmgr);
pool = ks_pool_get(bmmgr);
ks_hash_write_lock(bmmgr->protocols);
for (ks_hash_iterator_t *it = ks_hash_first(bmmgr->protocols, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *protocol = NULL;
blade_protocol_t *bp = NULL;
ks_bool_t unlock = KS_TRUE;
ks_hash_this(it, (const void **)&protocol, NULL, (void **)&bp);
blade_protocol_write_lock(bp);
if (blade_protocol_purge(bp, nodeid)) {
if (!blade_protocol_controller_available(bp)) {
if (!cleanup) ks_hash_create(&cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_hash_insert(cleanup, (void *)protocol, bp);
unlock = KS_FALSE;
}
else {
// @todo not the last controller, may need to propagate that the controller is no longer available?
}
}
if (unlock) blade_protocol_write_unlock(bp);
}
if (cleanup) {
for (ks_hash_iterator_t *it2 = ks_hash_first(cleanup, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
const char *protocol = NULL;
blade_protocol_t *bp = NULL;
ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, NULL, NULL, NULL, NULL, NULL);
ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", protocol);
blade_protocol_write_unlock(bp);
ks_hash_remove(bmmgr->protocols, (void *)protocol);
}
ks_hash_destroy(&cleanup);
}
ks_hash_write_unlock(bmmgr->protocols);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, ks_bool_t writelocked)
{
blade_protocol_t *bp = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_READLOCKED);
if (bp) {
if (writelocked) blade_protocol_write_lock(bp);
else blade_protocol_read_lock(bp);
}
ks_hash_read_unlock(bmmgr->protocols);
return bp;
}
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
blade_protocol_t *bp = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(controller);
pool = ks_pool_get(bmmgr);
ks_hash_write_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (bp) blade_protocol_write_lock(bp);
else {
blade_protocol_create(&bp, pool, protocol);
ks_assert(bp);
blade_protocol_write_lock(bp);
ks_log(KS_LOG_DEBUG, "Protocol Added: %s\n", protocol);
ks_hash_insert(bmmgr->protocols, (void *)ks_pstrdup(ks_pool_get(bmmgr), protocol), (void *)bp);
}
blade_protocol_controller_add(bp, controller);
ks_log(KS_LOG_DEBUG, "Protocol Controller Added: %s to %s\n", controller, protocol);
blade_protocol_write_unlock(bp);
ks_hash_write_unlock(bmmgr->protocols);
return ret;
}
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_protocol_t *bp = NULL;
ks_bool_t remove = KS_FALSE;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(controller);
ks_hash_write_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
blade_protocol_write_lock(bp);
if (blade_protocol_controller_remove(bp, controller)) {
ks_log(KS_LOG_DEBUG, "Protocol Controller Removed: %s from %s\n", controller, protocol);
if (!blade_protocol_controller_available(bp)) {
blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, NULL, NULL, NULL, NULL, NULL);
ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", protocol);
remove = KS_TRUE;
} else {
// @todo not the last controller, may need to propagate when a specific controller becomes unavailable though
}
}
blade_protocol_write_unlock(bp);
if (remove) ks_hash_remove(bmmgr->protocols, (void *)protocol);
done:
ks_hash_write_unlock(bmmgr->protocols);
return ret;
}
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, blade_channel_flags_t flags)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(channel);
ks_hash_read_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
blade_protocol_write_lock(bp);
bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
if (bc) {
ret = KS_STATUS_DUPLICATE_OPERATION;
goto done;
}
blade_channel_create(&bc, ks_pool_get(bp), channel, flags);
ks_assert(bc);
blade_channel_write_lock(bc);
if (blade_protocol_channel_add(bp, bc) == KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "Protocol Channel Added: %s to %s\n", blade_channel_name_get(bc), blade_protocol_name_get(bp));
}
done:
if (bc) blade_channel_write_unlock(bc);
if (bp) blade_protocol_write_unlock(bp);
ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(channel);
ks_hash_read_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
blade_protocol_write_lock(bp);
bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
if (!bc) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
if (blade_protocol_channel_remove(bp, channel)) {
blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE, NULL, protocol, channel, NULL, NULL, NULL, NULL);
ks_log(KS_LOG_DEBUG, "Protocol Channel Removed: %s from %s\n", blade_channel_name_get(bc), blade_protocol_name_get(bp));
blade_channel_write_unlock(bc);
blade_channel_destroy(&bc);
}
done:
if (bp) blade_protocol_write_unlock(bp);
ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *channel, const char *controller, const char *target)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(channel);
ks_assert(controller);
ks_assert(target);
ks_hash_read_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
blade_protocol_read_lock(bp);
if (!blade_protocol_controller_verify(bp, controller)) {
ret = KS_STATUS_NOT_ALLOWED;
goto done;
}
bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
if (!bc) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
if (remove) {
if (blade_channel_authorization_remove(bc, target)) {
ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from protocol %s, channel %s\n", target, blade_protocol_name_get(bp), blade_channel_name_get(bc));
} else ret = KS_STATUS_NOT_FOUND;
} else {
if (blade_channel_authorization_add(bc, target)) {
ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Added: %s to protocol %s, channel %s\n", target, blade_protocol_name_get(bp), blade_channel_name_get(bc));
}
}
done:
if (bc) blade_channel_write_unlock(bc);
if (bp) blade_protocol_read_unlock(bp);
ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
KS_DECLARE(ks_bool_t) blade_mastermgr_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, const char *target)
{
ks_bool_t ret = KS_FALSE;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
ks_assert(channel);
ks_assert(target);
ks_hash_read_lock(bmmgr->protocols);
bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_FALSE;
goto done;
}
blade_protocol_read_lock(bp);
bc = blade_protocol_channel_lookup(bp, channel, KS_FALSE);
if (!bc) {
ret = KS_FALSE;
goto done;
}
if ((blade_channel_flags_get(bc) & BLADE_CHANNEL_FLAGS_PUBLIC) == BLADE_CHANNEL_FLAGS_PUBLIC) ret = KS_TRUE;
else ret = blade_channel_authorization_verify(bc, target);
done:
if (bc) blade_channel_read_unlock(bc);
if (bp) blade_protocol_read_unlock(bp);
ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,289 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_protocol_s {
const char *name;
ks_rwl_t *lock;
ks_hash_t *controllers;
ks_hash_t *channels;
// @todo descriptors (schema, etc) for each method within a protocol
};
static void blade_protocol_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_protocol_t *bp = (blade_protocol_t *)ptr;
ks_assert(bp);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
if (bp->name) ks_pool_free(&bp->name);
if (bp->lock) ks_rwl_destroy(&bp->lock);
if (bp->controllers) ks_hash_destroy(&bp->controllers);
if (bp->channels) ks_hash_destroy(&bp->channels);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, const char *name)
{
blade_protocol_t *bp = NULL;
ks_assert(bpP);
ks_assert(pool);
ks_assert(name);
bp = ks_pool_alloc(pool, sizeof(blade_protocol_t));
bp->name = ks_pstrdup(pool, name);
ks_rwl_create(&bp->lock, pool);
ks_assert(bp->lock);
ks_hash_create(&bp->controllers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bp->controllers);
ks_hash_create(&bp->channels, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bp->channels);
ks_pool_set_cleanup(bp, NULL, blade_protocol_cleanup);
*bpP = bp;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_protocol_destroy(blade_protocol_t **bpP)
{
ks_assert(bpP);
ks_assert(*bpP);
ks_pool_free(bpP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_protocol_name_get(blade_protocol_t *bp)
{
ks_assert(bp);
return bp->name;
}
KS_DECLARE(ks_status_t) blade_protocol_read_lock(blade_protocol_t *bp)
{
ks_assert(bp);
return ks_rwl_read_lock(bp->lock);
}
KS_DECLARE(ks_status_t) blade_protocol_read_unlock(blade_protocol_t *bp)
{
ks_assert(bp);
return ks_rwl_read_unlock(bp->lock);
}
KS_DECLARE(ks_status_t) blade_protocol_write_lock(blade_protocol_t *bp)
{
ks_assert(bp);
return ks_rwl_write_lock(bp->lock);
}
KS_DECLARE(ks_status_t) blade_protocol_write_unlock(blade_protocol_t *bp)
{
ks_assert(bp);
return ks_rwl_write_unlock(bp->lock);
}
KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nodeid)
{
ks_bool_t ret = KS_FALSE;
ks_assert(bp);
ks_assert(nodeid);
// @todo iterate all channels, remove the nodeid from all authorized hashes
ks_hash_write_lock(bp->channels);
for (ks_hash_iterator_t *it = ks_hash_first(bp->channels, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
blade_channel_t *channel = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&channel);
if (blade_channel_authorization_remove(channel, nodeid)) {
ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from protocol %s, channel %s\n", nodeid, bp->name, key);
}
}
ks_hash_write_unlock(bp->channels);
if ((ret = blade_protocol_controller_remove(bp, nodeid))) {
ks_log(KS_LOG_DEBUG, "Protocol Controller Removed: %s from %s\n", nodeid, bp->name);
}
return ret;
}
KS_DECLARE(cJSON *) blade_protocol_controller_pack(blade_protocol_t *bp)
{
cJSON *controllers = cJSON_CreateObject();
ks_assert(bp);
ks_hash_read_lock(bp->controllers);
for (ks_hash_iterator_t *it = ks_hash_first(bp->controllers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
cJSON_AddItemToArray(controllers, cJSON_CreateString(key));
}
ks_hash_read_unlock(bp->controllers);
return controllers;
}
KS_DECLARE(ks_bool_t) blade_protocol_controller_verify(blade_protocol_t *bp, const char *controller)
{
ks_bool_t ret = KS_FALSE;
ks_assert(bp);
ks_assert(controller);
ret = (ks_bool_t)(uintptr_t)ks_hash_search(bp->controllers, (void *)controller, KS_READLOCKED);
ks_hash_read_unlock(bp->controllers);
return ret;
}
KS_DECLARE(ks_status_t) blade_protocol_controller_add(blade_protocol_t *bp, const char *nodeid)
{
char *key = NULL;
ks_assert(bp);
ks_assert(nodeid);
key = ks_pstrdup(ks_pool_get(bp), nodeid);
ks_hash_insert(bp->controllers, (void *)key, (void *)KS_TRUE);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_protocol_controller_remove(blade_protocol_t *bp, const char *nodeid)
{
ks_bool_t ret = KS_FALSE;
ks_assert(bp);
ks_assert(nodeid);
ks_hash_write_lock(bp->controllers);
if (ks_hash_remove(bp->controllers, (void *)nodeid)) {
ret = KS_TRUE;
}
ks_hash_write_unlock(bp->controllers);
return ret;
}
KS_DECLARE(ks_bool_t) blade_protocol_controller_available(blade_protocol_t *bp)
{
ks_assert(bp);
return ks_hash_count(bp->controllers) > 0;
}
KS_DECLARE(blade_channel_t *) blade_protocol_channel_lookup(blade_protocol_t *bp, const char *channel, ks_bool_t writelocked)
{
blade_channel_t *bc = NULL;
ks_assert(bp);
ks_assert(channel);
bc = (blade_channel_t *)ks_hash_search(bp->channels, (void *)channel, KS_READLOCKED);
if (bc) {
if (writelocked) blade_channel_write_lock(bc);
else blade_channel_read_lock(bc);
}
ks_hash_read_unlock(bp->channels);
return bc;
}
KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, blade_channel_t *channel)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
char *key = NULL;
ks_assert(bp);
ks_assert(channel);
pool = ks_pool_get(bp);
ks_hash_write_lock(bp->channels);
if (ks_hash_search(bp->channels, (void *)blade_channel_name_get(channel), KS_UNLOCKED)) {
ret = KS_STATUS_DUPLICATE_OPERATION;
goto done;
}
key = ks_pstrdup(pool, blade_channel_name_get(channel));
ks_hash_insert(bp->channels, (void *)key, (void *)channel);
done:
ks_hash_write_unlock(bp->channels);
return ret;
}
KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *channel)
{
ks_assert(bp);
ks_assert(channel);
return ks_hash_remove(bp->channels, (void *)channel) != NULL;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,562 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
#define BLADE_RESTMGR_SERVICE_CAPTURE_MAX 10
#define BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS (BLADE_RESTMGR_SERVICE_CAPTURE_MAX * 3) // @note Last third of this is workspace
typedef struct blade_restmgr_config_s {
ks_bool_t enabled;
ks_hash_t *options;
} blade_restmgr_config_t;
struct blade_restmgr_s {
blade_handle_t *handle;
blade_restmgr_config_t config;
void *data;
struct mg_context *context;
ks_hash_t *services;
};
typedef struct blade_restmgr_service_s {
pcre *compiled;
pcre_extra *extra;
const char *action;
blade_restmgr_service_callback_t callback;
} blade_restmgr_service_t;
static void blade_restmgr_service_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_restmgr_service_t *brestmgrs = (blade_restmgr_service_t *)ptr;
ks_assert(brestmgrs);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
if (brestmgrs->compiled) {
pcre_free(brestmgrs->compiled);
brestmgrs->compiled = NULL;
}
if (brestmgrs->extra) {
#ifdef PCRE_CONFIG_JIT
pcre_free_study(brestmgrs->extra);
#else
pcre_free(brestmgrs->extra);
#endif
brestmgrs->extra = NULL;
}
if (brestmgrs->action) ks_pool_free(&brestmgrs->action);
break;
case KS_MPCL_DESTROY:
break;
}
}
int blade_restmgr_handle_begin_request(struct mg_connection *conn);
void blade_restmgr_handle_end_request(const struct mg_connection *conn, int reply_status_code);
int blade_restmgr_handle_log_message(const struct mg_connection *conn, const char *message);
int blade_restmgr_handle_log_access(const struct mg_connection *conn, const char *message);
int blade_restmgr_handle_init_ssl(void *ssl_context, void *user_data);
void blade_restmgr_handle_connection_close(const struct mg_connection *conn);
const char *blade_restmgr_handle_open_file(const struct mg_connection *conn, const char *path, size_t *data_len);
void blade_restmgr_handle_init_lua(const struct mg_connection *conn, void *lua_context);
int blade_restmgr_handle_http_error(struct mg_connection *conn, int status);
void blade_restmgr_handle_init_context(const struct mg_context *ctx);
void blade_restmgr_handle_init_thread(const struct mg_context *ctx, int thread_type);
void blade_restmgr_handle_exit_context(const struct mg_context *ctx);
static void blade_restmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_restmgr_t *brestmgr = (blade_restmgr_t *)ptr;
//ks_assert(brestmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_restmgr_create(blade_restmgr_t **brestmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_restmgr_t *brestmgr = NULL;
ks_assert(brestmgrP);
ks_pool_open(&pool);
ks_assert(pool);
brestmgr = ks_pool_alloc(pool, sizeof(blade_restmgr_t));
brestmgr->handle = bh;
ks_hash_create(&brestmgr->config.options, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_assert(brestmgr->config.options);
ks_hash_create(&brestmgr->services, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(brestmgr->services);
ks_pool_set_cleanup(brestmgr, NULL, blade_restmgr_cleanup);
*brestmgrP = brestmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_restmgr_destroy(blade_restmgr_t **brestmgrP)
{
blade_restmgr_t *brestmgr = NULL;
ks_pool_t *pool;
ks_assert(brestmgrP);
ks_assert(*brestmgrP);
brestmgr = *brestmgrP;
*brestmgrP = NULL;
pool = ks_pool_get(brestmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
#define CONFIG_LOADSTR(k) \
tmp = config_setting_lookup(rest, k); \
if (tmp && config_setting_type(tmp) != CONFIG_TYPE_STRING) return KS_STATUS_FAIL; \
if (tmp) ks_hash_insert(brestmgr->config.options, (void *)k, (void *)ks_pstrdup(pool, config_setting_get_string(tmp)));
ks_status_t blade_restmgr_config(blade_restmgr_t *brestmgr, config_setting_t *config)
{
ks_pool_t *pool = NULL;
config_setting_t *rest = NULL;
config_setting_t *tmp = NULL;
ks_assert(brestmgr);
pool = ks_pool_get(brestmgr);
if (!config_setting_is_group(config)) {
ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
return KS_STATUS_FAIL;
}
rest = config_setting_get_member(config, "rest");
if (rest) {
tmp = config_setting_lookup(rest, "enabled");
if (!tmp) return KS_STATUS_FAIL;
if (config_setting_type(tmp) != CONFIG_TYPE_BOOL) return KS_STATUS_FAIL;
brestmgr->config.enabled = config_setting_get_bool(tmp);
if (!brestmgr->config.enabled) return KS_STATUS_SUCCESS;
CONFIG_LOADSTR("cgi_pattern");
CONFIG_LOADSTR("cgi_environment");
CONFIG_LOADSTR("put_delete_auth_file");
CONFIG_LOADSTR("cgi_interpreter");
CONFIG_LOADSTR("protect_uri");
CONFIG_LOADSTR("authentication_domain");
CONFIG_LOADSTR("enable_auth_domain_check");
CONFIG_LOADSTR("ssi_pattern");
CONFIG_LOADSTR("throttle");
CONFIG_LOADSTR("access_log_file");
CONFIG_LOADSTR("enable_directory_listing");
CONFIG_LOADSTR("error_log_file");
CONFIG_LOADSTR("global_auth_file");
CONFIG_LOADSTR("index_files");
CONFIG_LOADSTR("enable_keep_alive");
CONFIG_LOADSTR("access_control_list");
CONFIG_LOADSTR("extra_mime_types");
CONFIG_LOADSTR("listening_ports");
CONFIG_LOADSTR("document_root");
CONFIG_LOADSTR("ssl_certificate");
CONFIG_LOADSTR("ssl_certificate_chain");
CONFIG_LOADSTR("num_threads");
CONFIG_LOADSTR("run_as_user");
CONFIG_LOADSTR("url_rewrite_patterns");
CONFIG_LOADSTR("hide_files_patterns");
CONFIG_LOADSTR("request_timeout_ms");
CONFIG_LOADSTR("keep_alive_timeout_ms");
CONFIG_LOADSTR("linger_timeout_ms");
CONFIG_LOADSTR("ssl_verify_peer");
CONFIG_LOADSTR("ssl_ca_path");
CONFIG_LOADSTR("ssl_ca_file");
CONFIG_LOADSTR("ssl_verify_depth");
CONFIG_LOADSTR("ssl_default_verify_paths");
CONFIG_LOADSTR("ssl_cipher_list");
CONFIG_LOADSTR("ssl_protocol_version");
CONFIG_LOADSTR("ssl_short_trust");
CONFIG_LOADSTR("websocket_timeout_ms");
CONFIG_LOADSTR("decode_url");
CONFIG_LOADSTR("lua_preload_file");
CONFIG_LOADSTR("lua_script_pattern");
CONFIG_LOADSTR("lua_server_page_pattern");
CONFIG_LOADSTR("duktape_script_pattern");
CONFIG_LOADSTR("websocket_root");
CONFIG_LOADSTR("lua_websocket_pattern");
CONFIG_LOADSTR("access_control_allow_origin");
CONFIG_LOADSTR("access_control_allow_methods");
CONFIG_LOADSTR("access_control_allow_headers");
CONFIG_LOADSTR("error_pages");
CONFIG_LOADSTR("tcp_nodelay");
CONFIG_LOADSTR("static_file_max_age");
CONFIG_LOADSTR("strict_transport_security_max_age");
CONFIG_LOADSTR("allow_sendfile_call");
CONFIG_LOADSTR("case_sensitive");
CONFIG_LOADSTR("lua_background_script");
CONFIG_LOADSTR("lua_background_script_params");
CONFIG_LOADSTR("additional_header");
CONFIG_LOADSTR("max_request_size");
CONFIG_LOADSTR("allow_index_script_resource");
}
if (brestmgr->config.enabled) {
ks_log(KS_LOG_DEBUG, "Configured\n");
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_restmgr_startup(blade_restmgr_t *brestmgr, config_setting_t *config)
{
ks_assert(brestmgr);
if (blade_restmgr_config(brestmgr, config) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_restmgr_config failed\n");
return KS_STATUS_FAIL;
}
if (brestmgr->config.enabled) {
struct mg_callbacks callbacks;
const char **options = (const char **)ks_pool_calloc(ks_pool_get(brestmgr), (ks_hash_count(brestmgr->config.options) * 2) + 1, sizeof(char *));
ks_size_t index = 0;
memset(&callbacks, 0, sizeof(struct mg_callbacks));
callbacks.begin_request = blade_restmgr_handle_begin_request;
callbacks.end_request = blade_restmgr_handle_end_request;
callbacks.log_message = blade_restmgr_handle_log_message;
callbacks.log_access = blade_restmgr_handle_log_access;
//callbacks.init_ssl = blade_restmgr_handle_init_ssl;
callbacks.connection_close = blade_restmgr_handle_connection_close;
callbacks.open_file = blade_restmgr_handle_open_file;
callbacks.init_lua = blade_restmgr_handle_init_lua;
callbacks.http_error = blade_restmgr_handle_http_error;
callbacks.init_context = blade_restmgr_handle_init_context;
callbacks.init_thread = blade_restmgr_handle_init_thread;
callbacks.exit_context = blade_restmgr_handle_exit_context;
for (ks_hash_iterator_t *it = ks_hash_first(brestmgr->config.options, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
const char *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
options[index++] = key;
options[index++] = value;
}
options[index++] = NULL;
brestmgr->context = mg_start(&callbacks, brestmgr, options);
ks_pool_free(&options);
if (!brestmgr->context) return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_restmgr_shutdown(blade_restmgr_t *brestmgr)
{
ks_assert(brestmgr);
if (brestmgr->context) {
mg_stop(brestmgr->context);
brestmgr->context = NULL;
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_restmgr_handle_get(blade_restmgr_t *brestmgr)
{
ks_assert(brestmgr);
return brestmgr->handle;
}
KS_DECLARE(void *) blade_restmgr_data_get(blade_restmgr_t *brestmgr)
{
ks_assert(brestmgr);
return brestmgr->data;
}
KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void *data)
{
ks_assert(brestmgr);
brestmgr->data = data;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_restmgr_service_add(blade_restmgr_t *brestmgr, const char *action, const char *route, blade_restmgr_service_callback_t callback)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
char *key = NULL;
blade_restmgr_service_t *service = NULL;
const char *errString = NULL;
int errOffset = 0;
ks_assert(brestmgr);
ks_assert(route);
ks_assert(callback);
pool = ks_pool_get(brestmgr);
key = ks_psprintf(pool, "%s:%s", action, route);
ks_hash_write_lock(brestmgr->services);
if ((service = (blade_restmgr_service_t *)ks_hash_remove(brestmgr->services, (void *)key)) != NULL) {
ks_log(KS_LOG_DEBUG, "Service Removed: %s\n", key);
ks_pool_free(&service);
}
service = ks_pool_alloc(pool, sizeof(blade_restmgr_service_t));
ks_pool_set_cleanup(service, NULL, blade_restmgr_service_cleanup);
service->callback = callback;
service->action = ks_pstrdup(pool, action);
service->compiled = pcre_compile(route, 0, &errString, &errOffset, NULL);
if (service->compiled == NULL) {
ks_log(KS_LOG_DEBUG, "Could not compile '%s': %s\n", route, errString);
ret = KS_STATUS_FAIL;
goto done;
}
service->extra = pcre_study(service->compiled, 0, &errString);
if (errString != NULL) {
ks_log(KS_LOG_DEBUG, "Could not study '%s': %s\n", route, errString);
ret = KS_STATUS_FAIL;
goto done;
}
ks_hash_insert(brestmgr->services, (void *)key, (void *)service);
ks_log(KS_LOG_DEBUG, "Service Added: %s\n", key);
done:
ks_hash_write_unlock(brestmgr->services);
return ret;
}
KS_DECLARE(ks_status_t) blade_restmgr_service_remove(blade_restmgr_t *brestmgr, const char *action, const char *route)
{
ks_pool_t *pool = NULL;
const char *key = NULL;
blade_restmgr_service_t *service = NULL;
ks_assert(brestmgr);
ks_assert(route);
pool = ks_pool_get(brestmgr);
key = ks_psprintf(pool, "%s:%s", action, route);
if ((service = (blade_restmgr_service_t *)ks_hash_remove(brestmgr->services, (void *)key)) != NULL) {
ks_log(KS_LOG_DEBUG, "Service Removed: %s\n", key);
ks_pool_free(&service);
}
ks_pool_free(&key);
return KS_STATUS_SUCCESS;
}
int blade_restmgr_handle_begin_request(struct mg_connection *conn)
{
int ret = 0;
blade_restmgr_t *brestmgr = NULL;
const struct mg_request_info *info = NULL;
int execRet = 0;
int captureVectors[BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS];
info = mg_get_request_info(conn);
ks_log(KS_LOG_DEBUG, "Request for: %s on %s\n", info->request_uri, info->request_method);
brestmgr = (blade_restmgr_t *)info->user_data;
ks_hash_read_lock(brestmgr->services);
for (ks_hash_iterator_t *it = ks_hash_first(brestmgr->services, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
blade_restmgr_service_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
// @todo could optimize this to provide a separate hash for each action typed, keyed in a top level hash by the request_method/action string
if (ks_safe_strcasecmp(value->action, info->request_method)) continue;
execRet = pcre_exec(value->compiled,
value->extra,
info->request_uri,
strlen(info->request_uri),
0, // Offset
0, // Options
captureVectors,
BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS);
if (execRet < 0) {
switch (execRet) {
case PCRE_ERROR_NOMATCH: continue;
case PCRE_ERROR_NULL: ks_log(KS_LOG_DEBUG, "Something was null\n"); break;
case PCRE_ERROR_BADOPTION: ks_log(KS_LOG_DEBUG, "A bad option was passed\n"); break;
case PCRE_ERROR_BADMAGIC: ks_log(KS_LOG_DEBUG, "Magic number bad (compile corrupt?)\n"); break;
case PCRE_ERROR_UNKNOWN_NODE: ks_log(KS_LOG_DEBUG, "Something kooky in the compile\n"); break;
case PCRE_ERROR_NOMEMORY: ks_log(KS_LOG_DEBUG, "Ran out of memory\n"); break;
default: ks_log(KS_LOG_DEBUG, "Unknown error\n"); break;
}
ret = 500;
goto done;
} else {
const char **captures = NULL;
if (execRet == 0) {
ks_log(KS_LOG_DEBUG, "Too many substrings were found to fit in capture vectors!\n");
ret = 500;
goto done;
}
if (pcre_get_substring_list(info->request_uri, captureVectors, execRet, &captures) != 0) {
ks_log(KS_LOG_DEBUG, "Cannot get substring list!\n");
ret = 500;
goto done;
}
ret = value->callback(brestmgr, conn, captures);
pcre_free_substring_list(captures);
//ret = 200;
goto done;
}
}
done:
ks_hash_read_unlock(brestmgr->services);
return ret;
}
void blade_restmgr_handle_end_request(const struct mg_connection *conn, int reply_status_code)
{
}
int blade_restmgr_handle_log_message(const struct mg_connection *conn, const char *message)
{
return 0;
}
int blade_restmgr_handle_log_access(const struct mg_connection *conn, const char *message)
{
return 0;
}
int blade_restmgr_handle_init_ssl(void *ssl_context, void *user_data)
{
return 0;
}
void blade_restmgr_handle_connection_close(const struct mg_connection *conn)
{
}
const char *blade_restmgr_handle_open_file(const struct mg_connection *conn, const char *path, size_t *data_len)
{
return NULL;
}
void blade_restmgr_handle_init_lua(const struct mg_connection *conn, void *lua_context)
{
}
int blade_restmgr_handle_http_error(struct mg_connection *conn, int status)
{
return 1;
}
void blade_restmgr_handle_init_context(const struct mg_context *ctx)
{
}
void blade_restmgr_handle_init_thread(const struct mg_context *ctx, int thread_type)
{
}
void blade_restmgr_handle_exit_context(const struct mg_context *ctx)
{
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,533 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_routemgr_s {
blade_handle_t *handle;
const char *local_nodeid;
ks_rwl_t *local_lock;
const char *master_nodeid;
ks_rwl_t *master_lock;
ks_hash_t *routes; // target nodeid, downstream router nodeid
ks_hash_t *identities; // identity, target nodeid
};
static void blade_routemgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_routemgr_t *brmgr = (blade_routemgr_t *)ptr;
//ks_assert(brmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_routemgr_create(blade_routemgr_t **brmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_routemgr_t *brmgr = NULL;
ks_assert(brmgrP);
ks_pool_open(&pool);
ks_assert(pool);
brmgr = ks_pool_alloc(pool, sizeof(blade_routemgr_t));
brmgr->handle = bh;
ks_rwl_create(&brmgr->local_lock, pool);
ks_assert(brmgr->local_lock);
ks_rwl_create(&brmgr->master_lock, pool);
ks_assert(brmgr->master_lock);
// @note can let removes free keys and values for routes and identity, both use keys and values that are strings allocated from the same pool as the hash itself
ks_hash_create(&brmgr->routes, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(brmgr->routes);
ks_hash_create(&brmgr->identities, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(brmgr->routes);
ks_pool_set_cleanup(brmgr, NULL, blade_routemgr_cleanup);
*brmgrP = brmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_routemgr_destroy(blade_routemgr_t **brmgrP)
{
blade_routemgr_t *brmgr = NULL;
ks_pool_t *pool;
ks_assert(brmgrP);
ks_assert(*brmgrP);
brmgr = *brmgrP;
*brmgrP = NULL;
pool = ks_pool_get(brmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_routemgr_handle_get(blade_routemgr_t *brmgr)
{
ks_assert(brmgr);
return brmgr->handle;
}
KS_DECLARE(ks_status_t) blade_routemgr_local_set(blade_routemgr_t *brmgr, const char *nodeid)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(brmgr);
ks_rwl_write_lock(brmgr->local_lock);
if (brmgr->local_nodeid) ks_pool_free(&brmgr->local_nodeid);
if (nodeid) brmgr->local_nodeid = ks_pstrdup(ks_pool_get(brmgr), nodeid);
ks_log(KS_LOG_DEBUG, "Local NodeID: %s\n", nodeid);
ks_rwl_write_unlock(brmgr->local_lock);
return ret;
}
KS_DECLARE(ks_bool_t) blade_routemgr_local_check(blade_routemgr_t *brmgr, const char *target)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_assert(target);
ks_rwl_read_lock(brmgr->local_lock);
ret = !ks_safe_strcasecmp(brmgr->local_nodeid, target);
if (!ret) {
// @todo must parse target to an identity, and back to a properly formatted identity key
blade_identity_t *identity = NULL;
ks_pool_t *pool = ks_pool_get(brmgr);
blade_identity_create(&identity, pool);
if (blade_identity_parse(identity, target) == KS_STATUS_SUCCESS) {
char *key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
const char *value = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_READLOCKED);
if (value) ret = !ks_safe_strcasecmp(brmgr->local_nodeid, value);
ks_hash_read_unlock(brmgr->identities);
ks_pool_free(&key);
}
blade_identity_destroy(&identity);
}
ks_rwl_read_unlock(brmgr->local_lock);
return ret;
}
KS_DECLARE(ks_bool_t) blade_routemgr_local_copy(blade_routemgr_t *brmgr, const char **nodeid)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_assert(nodeid);
*nodeid = NULL;
ks_rwl_read_lock(brmgr->local_lock);
if (brmgr->local_nodeid) {
ret = KS_TRUE;
*nodeid = ks_pstrdup(ks_pool_get(brmgr), brmgr->local_nodeid);
}
ks_rwl_read_unlock(brmgr->local_lock);
return ret;
}
KS_DECLARE(ks_bool_t) blade_routemgr_local_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_assert(json);
ks_assert(key);
ks_rwl_read_lock(brmgr->local_lock);
if (brmgr->local_nodeid) {
ret = KS_TRUE;
cJSON_AddStringToObject(json, key, brmgr->local_nodeid);
}
ks_rwl_read_unlock(brmgr->local_lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_routemgr_master_set(blade_routemgr_t *brmgr, const char *nodeid)
{
ks_assert(brmgr);
ks_rwl_write_lock(brmgr->master_lock);
if (brmgr->master_nodeid) ks_pool_free(&brmgr->master_nodeid);
if (nodeid) brmgr->master_nodeid = ks_pstrdup(ks_pool_get(brmgr), nodeid);
ks_rwl_write_unlock(brmgr->master_lock);
ks_log(KS_LOG_DEBUG, "Master NodeID: %s\n", nodeid);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_routemgr_master_check(blade_routemgr_t *brmgr, const char *target)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_assert(target);
ks_rwl_read_lock(brmgr->master_lock);
ret = ks_safe_strcasecmp(brmgr->master_nodeid, target) == 0;
// @todo may also need to check against master identities, there are a number of ways master identities
// could be propagated to ensure this check works for identities, but for now just assume that master cannot
// use identities for these checks which should generally only be done to validate certain blade CoreRPC's which
// expect the responder to be the master, and which get packed in the function below
// the following would only work on the master itself, where it registered it's own identities and thus has the
// identities in the identities mapping, other nodes do not see master identity registrations and cannot currently
// validate master identities
//if (!ret) {
// const char *nodeid = (const char *)ks_hash_search(brmgr->identities, (void *)target, KS_READLOCKED);
// ret = nodeid && !ks_safe_strcasecmp(nodeid, brmgr->master_nodeid);
// ks_hash_read_unlock(brmgr->identities);
//}
ks_rwl_read_unlock(brmgr->master_lock);
return ret;
}
KS_DECLARE(ks_bool_t) blade_routemgr_master_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_assert(json);
ks_assert(key);
ks_rwl_read_lock(brmgr->master_lock);
if (brmgr->master_nodeid) {
ret = KS_TRUE;
cJSON_AddStringToObject(json, key, brmgr->master_nodeid);
// @todo may need to pack master identities into the json as well, for now just use nodeid only and
// assume master nodes have no identities, however this call is primarily used only to force certain
// blade CoreRPC's to route to the known master node, but is also used to pass to downstream nodes
// when they connect
}
ks_rwl_read_unlock(brmgr->master_lock);
return ret;
}
KS_DECLARE(ks_bool_t) blade_routemgr_master_local(blade_routemgr_t *brmgr)
{
ks_bool_t ret = KS_FALSE;
ks_assert(brmgr);
ks_rwl_read_lock(brmgr->master_lock);
ret = brmgr->master_nodeid && brmgr->local_nodeid && !ks_safe_strcasecmp(brmgr->master_nodeid, brmgr->local_nodeid);
//ret = brmgr->master_nodeid && brmgr->localid && !ks_safe_strcasecmp(brmgr->master_nodeid, brmgr->local_nodeid);
ks_rwl_read_unlock(brmgr->master_lock);
return ret;
}
KS_DECLARE(blade_session_t *) blade_routemgr_route_lookup(blade_routemgr_t *brmgr, const char *target)
{
blade_session_t *bs = NULL;
const char *router = NULL;
ks_assert(brmgr);
ks_assert(target);
// Short circuit any nodeid or identity that matches the local node by returning the loopback session explicitly
// @todo this could be potentially be avoided if the local nodeid and all local identities are added as routes to the loopback sessionid
if (blade_routemgr_local_check(brmgr, target)) bs = blade_sessionmgr_loopback_lookup(blade_handle_sessionmgr_get(brmgr->handle));
else {
// If the target is a downstream nodeid then it will be found in the route table immediately and return the sessionid of the downstream session to route through
router = (const char *)ks_hash_search(brmgr->routes, (void *)target, KS_READLOCKED);
if (!router) {
// If the target is a downstream node identity then it will be found in the identity table and return the nodeid which can then be used to lookup the route
blade_identity_t *identity = NULL;
ks_pool_t *pool = ks_pool_get(brmgr);
blade_identity_create(&identity, pool);
if (blade_identity_parse(identity, target) == KS_STATUS_SUCCESS) {
char *key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
router = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_READLOCKED);
ks_hash_read_unlock(brmgr->identities);
ks_pool_free(&key);
if (router) router = (const char *)ks_hash_search(brmgr->routes, (void *)router, KS_UNLOCKED);
}
blade_identity_destroy(&identity);
}
// When a router is found it is the sessionid of the downstream session, lookup the session to route through
if (router) bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(brmgr->handle), router);
ks_hash_read_unlock(brmgr->routes);
}
return bs;
}
ks_status_t blade_routemgr_purge(blade_routemgr_t *brmgr, const char *target)
{
ks_hash_t* cleanup = NULL;
ks_assert(brmgr);
ks_assert(target);
// @note this approach is deliberately slower than it could be, as it ensures that if there is a race condition and another session has registered
// the same identity before a prior session times out, then the correct targetted random nodeid is matched to confirm the identity removal and will
// not remove if the target isn't what is expected
ks_hash_write_lock(brmgr->identities);
for (ks_hash_iterator_t *it = ks_hash_first(brmgr->identities, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
const char *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
if (value && !ks_safe_strcasecmp(value, target)) {
if (!cleanup) ks_hash_create(&cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, ks_pool_get(brmgr));
ks_hash_insert(cleanup, (void *)key, (void *)value);
}
}
if (cleanup) {
for (ks_hash_iterator_t *it = ks_hash_first(cleanup, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
const char *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
ks_log(KS_LOG_DEBUG, "Identity Removed: %s through %s\n", key, value);
ks_hash_remove(brmgr->identities, (void *)key);
}
}
ks_hash_write_unlock(brmgr->identities);
if (cleanup) ks_hash_destroy(&cleanup);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const char *target, const char *router)
{
ks_pool_t *pool = NULL;
char *key = NULL;
char *value = NULL;
ks_assert(brmgr);
ks_assert(target);
ks_assert(router);
pool = ks_pool_get(brmgr);
key = ks_pstrdup(pool, target);
value = ks_pstrdup(pool, router);
ks_hash_insert(brmgr->routes, (void *)key, (void *)value);
ks_log(KS_LOG_DEBUG, "Route Added: %s through %s\n", key, value);
blade_handle_rpcroute(brmgr->handle, target, KS_FALSE, NULL, NULL);
if (blade_routemgr_master_local(brmgr)) {
cJSON *params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "nodeid", target);
blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "join", "joined", params, NULL, NULL);
cJSON_Delete(params);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, const char *target)
{
ks_assert(brmgr);
ks_assert(target);
ks_hash_remove(brmgr->routes, (void *)target);
ks_log(KS_LOG_DEBUG, "Route Removed: %s\n", target);
blade_handle_rpcroute(brmgr->handle, target, KS_TRUE, NULL, NULL);
blade_subscriptionmgr_purge(blade_handle_subscriptionmgr_get(brmgr->handle), target);
// @note protocols are cleaned up here because routes can be removed that are not locally connected with a session but still
// have protocols published to the master node from further downstream, in which case if a route is announced upstream to be
// removed, a master node is still able to catch that here even when there is no direct session, but is also hit when there
// is a direct session being terminated
blade_mastermgr_purge(blade_handle_mastermgr_get(brmgr->handle), target);
blade_routemgr_purge(brmgr, target);
if (blade_routemgr_master_local(brmgr)) {
cJSON *params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "nodeid", target);
blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "leave", "left", params, NULL, NULL);
cJSON_Delete(params);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_routemgr_identity_add(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target)
{
ks_pool_t *pool = NULL;
char *key = NULL;
char *value = NULL;
ks_assert(brmgr);
ks_assert(identity);
ks_assert(target);
pool = ks_pool_get(brmgr);
key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
value = ks_pstrdup(pool, target);
ks_hash_insert(brmgr->identities, (void *)key, (void *)value);
ks_log(KS_LOG_DEBUG, "Identity Added: %s through %s\n", key, value);
//if (blade_routemgr_master_local(blade_handle_routemgr_get(brmgr->handle))) {
// cJSON *params = cJSON_CreateObject();
// cJSON_AddStringToObject(params, "identity", blade_identity_uri_get(identity)); // full identity uri string
// cJSON_AddStringToObject(params, "nodeid", target);
// blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "join", "joined", params, NULL, NULL);
// cJSON_Delete(params);
//}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_routemgr_identity_remove(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target)
{
ks_pool_t *pool = NULL;
char *key = NULL;
const char *value = NULL;
ks_assert(brmgr);
ks_assert(identity);
ks_assert(target);
pool = ks_pool_get(brmgr);
key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
// @note this approach is deliberately slower than it could be, as it ensures that if there is a race condition and another session has registered
// the same identity before a prior session times out, then the correct targetted random nodeid is matched to confirm the identity removal and will
// not remove if the target isn't what is expected
ks_hash_write_lock(brmgr->identities);
value = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_UNLOCKED);
if (value && !ks_safe_strcasecmp(value, target)) {
ks_hash_remove(brmgr->identities, (void *)key);
ks_log(KS_LOG_DEBUG, "Identity Removed: %s through %s\n", key, value);
}
ks_hash_write_unlock(brmgr->identities);
//if (blade_routemgr_master_local(blade_handle_routemgr_get(brmgr->handle))) {
// cJSON *params = cJSON_CreateObject();
// cJSON_AddStringToObject(params, "nodeid", target);
// blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "leave", "left", params, NULL, NULL);
// cJSON_Delete(params);
//}
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,460 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_rpc_s {
blade_handle_t *handle;
const char *method;
const char *protocol;
blade_rpc_request_callback_t callback;
void *data;
};
struct blade_rpc_request_s {
blade_handle_t *handle;
const char *session_id;
cJSON *message;
const char *message_id; // pulled from message for easier keying
ks_time_t ttl;
blade_rpc_response_callback_t callback;
void *data;
};
struct blade_rpc_response_s {
blade_handle_t *handle;
const char *session_id;
blade_rpc_request_t *request;
cJSON *message;
};
static void blade_rpc_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_rpc_t *brpc = (blade_rpc_t *)ptr;
//ks_assert(brpc);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
// @todo delete data if present, requires update to ks_pool for self tracking the pool in allocation header
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, blade_rpc_request_callback_t callback, void *data)
{
blade_rpc_t *brpc = NULL;
ks_pool_t *pool = NULL;
ks_assert(brpcP);
ks_assert(bh);
ks_assert(method);
ks_assert(callback);
ks_pool_open(&pool);
ks_assert(pool);
brpc = ks_pool_alloc(pool, sizeof(blade_rpc_t));
brpc->handle = bh;
brpc->method = ks_pstrdup(pool, method);
if (protocol) brpc->protocol = ks_pstrdup(pool, protocol);
brpc->callback = callback;
brpc->data = data;
ks_pool_set_cleanup(brpc, NULL, blade_rpc_cleanup);
*brpcP = brpc;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_destroy(blade_rpc_t **brpcP)
{
blade_rpc_t *brpc = NULL;
ks_pool_t *pool = NULL;
ks_assert(brpcP);
ks_assert(*brpcP);
brpc = *brpcP;
*brpcP = NULL;
pool = ks_pool_get(brpc);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_rpc_handle_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
return brpc->handle;
}
KS_DECLARE(const char *) blade_rpc_method_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
return brpc->method;
}
KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
return brpc->protocol;
}
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
return brpc->callback;
}
KS_DECLARE(void *) blade_rpc_data_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
return brpc->data;
}
static void blade_rpc_request_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_rpc_request_t *brpcreq = (blade_rpc_request_t *)ptr;
ks_assert(brpcreq);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
ks_pool_free((void **)&brpcreq->session_id);
cJSON_Delete(brpcreq->message);
// @todo delete data if present, requires update to ks_pool for self tracking the pool in allocation header
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_rpc_request_create(blade_rpc_request_t **brpcreqP,
blade_handle_t *bh,
ks_pool_t *pool,
const char *session_id,
cJSON *json,
blade_rpc_response_callback_t callback,
void *data)
{
blade_rpc_request_t *brpcreq = NULL;
ks_assert(brpcreqP);
ks_assert(bh);
ks_assert(pool);
ks_assert(session_id);
ks_assert(json);
brpcreq = ks_pool_alloc(pool, sizeof(blade_rpc_request_t));
brpcreq->handle = bh;
brpcreq->session_id = ks_pstrdup(pool, session_id);
brpcreq->message = cJSON_Duplicate(json, 1);
brpcreq->message_id = cJSON_GetObjectCstr(brpcreq->message, "id");
brpcreq->callback = callback;
brpcreq->data = data;
ks_pool_set_cleanup(brpcreq, NULL, blade_rpc_request_cleanup);
*brpcreqP = brpcreq;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_request_destroy(blade_rpc_request_t **brpcreqP)
{
ks_assert(brpcreqP);
ks_assert(*brpcreqP);
ks_pool_free(brpcreqP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_request_duplicate(blade_rpc_request_t **brpcreqP, blade_rpc_request_t *brpcreq)
{
return blade_rpc_request_create(brpcreqP, brpcreq->handle, ks_pool_get(brpcreq), brpcreq->session_id, brpcreq->message, brpcreq->callback, brpcreq->data);
}
KS_DECLARE(blade_handle_t *) blade_rpc_request_handle_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->handle;
}
KS_DECLARE(const char *) blade_rpc_request_sessionid_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->session_id;
}
KS_DECLARE(cJSON *) blade_rpc_request_message_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->message;
}
KS_DECLARE(const char *) blade_rpc_request_messageid_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->message_id;
}
KS_DECLARE(ks_status_t) blade_rpc_request_ttl_set(blade_rpc_request_t *brpcreq, ks_time_t ttl)
{
ks_assert(brpcreq);
brpcreq->ttl = ks_time_now() + (ttl * KS_USEC_PER_SEC);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_rpc_request_expired(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->ttl <= ks_time_now();
}
KS_DECLARE(blade_rpc_response_callback_t) blade_rpc_request_callback_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->callback;
}
KS_DECLARE(void *) blade_rpc_request_data_get(blade_rpc_request_t *brpcreq)
{
ks_assert(brpcreq);
return brpcreq->data;
}
KS_DECLARE(ks_status_t) blade_rpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
{
cJSON *root = NULL;
cJSON *p = NULL;
uuid_t msgid;
const char *mid = NULL;
ks_assert(pool);
ks_assert(json);
ks_assert(method);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
ks_uuid(&msgid);
mid = ks_uuid_str(pool, &msgid);
cJSON_AddStringToObject(root, "id", mid);
ks_pool_free(&mid);
cJSON_AddStringToObject(root, "method", method);
p = cJSON_CreateObject();
cJSON_AddItemToObject(root, "params", p);
*json = root;
if (params) *params = p;
if (id) *id = cJSON_GetObjectCstr(root, "id");
return KS_STATUS_SUCCESS;
}
static void blade_rpc_response_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_rpc_response_t *brpcres = (blade_rpc_response_t *)ptr;
ks_assert(brpcres);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
ks_pool_free((void **)&brpcres->session_id);
blade_rpc_request_destroy(&brpcres->request);
cJSON_Delete(brpcres->message);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_rpc_response_create(blade_rpc_response_t **brpcresP,
blade_handle_t *bh,
ks_pool_t *pool,
const char *session_id,
blade_rpc_request_t *brpcreq,
cJSON *json)
{
blade_rpc_response_t *brpcres = NULL;
ks_assert(brpcresP);
ks_assert(bh);
ks_assert(pool);
ks_assert(session_id);
ks_assert(brpcreq);
ks_assert(json);
brpcres = ks_pool_alloc(pool, sizeof(blade_rpc_response_t));
brpcres->handle = bh;
brpcres->session_id = ks_pstrdup(pool, session_id);
brpcres->request = brpcreq;
brpcres->message = cJSON_Duplicate(json, 1);
ks_pool_set_cleanup(brpcres, NULL, blade_rpc_response_cleanup);
*brpcresP = brpcres;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_response_destroy(blade_rpc_response_t **brpcresP)
{
ks_assert(brpcresP);
ks_assert(*brpcresP);
ks_pool_free(brpcresP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpc_response_raw_create(cJSON **json, cJSON **result, const char *id)
{
cJSON *root = NULL;
cJSON *r = NULL;
ks_assert(json);
ks_assert(id);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
cJSON_AddStringToObject(root, "id", id);
r = cJSON_CreateObject();
cJSON_AddItemToObject(root, "result", r);
*json = root;
if (result) *result = r;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_rpc_response_handle_get(blade_rpc_response_t *brpcres)
{
ks_assert(brpcres);
return brpcres->handle;
}
KS_DECLARE(const char *) blade_rpc_response_sessionid_get(blade_rpc_response_t *brpcres)
{
ks_assert(brpcres);
return brpcres->session_id;
}
KS_DECLARE(blade_rpc_request_t *) blade_rpc_response_request_get(blade_rpc_response_t *brpcres)
{
ks_assert(brpcres);
return brpcres->request;
}
KS_DECLARE(cJSON *) blade_rpc_response_message_get(blade_rpc_response_t *brpcres)
{
ks_assert(brpcres);
return brpcres->message;
}
KS_DECLARE(ks_status_t) blade_rpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message)
{
cJSON *root = NULL;
cJSON *e = NULL;
ks_assert(json);
//ks_assert(id);
ks_assert(message);
root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
if (id) cJSON_AddStringToObject(root, "id", id);
e = cJSON_CreateObject();
cJSON_AddNumberToObject(e, "code", code);
cJSON_AddStringToObject(e, "message", message);
cJSON_AddItemToObject(root, "error", e);
*json = root;
if (error) *error = e;
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,364 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_rpcmgr_s {
blade_handle_t *handle;
ks_hash_t *corerpcs; // method, blade_rpc_t*
ks_hash_t *protocolrpcs; // method, blade_rpc_t*
ks_hash_t *requests; // id, blade_rpc_request_t*
ks_time_t requests_ttlcheck;
ks_mutex_t* requests_ttlcheck_lock;
};
static void blade_rpcmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_rpcmgr_t *brpcmgr = (blade_rpcmgr_t *)ptr;
ks_hash_iterator_t *it = NULL;
ks_assert(brpcmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
while ((it = ks_hash_first(brpcmgr->protocolrpcs, KS_UNLOCKED)) != NULL) {
void *key = NULL;
blade_rpc_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
ks_hash_remove(brpcmgr->protocolrpcs, key);
blade_rpc_destroy(&value); // must call destroy to close the method pool, using FREE_VALUE on the hash would attempt to free the method from the wrong pool
}
while ((it = ks_hash_first(brpcmgr->corerpcs, KS_UNLOCKED)) != NULL) {
void *key = NULL;
blade_rpc_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
ks_hash_remove(brpcmgr->corerpcs, key);
blade_rpc_destroy(&value); // must call destroy to close the rpc pool, using FREE_VALUE on the hash would attempt to free the rpc from the wrong pool
}
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_rpcmgr_create(blade_rpcmgr_t **brpcmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_rpcmgr_t *brpcmgr = NULL;
ks_assert(brpcmgrP);
ks_pool_open(&pool);
ks_assert(pool);
brpcmgr = ks_pool_alloc(pool, sizeof(blade_rpcmgr_t));
brpcmgr->handle = bh;
ks_hash_create(&brpcmgr->corerpcs, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(brpcmgr->corerpcs);
ks_hash_create(&brpcmgr->protocolrpcs, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(brpcmgr->protocolrpcs);
ks_hash_create(&brpcmgr->requests, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(brpcmgr->requests);
ks_mutex_create(&brpcmgr->requests_ttlcheck_lock, KS_MUTEX_FLAG_NON_RECURSIVE, pool);
ks_assert(brpcmgr->requests_ttlcheck_lock);
ks_pool_set_cleanup(brpcmgr, NULL, blade_rpcmgr_cleanup);
*brpcmgrP = brpcmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_destroy(blade_rpcmgr_t **brpcmgrP)
{
blade_rpcmgr_t *brpcmgr = NULL;
ks_pool_t *pool;
ks_assert(brpcmgrP);
ks_assert(*brpcmgrP);
brpcmgr = *brpcmgrP;
*brpcmgrP = NULL;
pool = ks_pool_get(brpcmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_rpcmgr_handle_get(blade_rpcmgr_t *brpcmgr)
{
ks_assert(brpcmgr);
return brpcmgr->handle;
}
KS_DECLARE(blade_rpc_t *) blade_rpcmgr_corerpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method)
{
blade_rpc_t *brpc = NULL;
ks_assert(brpcmgr);
ks_assert(method);
brpc = (blade_rpc_t *)ks_hash_search(brpcmgr->corerpcs, (void *)method, KS_READLOCKED);
// @todo if (brpc) blade_rpc_read_lock(brpc);
ks_hash_read_unlock(brpcmgr->corerpcs);
return brpc;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc)
{
char *key = NULL;
ks_assert(brpcmgr);
ks_assert(brpc);
key = ks_pstrdup(ks_pool_get(brpcmgr), blade_rpc_method_get(brpc));
ks_hash_insert(brpcmgr->corerpcs, (void *)key, (void *)brpc);
ks_log(KS_LOG_DEBUG, "CoreRPC Added: %s\n", key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc)
{
const char *method = NULL;
ks_assert(brpcmgr);
ks_assert(brpc);
method = blade_rpc_method_get(brpc);
ks_hash_remove(brpcmgr->corerpcs, (void *)method);
ks_log(KS_LOG_DEBUG, "CoreRPC Removed: %s\n", method);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol)
{
blade_rpc_t *brpc = NULL;
char *key = NULL;
ks_assert(brpcmgr);
ks_assert(method);
ks_assert(protocol);
key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
brpc = ks_hash_search(brpcmgr->protocolrpcs, (void *)key, KS_READLOCKED);
// @todo if (brpc) blade_rpc_read_lock(brpc);
ks_hash_read_unlock(brpcmgr->protocolrpcs);
ks_pool_free(&key);
return brpc;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc)
{
const char *method = NULL;
const char *protocol = NULL;
char *key = NULL;
ks_assert(brpcmgr);
ks_assert(brpc);
method = blade_rpc_method_get(brpc);
ks_assert(method);
protocol = blade_rpc_protocol_get(brpc);
ks_assert(protocol);
key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
ks_assert(key);
ks_hash_insert(brpcmgr->protocolrpcs, (void *)key, (void *)brpc);
ks_log(KS_LOG_DEBUG, "ProtocolRPC Added: %s\n", key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc)
{
const char *method = NULL;
const char *protocol = NULL;
char *key = NULL;
ks_assert(brpcmgr);
ks_assert(brpc);
method = blade_rpc_method_get(brpc);
ks_assert(method);
protocol = blade_rpc_protocol_get(brpc);
ks_assert(protocol);
key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
ks_assert(key);
ks_hash_remove(brpcmgr->protocolrpcs, (void *)key);
ks_log(KS_LOG_DEBUG, "ProtocolRPC Removed: %s\n", key);
ks_pool_free(&key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_rpc_request_t *) blade_rpcmgr_request_lookup(blade_rpcmgr_t *brpcmgr, const char *id)
{
blade_rpc_request_t *brpcreq = NULL;
ks_assert(brpcmgr);
ks_assert(id);
brpcreq = (blade_rpc_request_t *)ks_hash_search(brpcmgr->requests, (void *)id, KS_READLOCKED);
// @todo if (brpcreq) blade_rpc_request_read_lock(brpcreq);
ks_hash_read_unlock(brpcmgr->requests);
return brpcreq;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_request_add(blade_rpcmgr_t *brpcmgr, blade_rpc_request_t *brpcreq)
{
char *key = NULL;
ks_assert(brpcmgr);
ks_assert(brpcreq);
key = ks_pstrdup(ks_pool_get(brpcmgr), blade_rpc_request_messageid_get(brpcreq));
ks_hash_insert(brpcmgr->requests, (void *)key, (void *)brpcreq);
ks_log(KS_LOG_DEBUG, "Request Added: %s\n", key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_request_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_request_t *brpcreq)
{
const char *id = NULL;
ks_assert(brpcmgr);
ks_assert(brpcreq);
id = blade_rpc_request_messageid_get(brpcreq);
ks_hash_remove(brpcmgr->requests, (void *)id);
ks_log(KS_LOG_DEBUG, "Request Removed: %s\n", id);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_rpcmgr_request_timeouts(blade_rpcmgr_t *brpcmgr)
{
blade_session_t *loopback = NULL;
ks_assert(brpcmgr);
// All this stuff is to ensure that the requests hash is not locked up when it does not need to be,
// and this will also ensure that sessions will not lock up if any other session is trying to deal
// with timeouts already
if (ks_mutex_trylock(brpcmgr->requests_ttlcheck_lock) != KS_STATUS_SUCCESS) return KS_STATUS_SUCCESS;
if (brpcmgr->requests_ttlcheck > ks_time_now()) {
ks_mutex_unlock(brpcmgr->requests_ttlcheck_lock);
return KS_STATUS_SUCCESS;
}
ks_hash_write_lock(brpcmgr->requests);
// Give a one second delay between timeout checking
brpcmgr->requests_ttlcheck = ks_time_now() + KS_USEC_PER_SEC;
ks_mutex_unlock(brpcmgr->requests_ttlcheck_lock);
// Now find all the expired requests and send out loopback error responses, which will invoke request removal when received and processed
for (ks_hash_iterator_t *it = ks_hash_first(brpcmgr->requests, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
blade_rpc_request_t *value = NULL;
cJSON *res = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
if (!blade_rpc_request_expired(value)) continue;
if (!loopback) loopback = blade_sessionmgr_loopback_lookup(blade_handle_sessionmgr_get(brpcmgr->handle));
ks_log(KS_LOG_DEBUG, "Request (%s) TTL timeout\n", key);
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(value), -32000, "Request timed out");
// @todo may want to include requester-nodeid and responder-nodeid into the error block when they are present in the original request
// even though a response or error without them is treated as locally processed, it may be useful to know who the request was attempted with
// when multiple options are available such as a blade.execute where the protocol has multiple possible controllers to pick from
blade_session_send(loopback, res, 0, NULL, NULL);
cJSON_Delete(res);
}
if (loopback) blade_session_read_unlock(loopback);
ks_hash_write_unlock(brpcmgr->requests);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,810 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_session_s {
blade_handle_t *handle;
blade_session_flags_t flags;
const char *id;
ks_rwl_t *lock;
volatile blade_session_state_t state;
ks_cond_t *cond;
const char *connection;
ks_time_t ttl;
ks_q_t *sending;
ks_q_t *receiving;
ks_hash_t *routes;
cJSON *properties;
ks_rwl_t *properties_lock;
};
void *blade_session_state_thread(ks_thread_t *thread, void *data);
ks_status_t blade_session_onstate_startup(blade_session_t *bs);
ks_status_t blade_session_onstate_shutdown(blade_session_t *bs);
ks_status_t blade_session_onstate_run(blade_session_t *bs);
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json);
static void blade_session_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_session_t *bs = (blade_session_t *)ptr;
ks_assert(bs);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
blade_session_shutdown(bs);
break;
case KS_MPCL_DESTROY:
// @todo consider looking at supporting externally allocated memory entries that can have cleanup callbacks associated, but the memory is not freed from the pool, only linked as an external allocation for auto cleanup
// which would allow calling something like ks_pool_set_cleanup(bs->properties, ...) and when the pool is destroyed, it can call a callback which handles calling cJSON_Delete, which is allocated externally
cJSON_Delete(bs->properties);
break;
}
}
KS_DECLARE(ks_status_t) blade_session_create(blade_session_t **bsP, blade_handle_t *bh, blade_session_flags_t flags, const char *sessionid)
{
blade_session_t *bs = NULL;
ks_pool_t *pool = NULL;
ks_assert(bsP);
ks_assert(bh);
ks_pool_open(&pool);
ks_assert(pool);
bs = ks_pool_alloc(pool, sizeof(blade_session_t));
bs->handle = bh;
bs->flags = flags;
if (sessionid) bs->id = ks_pstrdup(pool, sessionid);
else {
uuid_t id;
ks_uuid(&id);
bs->id = ks_uuid_str(pool, &id);
}
ks_rwl_create(&bs->lock, pool);
ks_assert(bs->lock);
bs->state = BLADE_SESSION_STATE_NONE;
ks_cond_create(&bs->cond, pool);
ks_assert(bs->cond);
ks_q_create(&bs->sending, pool, 0);
ks_assert(bs->sending);
ks_q_create(&bs->receiving, pool, 0);
ks_assert(bs->receiving);
ks_hash_create(&bs->routes, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bs->routes);
bs->properties = cJSON_CreateObject();
ks_assert(bs->properties);
ks_rwl_create(&bs->properties_lock, pool);
ks_assert(bs->properties_lock);
ks_pool_set_cleanup(bs, NULL, blade_session_cleanup);
ks_log(KS_LOG_DEBUG, "Created\n");
*bsP = bs;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_destroy(blade_session_t **bsP)
{
blade_session_t *bs = NULL;
ks_pool_t *pool = NULL;
ks_assert(bsP);
ks_assert(*bsP);
bs = *bsP;
*bsP = NULL;
pool = ks_pool_get(bs);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_startup(blade_session_t *bs)
{
ks_thread_pool_t *tpool = NULL;
ks_assert(bs);
tpool = blade_handle_tpool_get(bs->handle);
ks_assert(tpool);
if (ks_thread_pool_add_job(tpool, blade_session_state_thread, bs) != KS_STATUS_SUCCESS) {
// @todo error logging
return KS_STATUS_FAIL;
}
ks_log(KS_LOG_DEBUG, "Started\n");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs)
{
ks_hash_iterator_t *it = NULL;
cJSON *json = NULL;
ks_assert(bs);
// make sure this is done first to remove the upstream session before it is attempted to be used for sending route updates
blade_sessionmgr_session_remove(blade_handle_sessionmgr_get(bs->handle), bs);
// if this is an upstream session there will be no routes, so this is harmless to always run regardless
ks_hash_read_lock(bs->routes);
for (it = ks_hash_first(bs->routes, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
blade_routemgr_route_remove(blade_handle_routemgr_get(bs->handle), (const char *)key);
}
ks_hash_read_unlock(bs->routes);
while (ks_q_trypop(bs->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
while (ks_q_trypop(bs->receiving, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
ks_log(KS_LOG_DEBUG, "Stopped\n");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_session_handle_get(blade_session_t *bs)
{
ks_assert(bs);
return bs->handle;
}
KS_DECLARE(ks_bool_t) blade_session_loopback(blade_session_t *bs)
{
ks_assert(bs);
return (bs->flags & BLADE_SESSION_FLAGS_LOOPBACK) == BLADE_SESSION_FLAGS_LOOPBACK;
}
KS_DECLARE(ks_bool_t) blade_session_upstream(blade_session_t *bs)
{
ks_assert(bs);
return (bs->flags & BLADE_SESSION_FLAGS_UPSTREAM) == BLADE_SESSION_FLAGS_UPSTREAM;
}
KS_DECLARE(const char *) blade_session_id_get(blade_session_t *bs)
{
ks_assert(bs);
return bs->id;
}
KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs)
{
ks_assert(bs);
return bs->state;
}
KS_DECLARE(ks_status_t) blade_session_route_add(blade_session_t *bs, const char *nodeid)
{
char *key = NULL;
ks_assert(bs);
ks_assert(nodeid);
key = ks_pstrdup(ks_pool_get(bs), nodeid);
ks_hash_insert(bs->routes, (void *)key, (void *)KS_TRUE);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_route_remove(blade_session_t *bs, const char *nodeid)
{
ks_assert(bs);
ks_assert(nodeid);
ks_hash_remove(bs->routes, (void *)nodeid);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(cJSON *) blade_session_properties_get(blade_session_t *bs)
{
ks_assert(bs);
return bs->properties;
}
KS_DECLARE(ks_status_t) blade_session_read_lock(blade_session_t *bs, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bs);
if (block) ret = ks_rwl_read_lock(bs->lock);
else ret = ks_rwl_try_read_lock(bs->lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_session_read_unlock(blade_session_t *bs)
{
ks_assert(bs);
return ks_rwl_read_unlock(bs->lock);
}
KS_DECLARE(ks_status_t) blade_session_write_lock(blade_session_t *bs, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bs);
if (block) ret = ks_rwl_write_lock(bs->lock);
else ret = ks_rwl_try_write_lock(bs->lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_session_write_unlock(blade_session_t *bs)
{
ks_assert(bs);
return ks_rwl_write_unlock(bs->lock);
}
KS_DECLARE(ks_status_t) blade_session_properties_read_lock(blade_session_t *bs, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bs);
if (block) ret = ks_rwl_read_lock(bs->properties_lock);
else ret = ks_rwl_try_read_lock(bs->properties_lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_session_properties_read_unlock(blade_session_t *bs)
{
ks_assert(bs);
return ks_rwl_read_unlock(bs->properties_lock);
}
KS_DECLARE(ks_status_t) blade_session_properties_write_lock(blade_session_t *bs, ks_bool_t block)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bs);
if (block) ret = ks_rwl_write_lock(bs->properties_lock);
else ret = ks_rwl_try_write_lock(bs->properties_lock);
return ret;
}
KS_DECLARE(ks_status_t) blade_session_properties_write_unlock(blade_session_t *bs)
{
ks_assert(bs);
return ks_rwl_write_unlock(bs->properties_lock);
}
KS_DECLARE(void) blade_session_state_set(blade_session_t *bs, blade_session_state_t state)
{
ks_assert(bs);
ks_cond_lock(bs->cond);
bs->state = state;
blade_sessionmgr_callback_execute(blade_handle_sessionmgr_get(bs->handle), bs, BLADE_SESSION_STATE_CONDITION_PRE);
ks_cond_unlock(bs->cond);
ks_cond_try_signal(bs->cond);
}
KS_DECLARE(void) blade_session_hangup(blade_session_t *bs)
{
ks_assert(bs);
if (!blade_session_terminating(bs)) {
ks_log(KS_LOG_DEBUG, "Session (%s) hanging up\n", bs->id);
blade_session_state_set(bs, BLADE_SESSION_STATE_SHUTDOWN);
}
}
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs)
{
ks_assert(bs);
return bs->state == BLADE_SESSION_STATE_SHUTDOWN || bs->state == BLADE_SESSION_STATE_CLEANUP;
}
KS_DECLARE(const char *) blade_session_connection_get(blade_session_t *bs)
{
ks_assert(bs);
return bs->connection;
}
KS_DECLARE(ks_status_t) blade_session_connection_set(blade_session_t *bs, const char *id)
{
ks_assert(bs);
if (id) {
if (bs->connection) {
// @todo best that can be done in this situation is see if the connection is still available, and if so then disconnect it... this really shouldn't happen
ks_pool_free(&bs->connection);
}
bs->connection = ks_pstrdup(ks_pool_get(bs), id);
ks_assert(bs->connection);
bs->ttl = 0;
ks_log(KS_LOG_DEBUG, "Session (%s) associated to connection (%s)\n", bs->id, id);
// @todo signal the wait condition for the state machine to see a reconnect immediately
} else if (bs->connection) {
ks_log(KS_LOG_DEBUG, "Session (%s) cleared connection (%s)\n", bs->id, bs->connection);
ks_pool_free(&bs->connection);
bs->ttl = ks_time_now() + (5 * KS_USEC_PER_SEC);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json)
{
ks_status_t ret = KS_STATUS_SUCCESS;
cJSON *json_copy = NULL;
ks_assert(bs);
ks_assert(json);
if ((bs->flags & BLADE_SESSION_FLAGS_LOOPBACK) == BLADE_SESSION_FLAGS_LOOPBACK)
ret = blade_session_receiving_push(bs, json);
else {
json_copy = cJSON_Duplicate(json, 1);
if ((ret = ks_q_push(bs->sending, json_copy)) == KS_STATUS_SUCCESS) ks_cond_try_signal(bs->cond);
}
return ret;
}
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json)
{
ks_assert(bs);
ks_assert(json);
return ks_q_trypop(bs->sending, (void **)json);
}
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json)
{
ks_status_t ret = KS_STATUS_SUCCESS;
cJSON *json_copy = NULL;
ks_assert(bs);
ks_assert(json);
json_copy = cJSON_Duplicate(json, 1);
if ((ret = ks_q_push(bs->receiving, json_copy)) == KS_STATUS_SUCCESS) ks_cond_try_signal(bs->cond);
return ret;
}
KS_DECLARE(ks_status_t) blade_session_receiving_pop(blade_session_t *bs, cJSON **json)
{
ks_assert(bs);
ks_assert(json);
return ks_q_trypop(bs->receiving, (void **)json);
}
void *blade_session_state_thread(ks_thread_t *thread, void *data)
{
blade_session_t *bs = NULL;
blade_session_state_t state;
cJSON *json = NULL;
ks_bool_t shutdown = KS_FALSE;
ks_assert(thread);
ks_assert(data);
bs = (blade_session_t *)data;
ks_cond_lock(bs->cond);
while (!shutdown) {
// Entering the call below, the mutex is expected to be locked and will be unlocked by the call
ks_cond_timedwait(bs->cond, 100);
// Leaving the call above, the mutex will be locked after being signalled, timing out, or woken up for any reason
state = bs->state;
if (bs->connection) {
blade_connection_t *bc = blade_connectionmgr_connection_lookup(blade_handle_connectionmgr_get(bs->handle), bs->connection);
if (bc) {
// @note in order for this to work on session reconnecting, the assumption is that as soon as a session has a connection set,
// we can start stuffing any messages queued for output on the session straight to the connection right away, may need to only
// do this when in session ready state but there may be implications of other states sending messages through the session
while (blade_session_sending_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
blade_connection_sending_push(bc, json);
cJSON_Delete(json);
}
blade_connection_read_unlock(bc);
}
}
// @todo evolve this system, it's probably not the best way to handle receiving session state updates externally
blade_sessionmgr_callback_execute(blade_handle_sessionmgr_get(bs->handle), bs, BLADE_SESSION_STATE_CONDITION_POST);
switch (state) {
case BLADE_SESSION_STATE_STARTUP:
blade_session_onstate_startup(bs);
break;
case BLADE_SESSION_STATE_SHUTDOWN:
blade_session_onstate_shutdown(bs);
shutdown = KS_TRUE;
break;
case BLADE_SESSION_STATE_RUN:
blade_session_onstate_run(bs);
break;
default: break;
}
if ((bs->flags & BLADE_SESSION_FLAGS_LOOPBACK) != BLADE_SESSION_FLAGS_LOOPBACK &&
!bs->connection &&
bs->ttl > 0 &&
!blade_session_terminating(bs) &&
ks_time_now() >= bs->ttl) {
ks_log(KS_LOG_DEBUG, "Session (%s) TTL timeout\n", bs->id);
blade_session_hangup(bs);
}
}
ks_cond_unlock(bs->cond);
blade_session_destroy(&bs);
return NULL;
}
ks_status_t blade_session_onstate_startup(blade_session_t *bs)
{
ks_assert(bs);
ks_log(KS_LOG_DEBUG, "Session (%s) state startup\n", bs->id);
blade_session_state_set(bs, BLADE_SESSION_STATE_RUN);
return KS_STATUS_SUCCESS;
}
ks_status_t blade_session_onstate_shutdown(blade_session_t *bs)
{
ks_assert(bs);
ks_log(KS_LOG_DEBUG, "Session (%s) state shutdown\n", bs->id);
blade_session_state_set(bs, BLADE_SESSION_STATE_CLEANUP);
if (bs->connection) {
blade_connection_t *bc = blade_connectionmgr_connection_lookup(blade_handle_connectionmgr_get(bs->handle), bs->connection);
if (bc) {
blade_connection_disconnect(bc);
blade_connection_read_unlock(bc);
}
}
// wait for the connection to disconnect before we resume session cleanup
while (bs->connection) ks_sleep(100);
return KS_STATUS_SUCCESS;
}
ks_status_t blade_session_onstate_run(blade_session_t *bs)
{
cJSON *json = NULL;
ks_assert(bs);
while (blade_session_receiving_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
blade_session_process(bs, json);
cJSON_Delete(json);
}
blade_rpcmgr_request_timeouts(blade_handle_rpcmgr_get(blade_session_handle_get(bs)));
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, ks_time_t ttl, blade_rpc_response_callback_t callback, void *data)
{
blade_rpc_request_t *brpcreq = NULL;
const char *method = NULL;
const char *id = NULL;
ks_assert(bs);
ks_assert(json);
method = cJSON_GetObjectCstr(json, "method");
id = cJSON_GetObjectCstr(json, "id");
ks_assert(id);
if (method) {
ks_log(KS_LOG_DEBUG, "Session (%s) sending request (%s) for %s\n", bs->id, id, method);
blade_rpc_request_create(&brpcreq, bs->handle, ks_pool_get(bs->handle), bs->id, json, callback, data);
ks_assert(brpcreq);
// @todo update to get default ttl from configuration
if (ttl <= 0) ttl = 10;
blade_rpc_request_ttl_set(brpcreq, ttl);
blade_rpcmgr_request_add(blade_handle_rpcmgr_get(bs->handle), brpcreq);
} else {
ks_log(KS_LOG_DEBUG, "Session (%s) sending response (%s)\n", bs->id, id);
}
if (!bs->connection) {
blade_session_sending_push(bs, json);
} else {
blade_connection_t *bc = blade_connectionmgr_connection_lookup(blade_handle_connectionmgr_get(bs->handle), bs->connection);
if (!bc) {
blade_session_sending_push(bs, json);
return KS_STATUS_FAIL;
}
blade_connection_sending_push(bc, json);
blade_connection_read_unlock(bc);
}
return KS_STATUS_SUCCESS;
}
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
{
blade_handle_t *bh = NULL;
blade_rpc_request_t *brpcreq = NULL;
blade_rpc_response_t *brpcres = NULL;
const char *jsonrpc = NULL;
const char *id = NULL;
const char *method = NULL;
ks_bool_t disconnect = KS_FALSE;
ks_assert(bs);
ks_assert(json);
ks_log(KS_LOG_DEBUG, "Session (%s) processing\n", bs->id);
bh = blade_session_handle_get(bs);
ks_assert(bh);
jsonrpc = cJSON_GetObjectCstr(json, "jsonrpc");
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
ks_log(KS_LOG_DEBUG, "Received message is not the expected protocol\n");
// @todo send error response, code = -32600 (invalid request)
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
id = cJSON_GetObjectCstr(json, "id");
if (!id) {
ks_log(KS_LOG_DEBUG, "Received message is missing 'id'\n");
// @todo send error response, code = -32600 (invalid request)
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
method = cJSON_GetObjectCstr(json, "method");
if (method) {
// @note This is scenario 2
// 2) Receiving a request (server: method callee or provider)
blade_rpc_t *brpc = NULL;
blade_rpc_request_callback_t callback = NULL;
cJSON *params = NULL;
const char *params_requester_nodeid = NULL;
const char *params_responder_nodeid = NULL;
ks_log(KS_LOG_DEBUG, "Session (%s) receiving request (%s) for %s\n", bs->id, id, method);
params = cJSON_GetObjectItem(json, "params");
if (params) {
params_requester_nodeid = cJSON_GetObjectCstr(params, "requester-nodeid");
params_responder_nodeid = cJSON_GetObjectCstr(params, "responder-nodeid");
if (params_requester_nodeid && params_responder_nodeid && !blade_routemgr_local_check(blade_handle_routemgr_get(bh), params_responder_nodeid)) {
// not meant for local processing, continue with standard unicast routing for requests
blade_session_t *bs_router = blade_routemgr_route_lookup(blade_handle_routemgr_get(bh), params_responder_nodeid);
if (!bs_router) {
bs_router = blade_sessionmgr_upstream_lookup(blade_handle_sessionmgr_get(bh));
if (!bs_router) {
cJSON *res = NULL;
cJSON *res_error = NULL;
// @todo adjust error when this is master to be route unavailable
ks_log(KS_LOG_DEBUG, "Session (%s) request (%s => %s) but upstream session unavailable\n", blade_session_id_get(bs), params_requester_nodeid, params_responder_nodeid);
blade_rpc_error_raw_create(&res, &res_error, id, -32603, "Upstream session unavailable");
// needed in case this error must propagate further than the session which sent it
cJSON_AddStringToObject(res_error, "requester-nodeid", params_requester_nodeid);
cJSON_AddStringToObject(res_error, "responder-nodeid", params_responder_nodeid); // @todo responder-nodeid should become the local_nodeid to inform of which node actually responded
blade_session_send(bs, res, 0, NULL, NULL);
return KS_STATUS_DISCONNECTED;
}
}
if (bs_router == bs) {
// @todo avoid circular by sending back an error instead, really should not happen but check for posterity in case a node is misbehaving for some reason
}
ks_log(KS_LOG_DEBUG, "Session (%s) request (%s => %s) routing (%s)\n", blade_session_id_get(bs), params_requester_nodeid, params_responder_nodeid, blade_session_id_get(bs_router));
blade_session_send(bs_router, json, 0, NULL, NULL);
blade_session_read_unlock(bs_router);
// @todo if this is a subscribe request to remove subscriptions, it must carry a field unsubscribed-channels for which
// subscriptions should be removed along the request path, regardless of whether it's the consumer requesting or the
// master due to a deauthorization, without respect to waiting for the response as it should be a gaurenteed operation
// even when requested by the subscriber. This unsubscribed-channels field is simply treated as a special field, regardless
// of the actual method of the request.
return KS_STATUS_SUCCESS;
}
}
// reach here if the request was not captured for routing, this SHOULD always mean the message is to be processed by local handlers
brpc = blade_rpcmgr_corerpc_lookup(blade_handle_rpcmgr_get(bs->handle), method);
if (!brpc) {
cJSON *res = NULL;
cJSON *res_error = NULL;
ks_log(KS_LOG_DEBUG, "Received unknown rpc method %s\n", method);
blade_rpc_error_raw_create(&res, &res_error, id, -32601, "RPC method not found");
// needed in case this error must propagate further than the session which sent it
if (params_requester_nodeid) cJSON_AddStringToObject(res_error, "requester-nodeid", params_requester_nodeid);
if (params_responder_nodeid) cJSON_AddStringToObject(res_error, "responder-nodeid", params_responder_nodeid);
blade_session_send(bs, res, 0, NULL, NULL);
return KS_STATUS_FAIL;
}
callback = blade_rpc_callback_get(brpc);
ks_assert(callback);
blade_rpc_request_create(&brpcreq, bs->handle, ks_pool_get(bs->handle), bs->id, json, NULL, NULL);
ks_assert(brpcreq);
disconnect = callback(brpcreq, blade_rpc_data_get(brpc));
blade_rpc_request_destroy(&brpcreq);
} else {
// @note This is scenario 4
// 4) Receiving a response or error (client: method caller or consumer)
blade_rpc_response_callback_t callback = NULL;
cJSON *error = NULL;
cJSON *result = NULL;
cJSON *object = NULL;
ks_log(KS_LOG_DEBUG, "Session (%s) receiving response (%s)\n", bs->id, id);
error = cJSON_GetObjectItem(json, "error");
result = cJSON_GetObjectItem(json, "result");
object = error ? error : result;
if (object) {
const char *object_requester_nodeid = cJSON_GetObjectCstr(object, "requester-nodeid");
const char *object_responder_nodeid = cJSON_GetObjectCstr(object, "responder-nodeid");
if (object_requester_nodeid && object_responder_nodeid && !blade_routemgr_local_check(blade_handle_routemgr_get(bh), object_requester_nodeid)) {
// not meant for local processing, continue with standard unicast routing for responses
blade_session_t *bs_router = blade_routemgr_route_lookup(blade_handle_routemgr_get(bh), object_requester_nodeid);
if (!bs_router) {
bs_router = blade_sessionmgr_upstream_lookup(blade_handle_sessionmgr_get(bh));
if (!bs_router) {
ks_log(KS_LOG_DEBUG, "Session (%s) response (%s <= %s) but upstream session unavailable\n", blade_session_id_get(bs), object_requester_nodeid, object_responder_nodeid);
return KS_STATUS_DISCONNECTED;
}
}
if (bs_router == bs) {
// @todo avoid circular, really should not happen but check for posterity in case a node is misbehaving for some reason
}
ks_log(KS_LOG_DEBUG, "Session (%s) response (%s <= %s) routing (%s)\n", blade_session_id_get(bs), object_requester_nodeid, object_responder_nodeid, blade_session_id_get(bs_router));
blade_session_send(bs_router, json, 0, NULL, NULL);
blade_session_read_unlock(bs_router);
// @todo if this is a subscribe response to add a subscriber with the master as the responder-nodeid, it must have a
// subscribed-channels field which should be added for the requester-nodeid, this will ensure the subscriptions are
// added with respect to the master response and not immediately upon request. This subscribed-channels field is
// simply treated as a special field, regardless of the actual method of the request which is unavailable here.
return KS_STATUS_SUCCESS;
}
}
brpcreq = blade_rpcmgr_request_lookup(blade_handle_rpcmgr_get(bs->handle), id);
if (!brpcreq) {
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
blade_rpcmgr_request_remove(blade_handle_rpcmgr_get(bs->handle), brpcreq);
callback = blade_rpc_request_callback_get(brpcreq);
blade_rpc_response_create(&brpcres, bs->handle, ks_pool_get(bs), bs->id, brpcreq, json);
ks_assert(brpcres);
if (callback) disconnect = callback(brpcres, blade_rpc_request_data_get(brpcreq));
blade_rpc_response_destroy(&brpcres);
}
if (disconnect) {
// @todo hangup session entirely?
return KS_STATUS_FAIL;
}
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,338 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_sessionmgr_s {
blade_handle_t *handle;
blade_session_t *loopback;
blade_session_t *upstream;
ks_hash_t *sessions; // id, blade_session_t*
ks_hash_t *callbacks; // id, blade_session_callback_data_t*
};
struct blade_session_callback_data_s {
const char *id;
void *data;
blade_session_callback_t callback;
};
static void blade_sessionmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_sessionmgr_t *bsmgr = (blade_sessionmgr_t *)ptr;
//ks_assert(bsmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
static void blade_session_callback_data_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_session_callback_data_t *bscd = (blade_session_callback_data_t *)ptr;
ks_assert(bscd);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
ks_pool_free(&bscd->id);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_sessionmgr_create(blade_sessionmgr_t **bsmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_sessionmgr_t *bsmgr = NULL;
ks_assert(bsmgrP);
ks_pool_open(&pool);
ks_assert(pool);
bsmgr = ks_pool_alloc(pool, sizeof(blade_sessionmgr_t));
bsmgr->handle = bh;
ks_hash_create(&bsmgr->sessions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bsmgr->sessions);
ks_hash_create(&bsmgr->callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bsmgr->callbacks);
ks_pool_set_cleanup(bsmgr, NULL, blade_sessionmgr_cleanup);
*bsmgrP = bsmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_destroy(blade_sessionmgr_t **bsmgrP)
{
blade_sessionmgr_t *bsmgr = NULL;
ks_pool_t *pool;
ks_assert(bsmgrP);
ks_assert(*bsmgrP);
bsmgr = *bsmgrP;
*bsmgrP = NULL;
pool = ks_pool_get(bsmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_sessionmgr_handle_get(blade_sessionmgr_t *bsmgr)
{
ks_assert(bsmgr);
return bsmgr->handle;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_startup(blade_sessionmgr_t *bsmgr, config_setting_t *config)
{
ks_assert(bsmgr);
blade_session_create(&bsmgr->loopback, bsmgr->handle, BLADE_SESSION_FLAGS_LOOPBACK, NULL);
ks_assert(bsmgr->loopback);
ks_log(KS_LOG_DEBUG, "Session (%s) created\n", blade_session_id_get(bsmgr->loopback));
if (blade_session_startup(bsmgr->loopback) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "Session (%s) startup failed\n", blade_session_id_get(bsmgr->loopback));
blade_session_destroy(&bsmgr->loopback);
return KS_STATUS_FAIL;
}
ks_log(KS_LOG_DEBUG, "Session (%s) started\n", blade_session_id_get(bsmgr->loopback));
blade_sessionmgr_session_add(bsmgr, bsmgr->loopback);
blade_session_state_set(bsmgr->loopback, BLADE_SESSION_STATE_STARTUP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_shutdown(blade_sessionmgr_t *bsmgr)
{
ks_hash_iterator_t *it = NULL;
ks_assert(bsmgr);
//if (bsmgr->loopback) {
// blade_session_hangup(bsmgr->loopback);
// ks_sleep_ms(100);
//}
ks_hash_read_lock(bsmgr->sessions);
for (it = ks_hash_first(bsmgr->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_session_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
blade_session_hangup(value);
}
ks_hash_read_unlock(bsmgr->sessions);
while (ks_hash_count(bsmgr->sessions) > 0) ks_sleep_ms(100);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_session_t *) blade_sessionmgr_loopback_lookup(blade_sessionmgr_t *bsmgr)
{
ks_assert(bsmgr);
blade_session_read_lock(bsmgr->loopback, KS_TRUE);
return bsmgr->loopback;
}
KS_DECLARE(blade_session_t *) blade_sessionmgr_upstream_lookup(blade_sessionmgr_t *bsmgr)
{
ks_assert(bsmgr);
if (bsmgr->upstream) blade_session_read_lock(bsmgr->upstream, KS_TRUE);
return bsmgr->upstream;
}
KS_DECLARE(blade_session_t *) blade_sessionmgr_session_lookup(blade_sessionmgr_t *bsmgr, const char *id)
{
blade_session_t *bs = NULL;
ks_assert(bsmgr);
ks_assert(id);
bs = ks_hash_search(bsmgr->sessions, (void *)id, KS_READLOCKED);
if (bs) blade_session_read_lock(bs, KS_TRUE);
ks_hash_read_unlock(bsmgr->sessions);
return bs;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_session_add(blade_sessionmgr_t *bsmgr, blade_session_t *bs)
{
char *key = NULL;
ks_assert(bsmgr);
ks_assert(bs);
key = ks_pstrdup(ks_pool_get(bsmgr), blade_session_id_get(bs));
ks_hash_insert(bsmgr->sessions, (void *)key, bs);
ks_log(KS_LOG_DEBUG, "Session Added: %s\n", key);
if (blade_session_upstream(bs)) bsmgr->upstream = bs;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmgr, blade_session_t *bs)
{
const char *id = NULL;
blade_routemgr_t *routemgr = NULL;
ks_assert(bsmgr);
ks_assert(bs);
blade_session_write_lock(bs, KS_TRUE);
id = blade_session_id_get(bs);
ks_hash_remove(bsmgr->sessions, (void *)id);
ks_log(KS_LOG_DEBUG, "Session Removed: %s\n", id);
routemgr = blade_handle_routemgr_get(bsmgr->handle);
if (blade_session_upstream(bs)) {
bsmgr->upstream = NULL;
blade_routemgr_local_set(routemgr, NULL);
blade_routemgr_master_set(routemgr, NULL);
ks_hash_read_lock(bsmgr->sessions);
for (ks_hash_iterator_t *it = ks_hash_first(bsmgr->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_session_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
if (blade_session_loopback(value)) continue;
blade_session_hangup(value);
}
ks_hash_read_unlock(bsmgr->sessions);
}
blade_session_write_unlock(bs);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_callback_add(blade_sessionmgr_t *bsmgr, void *data, blade_session_callback_t callback, const char **id)
{
ks_pool_t *pool = NULL;
blade_session_callback_data_t *bscd = NULL;
uuid_t uuid;
ks_assert(bsmgr);
ks_assert(callback);
ks_assert(id);
pool = ks_pool_get(bsmgr);
ks_uuid(&uuid);
bscd = ks_pool_alloc(pool, sizeof(blade_session_callback_data_t));
bscd->id = ks_uuid_str(pool, &uuid);
bscd->data = data;
bscd->callback = callback;
ks_pool_set_cleanup(bscd, NULL, blade_session_callback_data_cleanup);
ks_hash_insert(bsmgr->callbacks, (void *)ks_pstrdup(pool, bscd->id), bscd);
*id = bscd->id;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_sessionmgr_callback_remove(blade_sessionmgr_t *bsmgr, const char *id)
{
ks_assert(bsmgr);
ks_assert(id);
ks_hash_remove(bsmgr->callbacks, (void *)id);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(void) blade_sessionmgr_callback_execute(blade_sessionmgr_t *bsmgr, blade_session_t *bs, blade_session_state_condition_t condition)
{
ks_assert(bsmgr);
ks_assert(bs);
if (blade_session_state_get(bs) == BLADE_SESSION_STATE_NONE) return;
ks_hash_read_lock(bsmgr->callbacks);
for (ks_hash_iterator_t *it = ks_hash_first(bsmgr->callbacks, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_session_callback_data_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
value->callback(bs, condition, value->data);
}
ks_hash_read_unlock(bsmgr->callbacks);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_subscription_s {
const char *protocol;
const char *channel;
ks_hash_t *subscribers;
blade_rpc_request_callback_t callback;
void *callback_data;
};
static void blade_subscription_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_subscription_t *bsub = (blade_subscription_t *)ptr;
ks_assert(bsub);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
if (bsub->protocol) ks_pool_free(&bsub->protocol);
if (bsub->channel) ks_pool_free(&bsub->channel);
if (bsub->subscribers) ks_hash_destroy(&bsub->subscribers);
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *channel)
{
blade_subscription_t *bsub = NULL;
ks_assert(bsubP);
ks_assert(pool);
ks_assert(protocol);
ks_assert(channel);
bsub = ks_pool_alloc(pool, sizeof(blade_subscription_t));
bsub->protocol = ks_pstrdup(pool, protocol);
bsub->channel = ks_pstrdup(pool, channel);
ks_hash_create(&bsub->subscribers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bsub->subscribers);
ks_pool_set_cleanup(bsub, NULL, blade_subscription_cleanup);
*bsubP = bsub;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_subscription_destroy(blade_subscription_t **bsubP)
{
ks_assert(bsubP);
ks_assert(*bsubP);
ks_pool_free(bsubP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_subscription_protocol_get(blade_subscription_t *bsub)
{
ks_assert(bsub);
return bsub->protocol;
}
KS_DECLARE(const char *) blade_subscription_channel_get(blade_subscription_t *bsub)
{
ks_assert(bsub);
return bsub->channel;
}
KS_DECLARE(ks_hash_t *) blade_subscription_subscribers_get(blade_subscription_t *bsub)
{
ks_assert(bsub);
return bsub->subscribers;
}
KS_DECLARE(ks_status_t) blade_subscription_subscribers_add(blade_subscription_t *bsub, const char *nodeid)
{
char *key = NULL;
ks_assert(bsub);
ks_assert(nodeid);
key = ks_pstrdup(ks_pool_get(bsub), nodeid);
ks_hash_insert(bsub->subscribers, (void *)key, (void *)KS_TRUE);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_subscription_subscribers_remove(blade_subscription_t *bsub, const char *nodeid)
{
ks_assert(bsub);
ks_assert(nodeid);
ks_hash_remove(bsub->subscribers, (void *)nodeid);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_rpc_request_callback_t) blade_subscription_callback_get(blade_subscription_t *bsub)
{
ks_assert(bsub);
return bsub->callback;
}
KS_DECLARE(void) blade_subscription_callback_set(blade_subscription_t *bsub, blade_rpc_request_callback_t callback)
{
ks_assert(bsub);
bsub->callback = callback;
}
KS_DECLARE(void *) blade_subscription_callback_data_get(blade_subscription_t *bsub)
{
ks_assert(bsub);
return bsub->callback_data;
}
KS_DECLARE(void) blade_subscription_callback_data_set(blade_subscription_t *bsub, void *data)
{
ks_assert(bsub);
bsub->callback_data = data;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,509 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_subscriptionmgr_s {
blade_handle_t *handle;
ks_hash_t *subscriptions; // key, blade_subscription_t*
ks_hash_t *subscriptions_cleanup; // target, ks_hash_t*
};
static void blade_subscriptionmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_routemgr_t *brmgr = (blade_routemgr_t *)ptr;
//ks_assert(brmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_subscriptionmgr_create(blade_subscriptionmgr_t **bsmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_subscriptionmgr_t *bsmgr = NULL;
ks_assert(bsmgrP);
ks_pool_open(&pool);
ks_assert(pool);
bsmgr = ks_pool_alloc(pool, sizeof(blade_subscriptionmgr_t));
bsmgr->handle = bh;
// @note can let removes free keys and values for subscriptions, both are allocated from the same pool as the hash itself
ks_hash_create(&bsmgr->subscriptions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bsmgr->subscriptions);
ks_hash_create(&bsmgr->subscriptions_cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bsmgr->subscriptions_cleanup);
ks_pool_set_cleanup(bsmgr, NULL, blade_subscriptionmgr_cleanup);
*bsmgrP = bsmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_subscriptionmgr_destroy(blade_subscriptionmgr_t **bsmgrP)
{
blade_subscriptionmgr_t *bsmgr = NULL;
ks_pool_t *pool;
ks_assert(bsmgrP);
ks_assert(*bsmgrP);
bsmgr = *bsmgrP;
*bsmgrP = NULL;
pool = ks_pool_get(bsmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_subscriptionmgr_handle_get(blade_subscriptionmgr_t *bsmgr)
{
ks_assert(bsmgr);
return bsmgr->handle;
}
//KS_DECLARE(blade_session_t *) blade_subscriptionmgr_route_lookup(blade_routemgr_t *brmgr, const char *target)
//{
// blade_session_t *bs = NULL;
// const char *router = NULL;
//
// ks_assert(brmgr);
// ks_assert(target);
//
// router = (const char *)ks_hash_search(brmgr->routes, (void *)target, KS_READLOCKED);
// if (router) bs = blade_handle_sessions_lookup(brmgr->handle, router);
// ks_hash_read_unlock(brmgr->routes);
//
// return bs;
//}
KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel)
{
blade_subscription_t *bsub = NULL;
char *key = NULL;
ks_assert(bsmgr);
ks_assert(protocol);
ks_assert(channel);
key = ks_psprintf(ks_pool_get(bsmgr), "%s:%s", protocol, channel);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)key, KS_READLOCKED);
// @todo if (bsub) blade_subscription_read_lock(bsub);
ks_hash_read_unlock(bsmgr->subscriptions);
ks_pool_free(&key);
return bsub;
}
KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel)
{
ks_pool_t *pool = NULL;
char *bsub_key = NULL;
blade_subscription_t *bsub = NULL;
ks_hash_t *subscribers = NULL;
ks_hash_t *subscriptions = NULL;
ks_assert(bsmgr);
ks_assert(protocol);
ks_assert(channel);
pool = ks_pool_get(bsmgr);
bsub_key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)bsub_key, KS_UNLOCKED);
subscribers = blade_subscription_subscribers_get(bsub);
ks_assert(subscribers);
for (ks_hash_iterator_t *it = ks_hash_first(subscribers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
subscriptions = (ks_hash_t *)ks_hash_search(bsmgr->subscriptions_cleanup, key, KS_UNLOCKED);
ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from protocol %s, channel %s\n", key, protocol, channel);
ks_hash_remove(subscriptions, bsub_key);
if (ks_hash_count(subscriptions) == 0) {
ks_hash_remove(bsmgr->subscriptions_cleanup, key);
}
}
ks_log(KS_LOG_DEBUG, "Subscription Removed: %s from %s\n", channel, protocol);
ks_hash_remove(bsmgr->subscriptions, (void *)bsub_key);
ks_hash_write_unlock(bsmgr->subscriptions);
ks_pool_free(&bsub_key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber)
{
ks_pool_t *pool = NULL;
char *key = NULL;
blade_subscription_t *bsub = NULL;
ks_hash_t *bsub_cleanup = NULL;
ks_bool_t propagate = KS_FALSE;
ks_assert(bsmgr);
ks_assert(protocol);
ks_assert(channel);
ks_assert(subscriber);
pool = ks_pool_get(bsmgr);
key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)key, KS_UNLOCKED);
if (!bsub) {
blade_subscription_create(&bsub, pool, protocol, channel);
ks_assert(bsub);
ks_hash_insert(bsmgr->subscriptions, (void *)ks_pstrdup(pool, key), (void *)bsub);
propagate = KS_TRUE;
}
bsub_cleanup = (ks_hash_t *)ks_hash_search(bsmgr->subscriptions_cleanup, (void *)subscriber, KS_UNLOCKED);
if (!bsub_cleanup) {
ks_hash_create(&bsub_cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bsub_cleanup);
ks_log(KS_LOG_DEBUG, "Subscription Added: %s to %s\n", channel, protocol);
ks_hash_insert(bsmgr->subscriptions_cleanup, (void *)ks_pstrdup(pool, subscriber), (void *)bsub_cleanup);
}
ks_hash_insert(bsub_cleanup, (void *)ks_pstrdup(pool, key), (void *)KS_TRUE);
blade_subscription_subscribers_add(bsub, subscriber);
ks_hash_write_unlock(bsmgr->subscriptions);
ks_log(KS_LOG_DEBUG, "Subscriber Added: %s to protocol %s, channel %s\n", subscriber, protocol, channel);
ks_pool_free(&key);
if (bsubP) *bsubP = bsub;
return propagate;
}
KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber)
{
char *key = NULL;
blade_subscription_t *bsub = NULL;
ks_hash_t *bsub_cleanup = NULL;
ks_bool_t propagate = KS_FALSE;
ks_assert(bsmgr);
ks_assert(protocol);
ks_assert(channel);
ks_assert(subscriber);
key = ks_psprintf(ks_pool_get(bsmgr), "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)key, KS_UNLOCKED);
if (bsub) {
bsub_cleanup = (ks_hash_t *)ks_hash_search(bsmgr->subscriptions_cleanup, (void *)subscriber, KS_UNLOCKED);
if (bsub_cleanup) {
ks_hash_remove(bsub_cleanup, key);
if (ks_hash_count(bsub_cleanup) == 0) {
ks_hash_remove(bsmgr->subscriptions_cleanup, (void *)subscriber);
}
ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from protocol %s, channel %s\n", subscriber, protocol, channel);
blade_subscription_subscribers_remove(bsub, subscriber);
if (ks_hash_count(blade_subscription_subscribers_get(bsub)) == 0) {
ks_log(KS_LOG_DEBUG, "Subscription Removed: %s from %s\n", channel, protocol);
ks_hash_remove(bsmgr->subscriptions, (void *)key);
propagate = KS_TRUE;
}
}
}
ks_hash_write_unlock(bsmgr->subscriptions);
ks_pool_free(&key);
if (bsubP) *bsubP = bsub;
return propagate;
}
KS_DECLARE(void) blade_subscriptionmgr_purge(blade_subscriptionmgr_t *bsmgr, const char *target)
{
ks_pool_t *pool = NULL;
ks_bool_t unsubbed = KS_FALSE;
ks_assert(bsmgr);
ks_assert(target);
pool = ks_pool_get(bsmgr);
while (!unsubbed) {
ks_hash_t *subscriptions = NULL;
const char *protocol = NULL;
const char *channel = NULL;
ks_hash_read_lock(bsmgr->subscriptions);
subscriptions = (ks_hash_t *)ks_hash_search(bsmgr->subscriptions_cleanup, (void *)target, KS_UNLOCKED);
if (!subscriptions) unsubbed = KS_TRUE;
else {
void *key = NULL;
void *value = NULL;
blade_subscription_t *bsub = NULL;
ks_hash_iterator_t *it = ks_hash_first(subscriptions, KS_UNLOCKED);
ks_assert(it);
ks_hash_this(it, (const void **)&key, NULL, &value);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, key, KS_UNLOCKED);
ks_assert(bsub);
// @note allocate these to avoid lifecycle issues when the last subscriber is removed causing the subscription to be removed
protocol = ks_pstrdup(pool, blade_subscription_protocol_get(bsub));
channel = ks_pstrdup(pool, blade_subscription_channel_get(bsub));
}
ks_hash_read_unlock(bsmgr->subscriptions);
if (!unsubbed) {
blade_subscriptionmgr_subscriber_remove(bsmgr, NULL, protocol, channel, target);
ks_pool_free(&protocol);
ks_pool_free(&channel);
}
}
}
KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_sessionid, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data)
{
ks_pool_t *pool = NULL;
const char *bsub_key = NULL;
blade_subscription_t *bsub = NULL;
blade_session_t *bs = NULL;
cJSON *req = NULL;
cJSON *req_params = NULL;
ks_hash_t *routers = NULL;
ks_hash_t *channels = NULL;
ks_assert(bsmgr);
ks_assert(protocol);
pool = ks_pool_get(bsmgr);
switch (command) {
case BLADE_RPCBROADCAST_COMMAND_EVENT:
ks_assert(channel);
ks_assert(event);
case BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE:
ks_assert(channel);
bsub_key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_read_lock(bsmgr->subscriptions);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)bsub_key, KS_UNLOCKED);
if (bsub) {
ks_hash_t *subscribers = blade_subscription_subscribers_get(bsub);
ks_assert(subscribers);
for (ks_hash_iterator_t *it = ks_hash_first(subscribers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
//if (excluded_nodeid && !ks_safe_strcasecmp(excluded_nodeid, (const char *)key)) continue;
//if (blade_routemgr_local_check(blade_handle_routemgr_get(bsmgr->handle), (const char *)key)) continue;
bs = blade_routemgr_route_lookup(blade_handle_routemgr_get(bsmgr->handle), (const char *)key);
if (bs) {
if (excluded_sessionid && !ks_safe_strcasecmp(excluded_sessionid, blade_session_id_get(bs))) continue;
if (!routers) ks_hash_create(&routers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
if (!ks_hash_search(routers, (void *)blade_session_id_get(bs), KS_UNLOCKED)) ks_hash_insert(routers, (void *)blade_session_id_get(bs), (void *)bs);
else blade_session_read_unlock(bs);
}
}
if (command == BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE) {
if (!channels) ks_hash_create(&channels, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_hash_insert(channels, (void *)channel, (void *)KS_TRUE);
}
}
ks_hash_read_unlock(bsmgr->subscriptions);
break;
case BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE:
bsub_key = ks_pstrdup(pool, protocol);
ks_hash_read_lock(bsmgr->subscriptions);
for (ks_hash_iterator_t *it = ks_hash_first(bsmgr->subscriptions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
bsub = (blade_subscription_t *)value;
if (ks_stristr(bsub_key, (const char *)key) == (const char *)key) {
ks_hash_t *subscribers = blade_subscription_subscribers_get(bsub);
ks_assert(subscribers);
for (ks_hash_iterator_t *it2 = ks_hash_first(subscribers, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
void *key2 = NULL;
void *value2 = NULL;
ks_hash_this(it2, (const void **)&key2, NULL, &value2);
//if (excluded_nodeid && !ks_safe_strcasecmp(excluded_nodeid, (const char *)key2)) continue;
//if (blade_routemgr_local_check(blade_handle_routemgr_get(bsmgr->handle), (const char *)key2)) continue;
bs = blade_routemgr_route_lookup(blade_handle_routemgr_get(bsmgr->handle), (const char *)key2);
if (bs) {
if (excluded_sessionid && !ks_safe_strcasecmp(excluded_sessionid, blade_session_id_get(bs))) continue;
if (!routers) ks_hash_create(&routers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
if (!ks_hash_search(routers, (void *)blade_session_id_get(bs), KS_UNLOCKED)) ks_hash_insert(routers, (void *)blade_session_id_get(bs), (void *)bs);
else blade_session_read_unlock(bs);
}
}
if (!channels) ks_hash_create(&channels, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_hash_insert(channels, (void *)blade_subscription_channel_get(bsub), (void *)KS_TRUE);
}
}
ks_hash_read_unlock(bsmgr->subscriptions);
break;
default: return KS_STATUS_ARG_INVALID;
}
bs = blade_sessionmgr_upstream_lookup(blade_handle_sessionmgr_get(bsmgr->handle));
if (bs) {
if (!excluded_sessionid || ks_safe_strcasecmp(excluded_sessionid, blade_session_id_get(bs))) {
if (!routers) ks_hash_create(&routers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
ks_hash_insert(routers, (void *)blade_session_id_get(bs), (void *)bs);
}
else blade_session_read_unlock(bs);
}
if (channels) {
for (ks_hash_iterator_t *it = ks_hash_first(channels, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
blade_subscriptionmgr_subscription_remove(bsmgr, protocol, (const char *)key);
}
ks_hash_destroy(&channels);
}
if (routers) {
for (ks_hash_iterator_t *it = ks_hash_first(routers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
void *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, &value);
bs = (blade_session_t *)value;
blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.broadcast");
cJSON_AddNumberToObject(req_params, "command", command);
cJSON_AddStringToObject(req_params, "protocol", protocol);
if (channel) cJSON_AddStringToObject(req_params, "channel", channel);
if (event) cJSON_AddStringToObject(req_params, "event", event);
if (params) cJSON_AddItemToObject(req_params, "params", cJSON_Duplicate(params, 1));
ks_log(KS_LOG_DEBUG, "Broadcasting: protocol %s, channel %s through %s\n", protocol, channel, blade_session_id_get(bs));
blade_session_send(bs, req, 0, callback, data);
cJSON_Delete(req);
blade_session_read_unlock(bs);
}
ks_hash_destroy(&routers);
}
ks_pool_free(&bsub_key);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,137 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_transport_s {
blade_handle_t *handle;
const char *name;
void *data;
blade_transport_callbacks_t *callbacks;
};
static void blade_transport_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_transport_t *bt = (blade_transport_t *)ptr;
//ks_assert(bt);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_transport_create(blade_transport_t **btP, blade_handle_t *bh, ks_pool_t *pool, const char *name, void *data, blade_transport_callbacks_t *callbacks)
{
blade_transport_t *bt = NULL;
ks_assert(btP);
ks_assert(bh);
ks_assert(pool);
ks_assert(name);
ks_assert(callbacks);
bt = ks_pool_alloc(pool, sizeof(blade_transport_t));
bt->handle = bh;
bt->name = ks_pstrdup(pool, name);
bt->data = data;
bt->callbacks = callbacks;
ks_pool_set_cleanup(bt, NULL, blade_transport_cleanup);
ks_log(KS_LOG_DEBUG, "Created transport %s\n", name);
*btP = bt;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_transport_destroy(blade_transport_t **btP)
{
blade_transport_t *bt = NULL;
ks_pool_t *pool = NULL;
ks_assert(btP);
ks_assert(*btP);
bt = *btP;
*btP = NULL;
pool = ks_pool_get(bt);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_transport_handle_get(blade_transport_t *bt)
{
ks_assert(bt);
return bt->handle;
}
KS_DECLARE(const char *) blade_transport_name_get(blade_transport_t *bt)
{
ks_assert(bt);
return bt->name;
}
KS_DECLARE(void *) blade_transport_data_get(blade_transport_t *bt)
{
ks_assert(bt);
return bt->data;
}
KS_DECLARE(blade_transport_callbacks_t *) blade_transport_callbacks_get(blade_transport_t *bt)
{
ks_assert(bt);
return bt->callbacks;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,233 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_transportmgr_s {
blade_handle_t *handle;
ks_hash_t *transports; // name, blade_transport_t*
blade_transport_t *default_transport; // default wss transport
};
static void blade_transportmgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_transportmgr_t *btmgr = (blade_transportmgr_t *)ptr;
ks_hash_iterator_t *it = NULL;
ks_assert(btmgr);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
while ((it = ks_hash_first(btmgr->transports, KS_UNLOCKED)) != NULL) {
void *key = NULL;
blade_transport_t *value = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
ks_hash_remove(btmgr->transports, key);
blade_transport_destroy(&value); // must call destroy to close the transport pool, using FREE_VALUE on the hash would attempt to free the transport from the wrong pool
}
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_transportmgr_create(blade_transportmgr_t **btmgrP, blade_handle_t *bh)
{
ks_pool_t *pool = NULL;
blade_transportmgr_t *btmgr = NULL;
ks_assert(btmgrP);
ks_pool_open(&pool);
ks_assert(pool);
btmgr = ks_pool_alloc(pool, sizeof(blade_transportmgr_t));
btmgr->handle = bh;
ks_hash_create(&btmgr->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(btmgr->transports);
ks_pool_set_cleanup(btmgr, NULL, blade_transportmgr_cleanup);
*btmgrP = btmgr;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_transportmgr_destroy(blade_transportmgr_t **btmgrP)
{
blade_transportmgr_t *btmgr = NULL;
ks_pool_t *pool;
ks_assert(btmgrP);
ks_assert(*btmgrP);
btmgr = *btmgrP;
*btmgrP = NULL;
pool = ks_pool_get(btmgr);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_transportmgr_startup(blade_transportmgr_t *btmgr, config_setting_t *config)
{
ks_assert(btmgr);
for (ks_hash_iterator_t *it = ks_hash_first(btmgr->transports, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_transport_t *value = NULL;
blade_transport_callbacks_t *callbacks = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
callbacks = blade_transport_callbacks_get(value);
ks_assert(callbacks);
if (callbacks->onstartup) callbacks->onstartup(value, config);
}
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_transportmgr_shutdown(blade_transportmgr_t *btmgr)
{
ks_assert(btmgr);
ks_hash_read_lock(btmgr->transports);
for (ks_hash_iterator_t *it = ks_hash_first(btmgr->transports, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
void *key = NULL;
blade_transport_t *value = NULL;
blade_transport_callbacks_t *callbacks = NULL;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
callbacks = blade_transport_callbacks_get(value);
ks_assert(callbacks);
if (callbacks->onshutdown) callbacks->onshutdown(value);
}
ks_hash_read_unlock(btmgr->transports);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_handle_t *) blade_transportmgr_handle_get(blade_transportmgr_t *btmgr)
{
ks_assert(btmgr);
return btmgr->handle;
}
KS_DECLARE(blade_transport_t *) blade_transportmgr_default_get(blade_transportmgr_t *btmgr)
{
ks_assert(btmgr);
return btmgr->default_transport;
}
KS_DECLARE(ks_status_t) blade_transportmgr_default_set(blade_transportmgr_t *btmgr, blade_transport_t *bt)
{
ks_assert(btmgr);
ks_assert(bt);
btmgr->default_transport = bt;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(blade_transport_t *) blade_transportmgr_transport_lookup(blade_transportmgr_t *btmgr, const char *name, ks_bool_t ordefault)
{
blade_transport_t *bt = NULL;
ks_assert(btmgr);
ks_hash_read_lock(btmgr->transports);
if (name && name[0]) bt = (blade_transport_t *)ks_hash_search(btmgr->transports, (void *)name, KS_UNLOCKED);
if (!bt && ordefault) bt = btmgr->default_transport;
// @todo if (bt) blade_transport_read_lock(bt);
ks_hash_read_unlock(btmgr->transports);
return bt;
}
KS_DECLARE(ks_status_t) blade_transportmgr_transport_add(blade_transportmgr_t *btmgr, blade_transport_t *bt)
{
char *key = NULL;
ks_assert(btmgr);
ks_assert(bt);
key = ks_pstrdup(ks_pool_get(btmgr), blade_transport_name_get(bt));
ks_hash_insert(btmgr->transports, (void *)key, (void *)bt);
ks_log(KS_LOG_DEBUG, "Transport Added: %s\n", key);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_transportmgr_transport_remove(blade_transportmgr_t *btmgr, blade_transport_t *bt)
{
const char *name = NULL;
ks_assert(btmgr);
ks_assert(bt);
name = blade_transport_name_get(bt);
ks_hash_remove(btmgr->transports, (void *)name);
ks_log(KS_LOG_DEBUG, "Transport Removed: %s\n", name);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,107 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_tuple_s {
void *value1;
void *value2;
};
static void blade_tuple_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//blade_tuple_t *bt = (blade_tuple_t *)ptr;
//ks_assert(bt);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_tuple_create(blade_tuple_t **btP, ks_pool_t *pool, void *value1, void *value2)
{
blade_tuple_t *bt = NULL;
ks_assert(btP);
ks_assert(pool);
bt = ks_pool_alloc(pool, sizeof(blade_tuple_t));
bt->value1 = value1;
bt->value2 = value2;
ks_pool_set_cleanup(bt, NULL, blade_tuple_cleanup);
*btP = bt;
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_tuple_destroy(blade_tuple_t **btP)
{
ks_assert(btP);
ks_assert(*btP);
ks_pool_free(btP);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(void *) blade_tuple_value1_get(blade_tuple_t *bt)
{
ks_assert(bt);
return bt->value1;
}
KS_DECLARE(void *) blade_tuple_value2_get(blade_tuple_t *bt)
{
ks_assert(bt);
return bt->value2;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,674 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "blade.h"
struct blade_webrequest_s {
const char *action;
const char *path;
ks_hash_t *query;
ks_hash_t *headers;
ks_sb_t *content;
};
struct blade_webresponse_s {
const char *status_code;
const char *status_message;
ks_hash_t *headers;
ks_sb_t *content;
};
static void blade_webrequest_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_webrequest_t *bwreq = (blade_webrequest_t *)ptr;
ks_assert(bwreq);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
static void blade_webresponse_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
blade_webresponse_t *bwres = (blade_webresponse_t *)ptr;
ks_assert(bwres);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
KS_DECLARE(ks_status_t) blade_webrequest_create(blade_webrequest_t **bwreqP, const char *action, const char *path)
{
ks_pool_t *pool = NULL;
blade_webrequest_t *bwreq = NULL;
ks_assert(bwreqP);
ks_assert(action);
ks_assert(path);
ks_pool_open(&pool);
ks_assert(pool);
bwreq = ks_pool_alloc(pool, sizeof(blade_webrequest_t));
bwreq->action = ks_pstrdup(pool, action);
bwreq->path = ks_pstrdup(pool, path);
ks_hash_create(&bwreq->query, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwreq->query);
ks_hash_create(&bwreq->headers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwreq->headers);
ks_sb_create(&bwreq->content, pool, 0);
ks_assert(bwreq->content);
ks_pool_set_cleanup(bwreq, NULL, blade_webrequest_cleanup);
*bwreqP = bwreq;
blade_webrequest_header_add(bwreq, "Content-Type", "application/x-www-form-urlencoded");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webrequest_load(blade_webrequest_t **bwreqP, struct mg_connection *conn)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
blade_webrequest_t *bwreq = NULL;
const struct mg_request_info *info = NULL;
char buf[1024];
int bytes = 0;
ks_assert(bwreqP);
ks_assert(conn);
info = mg_get_request_info(conn);
ks_pool_open(&pool);
ks_assert(pool);
bwreq = ks_pool_alloc(pool, sizeof(blade_webrequest_t));
bwreq->action = ks_pstrdup(pool, info->request_method);
bwreq->path = ks_pstrdup(pool, info->request_uri);
ks_hash_create(&bwreq->query, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwreq->query);
ks_hash_create(&bwreq->headers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwreq->headers);
ks_sb_create(&bwreq->content, pool, 0);
ks_assert(bwreq->content);
ks_pool_set_cleanup(bwreq, NULL, blade_webrequest_cleanup);
if (info->query_string && info->query_string[0]) {
char *query = ks_pstrdup(pool, info->query_string);
char *start = query;
char *end = NULL;
do {
char *key = start;
char *value = NULL;
end = strchr(start, '&');
if (end) *end = '\0';
value = strchr(start, '=');
if (value) {
*value = '\0';
value++;
if (*key && *value) {
ks_hash_insert(bwreq->query, (void *)ks_pstrdup(pool, key), (void *)ks_pstrdup(pool, value));
}
}
if (end) start = ++end;
else start = NULL;
} while (start);
ks_pool_free(&query);
}
for (int index = 0; index < info->num_headers; ++index) {
const struct mg_header *header = &info->http_headers[index];
ks_hash_insert(bwreq->headers, (void *)ks_pstrdup(pool, header->name), (void *)ks_pstrdup(pool, header->value));
}
while ((bytes = mg_read(conn, buf, sizeof(buf))) > 0) ks_sb_append_ex(bwreq->content, buf, bytes);
if (bytes < 0) {
blade_webrequest_destroy(&bwreq);
ret = KS_STATUS_FAIL;
}
else *bwreqP = bwreq;
return ret;
}
KS_DECLARE(ks_status_t) blade_webrequest_destroy(blade_webrequest_t **bwreqP)
{
blade_webrequest_t *bwreq = NULL;
ks_pool_t *pool;
ks_assert(bwreqP);
ks_assert(*bwreqP);
bwreq = *bwreqP;
*bwreqP = NULL;
pool = ks_pool_get(bwreq);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_webrequest_action_get(blade_webrequest_t *bwreq)
{
ks_assert(bwreq);
return bwreq->action;
}
KS_DECLARE(const char *) blade_webrequest_path_get(blade_webrequest_t *bwreq)
{
ks_assert(bwreq);
return bwreq->path;
}
KS_DECLARE(ks_status_t) blade_webrequest_query_add(blade_webrequest_t *bwreq, const char *name, const char *value)
{
ks_assert(bwreq);
ks_assert(name);
ks_assert(value);
ks_hash_insert(bwreq->query, (void *)ks_pstrdup(ks_pool_get(bwreq), name), (void *)ks_pstrdup(ks_pool_get(bwreq), value));
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_webrequest_query_get(blade_webrequest_t *bwreq, const char *name)
{
ks_assert(bwreq);
ks_assert(name);
return (const char *)ks_hash_search(bwreq->query, (void *)name, KS_UNLOCKED);
}
KS_DECLARE(ks_status_t) blade_webrequest_header_add(blade_webrequest_t *bwreq, const char *header, const char *value)
{
ks_assert(bwreq);
ks_assert(header);
ks_assert(value);
ks_hash_insert(bwreq->headers, (void *)ks_pstrdup(ks_pool_get(bwreq), header), (void *)ks_pstrdup(ks_pool_get(bwreq), value));
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webrequest_header_printf(blade_webrequest_t *bwreq, const char *header, const char *fmt, ...)
{
va_list ap;
char *result = NULL;
ks_assert(bwreq);
ks_assert(header);
ks_assert(fmt);
va_start(ap, fmt);
result = ks_vpprintf(ks_pool_get(bwreq), fmt, ap);
va_end(ap);
ks_hash_insert(bwreq->headers, (void *)ks_pstrdup(ks_pool_get(bwreq), header), (void *)result);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_webrequest_header_get(blade_webrequest_t *bwreq, const char *header)
{
ks_assert(bwreq);
ks_assert(header);
return (const char *)ks_hash_search(bwreq->headers, (void *)header, KS_UNLOCKED);
}
KS_DECLARE(ks_status_t) blade_webrequest_content_json_append(blade_webrequest_t *bwreq, cJSON *json)
{
ks_assert(bwreq);
ks_assert(json);
blade_webrequest_header_add(bwreq, "Content-Type", "application/json");
ks_sb_json(bwreq->content, json);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webrequest_content_string_append(blade_webrequest_t *bwreq, const char *str)
{
ks_assert(bwreq);
ks_assert(str);
ks_sb_append(bwreq->content, str);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webrequest_send(blade_webrequest_t *bwreq, ks_bool_t secure, const char *host, ks_port_t port, blade_webresponse_t **bwresP)
{
ks_status_t ret = KS_STATUS_SUCCESS;
char buf[1024];
struct mg_connection *conn = NULL;
const char *path = NULL;
ks_sb_t *pathAndQuery = NULL;
ks_assert(bwreq);
ks_assert(host);
ks_assert(bwresP);
if (port == 0) port = secure ? 443 : 80;
conn = mg_connect_client(host, port, secure, buf, sizeof(buf));
if (!conn) {
ret = KS_STATUS_FAIL;
goto done;
}
path = bwreq->path;
if (ks_hash_count(bwreq->query) > 0) {
ks_bool_t firstQuery = KS_TRUE;
ks_sb_create(&pathAndQuery, NULL, 0);
ks_sb_append(pathAndQuery, bwreq->path);
for (ks_hash_iterator_t *it = ks_hash_first(bwreq->query, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key;
const char *value;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
// @todo make sure key and value are URL encoded
mg_url_encode(key, buf, sizeof(buf));
ks_sb_printf(pathAndQuery, "%c%s=", firstQuery ? '?' : '&', buf);
mg_url_encode(value, buf, sizeof(buf));
ks_sb_append(pathAndQuery, buf);
firstQuery = KS_FALSE;
}
path = ks_sb_cstr(pathAndQuery);
}
mg_printf(conn,
"%s %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Length: %lu\r\n",
bwreq->action,
path,
host,
ks_sb_length(bwreq->content));
if (pathAndQuery) ks_sb_destroy(&pathAndQuery);
for (ks_hash_iterator_t *it = ks_hash_first(bwreq->headers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key;
const char *value;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
mg_printf(conn, "%s: %s\r\n", key, value);
}
mg_write(conn, "\r\n", 2);
mg_write(conn, ks_sb_cstr(bwreq->content), ks_sb_length(bwreq->content));
if (mg_get_response(conn, buf, sizeof(buf), 1000) <= 0) {
ret = KS_STATUS_FAIL;
goto done;
}
ret = blade_webresponse_load(bwresP, conn);
done:
if (conn) mg_close_connection(conn);
return ret;
}
KS_DECLARE(ks_status_t) blade_webrequest_oauth2_token_by_credentials_send(ks_bool_t secure, const char *host, ks_port_t port, const char *path, const char *client_id, const char *client_secret, const char **token)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_webrequest_t *bwreq = NULL;
blade_webresponse_t *bwres = NULL;
cJSON *json = NULL;
char *auth = NULL;
char encoded[1024];
ks_pool_t *pool = NULL;
const char *tok = NULL;
ks_assert(host);
ks_assert(path);
ks_assert(client_id);
ks_assert(client_secret);
ks_assert(token);
blade_webrequest_create(&bwreq, "POST", path);
auth = ks_psprintf(ks_pool_get(bwreq), "%s:%s", client_id, client_secret);
ks_b64_encode((unsigned char *)auth, strlen(auth), (unsigned char *)encoded, sizeof(encoded));
ks_pool_free(&auth);
blade_webrequest_header_printf(bwreq, "Authorization", "Basic %s", encoded);
json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "grant_type", "client_credentials");
blade_webrequest_content_json_append(bwreq, json);
cJSON_Delete(json);
if ((ret = blade_webrequest_send(bwreq, secure, host, port, &bwres)) != KS_STATUS_SUCCESS) goto done;
if ((ret = blade_webresponse_content_json_get(bwres, &json)) != KS_STATUS_SUCCESS) goto done;
if ((tok = cJSON_GetObjectCstr(json, "access_token")) == NULL) {
ret = KS_STATUS_FAIL;
goto done;
}
ks_pool_open(&pool);
*token = ks_pstrdup(pool, tok);
done:
if (json) cJSON_Delete(json);
blade_webrequest_destroy(&bwreq);
if (bwres) blade_webresponse_destroy(&bwres);
return ret;
}
KS_DECLARE(ks_status_t) blade_webrequest_oauth2_token_by_code_send(ks_bool_t secure, const char *host, ks_port_t port, const char *path, const char *client_id, const char *client_secret, const char *code, const char **token)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_webrequest_t *bwreq = NULL;
blade_webresponse_t *bwres = NULL;
cJSON *json = NULL;
char *auth = NULL;
char encoded[1024];
ks_pool_t *pool = NULL;
const char *tok = NULL;
ks_assert(host);
ks_assert(path);
ks_assert(client_id);
ks_assert(client_secret);
ks_assert(code);
ks_assert(token);
blade_webrequest_create(&bwreq, "POST", path);
auth = ks_psprintf(ks_pool_get(bwreq), "%s:%s", client_id, client_secret);
ks_b64_encode((unsigned char *)auth, strlen(auth), (unsigned char *)encoded, sizeof(encoded));
ks_pool_free(&auth);
blade_webrequest_header_printf(bwreq, "Authorization", "Basic %s", encoded);
json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "grant_type", "authorization_code");
cJSON_AddStringToObject(json, "code", code);
blade_webrequest_content_json_append(bwreq, json);
cJSON_Delete(json);
if ((ret = blade_webrequest_send(bwreq, secure, host, port, &bwres)) != KS_STATUS_SUCCESS) goto done;
if ((ret = blade_webresponse_content_json_get(bwres, &json)) != KS_STATUS_SUCCESS) goto done;
if ((tok = cJSON_GetObjectCstr(json, "access_token")) == NULL) {
ret = KS_STATUS_FAIL;
goto done;
}
ks_pool_open(&pool);
*token = ks_pstrdup(pool, tok);
done:
if (json) cJSON_Delete(json);
blade_webrequest_destroy(&bwreq);
if (bwres) blade_webresponse_destroy(&bwres);
return ret;
}
KS_DECLARE(ks_status_t) blade_webresponse_create(blade_webresponse_t **bwresP, const char *status)
{
ks_pool_t *pool = NULL;
blade_webresponse_t *bwres = NULL;
ks_assert(bwresP);
ks_assert(status);
ks_pool_open(&pool);
ks_assert(pool);
bwres = ks_pool_alloc(pool, sizeof(blade_webresponse_t));
bwres->status_code = ks_pstrdup(pool, status);
bwres->status_message = ks_pstrdup(pool, mg_get_response_code_text(NULL, atoi(status)));
ks_hash_create(&bwres->headers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwres->headers);
ks_sb_create(&bwres->content, pool, 0);
ks_assert(bwres->content);
ks_pool_set_cleanup(bwres, NULL, blade_webresponse_cleanup);
*bwresP = bwres;
blade_webresponse_header_add(bwres, "Content-Type", "application/x-www-form-urlencoded");
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webresponse_load(blade_webresponse_t **bwresP, struct mg_connection *conn)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
blade_webresponse_t *bwres = NULL;
const struct mg_request_info *info = NULL;
char buf[1024];
int bytes = 0;
ks_assert(bwresP);
ks_assert(conn);
info = mg_get_request_info(conn);
ks_pool_open(&pool);
ks_assert(pool);
bwres = ks_pool_alloc(pool, sizeof(blade_webrequest_t));
bwres->status_code = ks_pstrdup(pool, info->request_uri);
bwres->status_message = ks_pstrdup(pool, info->http_version);
ks_hash_create(&bwres->headers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(bwres->headers);
ks_sb_create(&bwres->content, pool, 0);
ks_assert(bwres->content);
ks_pool_set_cleanup(bwres, NULL, blade_webresponse_cleanup);
for (int index = 0; index < info->num_headers; ++index) {
const struct mg_header *header = &info->http_headers[index];
ks_hash_insert(bwres->headers, (void *)ks_pstrdup(pool, header->name), (void *)ks_pstrdup(pool, header->value));
}
while ((bytes = mg_read(conn, buf, sizeof(buf))) > 0) ks_sb_append_ex(bwres->content, buf, bytes);
if (bytes < 0) {
blade_webresponse_destroy(&bwres);
ret = KS_STATUS_FAIL;
}
else *bwresP = bwres;
return ret;
}
KS_DECLARE(ks_status_t) blade_webresponse_destroy(blade_webresponse_t **bwresP)
{
blade_webresponse_t *bwres = NULL;
ks_pool_t *pool;
ks_assert(bwresP);
ks_assert(*bwresP);
bwres = *bwresP;
*bwresP = NULL;
pool = ks_pool_get(bwres);
ks_pool_close(&pool);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webresponse_header_add(blade_webresponse_t *bwres, const char *header, const char *value)
{
ks_assert(bwres);
ks_assert(header);
ks_assert(value);
ks_hash_insert(bwres->headers, (void *)ks_pstrdup(ks_pool_get(bwres), header), (void *)ks_pstrdup(ks_pool_get(bwres), value));
return KS_STATUS_SUCCESS;
}
KS_DECLARE(const char *) blade_webresponse_header_get(blade_webresponse_t *bwres, const char *header)
{
ks_assert(bwres);
ks_assert(header);
return (const char *)ks_hash_search(bwres->headers, (void *)header, KS_UNLOCKED);
}
KS_DECLARE(ks_status_t) blade_webresponse_content_json_append(blade_webresponse_t *bwres, cJSON *json)
{
ks_assert(bwres);
ks_assert(json);
blade_webresponse_header_add(bwres, "Content-Type", "application/json");
ks_sb_json(bwres->content, json);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webresponse_content_string_append(blade_webresponse_t *bwres, const char *str)
{
ks_assert(bwres);
ks_assert(str);
ks_sb_append(bwres->content, str);
return KS_STATUS_SUCCESS;
}
KS_DECLARE(ks_status_t) blade_webresponse_content_json_get(blade_webresponse_t *bwres, cJSON **json)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bwres);
ks_assert(json);
if (!(*json = cJSON_Parse(ks_sb_cstr(bwres->content)))) ret = KS_STATUS_FAIL;
return ret;
}
KS_DECLARE(ks_status_t) blade_webresponse_send(blade_webresponse_t *bwres, struct mg_connection *conn)
{
ks_assert(bwres);
ks_assert(conn);
mg_printf(conn,
"HTTP/1.1 %s %s\r\n"
"Content-Length: %lu\r\n"
"Connection: close\r\n",
bwres->status_code,
bwres->status_message,
ks_sb_length(bwres->content));
for (ks_hash_iterator_t *it = ks_hash_first(bwres->headers, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key;
const char *value;
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
mg_printf(conn, "%s: %s\r\n", key, value);
}
mg_write(conn, "\r\n", 2);
mg_write(conn, ks_sb_cstr(bwres->content), ks_sb_length(bwres->content));
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
KS_DECLARE(ks_status_t) ks_dht_datagram_create(ks_dht_datagram_t **datagram,
ks_pool_t *pool,
ks_dht_t *dht,
ks_dht_endpoint_t *endpoint,
const ks_sockaddr_t *raddr)
{
ks_dht_datagram_t *dg;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(datagram);
ks_assert(pool);
ks_assert(dht);
ks_assert(endpoint);
ks_assert(raddr);
ks_assert(raddr->family == AF_INET || raddr->family == AF_INET6);
*datagram = dg = ks_pool_alloc(pool, sizeof(ks_dht_datagram_t));
ks_assert(dg);
dg->pool = pool;
dg->dht = dht;
dg->endpoint = endpoint;
dg->raddr = *raddr;
memcpy(dg->buffer, dht->recv_buffer, dht->recv_buffer_length);
dg->buffer_length = dht->recv_buffer_length;
// done:
if (ret != KS_STATUS_SUCCESS) {
ks_dht_datagram_destroy(datagram);
}
return ret;
}
KS_DECLARE(void) ks_dht_datagram_destroy(ks_dht_datagram_t **datagram)
{
ks_dht_datagram_t *dg;
ks_assert(datagram);
ks_assert(*datagram);
dg = *datagram;
ks_pool_free(dg->pool, datagram);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,65 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
KS_DECLARE(ks_status_t) ks_dht_distribute_create(ks_dht_distribute_t **distribute,
ks_pool_t *pool,
ks_dht_storageitem_callback_t callback,
void *data,
int64_t cas,
ks_dht_storageitem_t *item)
{
ks_dht_distribute_t *d;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(distribute);
ks_assert(pool);
ks_assert(cas >= 0);
ks_assert(item);
*distribute = d = ks_pool_alloc(pool, sizeof(ks_dht_distribute_t));
ks_assert(d);
d->pool = pool;
d->callback = callback;
d->data = data;
ks_mutex_create(&d->mutex, KS_MUTEX_FLAG_DEFAULT, d->pool);
ks_assert(d->mutex);
d->cas = cas;
d->item = item;
ks_dht_storageitem_reference(d->item);
// done:
if (ret != KS_STATUS_SUCCESS) {
if (d) ks_dht_distribute_destroy(distribute);
}
return ret;
}
KS_DECLARE(void) ks_dht_distribute_destroy(ks_dht_distribute_t **distribute)
{
ks_dht_distribute_t *d;
ks_assert(distribute);
ks_assert(*distribute);
d = *distribute;
if (d->mutex) ks_mutex_destroy(&d->mutex);
ks_dht_storageitem_dereference(d->item);
ks_pool_free(d->pool, distribute);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,61 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_endpoint_create(ks_dht_endpoint_t **endpoint,
ks_pool_t *pool,
const ks_sockaddr_t *addr,
ks_socket_t sock)
{
ks_dht_endpoint_t *ep;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(endpoint);
ks_assert(pool);
ks_assert(addr);
ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
*endpoint = ep = ks_pool_alloc(pool, sizeof(ks_dht_endpoint_t));
ks_assert(ep);
ep->pool = pool;
ep->addr = *addr;
ep->sock = sock;
// done:
if (ret != KS_STATUS_SUCCESS) {
if (ep) ks_dht_endpoint_destroy(endpoint);
}
return ret;
}
/**
*
*/
KS_DECLARE(void) ks_dht_endpoint_destroy(ks_dht_endpoint_t **endpoint)
{
ks_dht_endpoint_t *ep;
ks_assert(endpoint);
ks_assert(*endpoint);
ep = *endpoint;
if (ep->sock != KS_SOCK_INVALID) ks_socket_close(&ep->sock);
ks_pool_free(ep->pool, endpoint);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,136 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
KS_DECLARE(ks_status_t) ks_dht_job_create(ks_dht_job_t **job,
ks_pool_t *pool,
const ks_sockaddr_t *raddr,
int32_t attempts,
void *data)
{
ks_dht_job_t *j;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(job);
ks_assert(pool);
//ks_assert(dht);
ks_assert(attempts > 0 && attempts <= 10);
*job = j = ks_pool_alloc(pool, sizeof(ks_dht_job_t));
ks_assert(j);
j->pool = pool;
j->state = KS_DHT_JOB_STATE_QUERYING;
if (raddr) j->raddr = *raddr;
j->attempts = attempts;
j->data = data;
// done:
if (ret != KS_STATUS_SUCCESS) {
if (j) ks_dht_job_destroy(job);
}
return ret;
}
KS_DECLARE(void) ks_dht_job_build_ping(ks_dht_job_t *job, ks_dht_job_callback_t query_callback, ks_dht_job_callback_t finish_callback)
{
ks_assert(job);
ks_assert(query_callback);
job->query_callback = query_callback;
job->finish_callback = finish_callback;
}
KS_DECLARE(void) ks_dht_job_build_findnode(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_nodeid_t *target)
{
ks_assert(job);
ks_assert(query_callback);
ks_assert(target);
job->query_callback = query_callback;
job->finish_callback = finish_callback;
job->query_target = *target;
}
KS_DECLARE(void) ks_dht_job_build_get(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_nodeid_t *target,
const uint8_t *salt,
ks_size_t salt_length)
{
ks_assert(job);
ks_assert(query_callback);
ks_assert(target);
job->query_callback = query_callback;
job->finish_callback = finish_callback;
job->query_target = *target;
if (salt && salt_length > 0) job->query_salt = ben_blob(salt, salt_length);
}
KS_DECLARE(void) ks_dht_job_build_put(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_token_t *token,
int64_t cas,
ks_dht_storageitem_t *item)
{
ks_assert(job);
ks_assert(query_callback);
ks_assert(token);
ks_assert(item);
job->query_callback = query_callback;
job->finish_callback = finish_callback;
job->query_token = *token;
job->query_cas = cas;
job->query_storageitem = item;
ks_dht_storageitem_reference(job->query_storageitem);
}
KS_DECLARE(void) ks_dht_job_build_search(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback)
{
ks_assert(job);
ks_assert(query_callback);
job->query_callback = query_callback;
job->finish_callback = finish_callback;
}
KS_DECLARE(void) ks_dht_job_destroy(ks_dht_job_t **job)
{
ks_dht_job_t *j;
ks_assert(job);
ks_assert(*job);
j = *job;
if (j->query_salt) ben_free(j->query_salt);
if (j->response_id) ks_dhtrt_release_node(j->response_id);
for (int32_t i = 0; i < j->response_nodes_count; ++i) ks_dhtrt_release_node(j->response_nodes[i]);
for (int32_t i = 0; i < j->response_nodes6_count; ++i) ks_dhtrt_release_node(j->response_nodes6[i]);
if (j->query_storageitem) ks_dht_storageitem_dereference(j->query_storageitem);
if (j->response_storageitem) ks_dht_storageitem_dereference(j->response_storageitem);
if (j->error_description) ben_free(j->error_description);
ks_pool_free(j->pool, job);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,122 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
KS_DECLARE(ks_status_t) ks_dht_message_create(ks_dht_message_t **message,
ks_pool_t *pool,
ks_dht_endpoint_t *endpoint,
const ks_sockaddr_t *raddr,
ks_bool_t alloc_data)
{
ks_dht_message_t *m;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(message);
ks_assert(pool);
*message = m = ks_pool_alloc(pool, sizeof(ks_dht_message_t));
ks_assert(m);
m->pool = pool;
m->endpoint = endpoint;
m->raddr = *raddr;
if (alloc_data) {
m->data = ben_dict();
ks_assert(m->data);
}
// done:
if (ret != KS_STATUS_SUCCESS) {
ks_dht_message_destroy(message);
}
return ret;
}
KS_DECLARE(void) ks_dht_message_destroy(ks_dht_message_t **message)
{
ks_dht_message_t *m;
ks_assert(message);
ks_assert(*message);
m = *message;
if (m->data) {
ben_free(m->data);
m->data = NULL;
}
ks_pool_free(m->pool, message);
}
KS_DECLARE(ks_status_t) ks_dht_message_parse(ks_dht_message_t *message, const uint8_t *buffer, ks_size_t buffer_length)
{
struct bencode *t;
struct bencode *y;
const char *tv;
const char *yv;
ks_size_t tv_len;
ks_size_t yv_len;
ks_assert(message);
ks_assert(message->pool);
ks_assert(buffer);
ks_assert(!message->data);
message->data = ben_decode((const void *)buffer, buffer_length);
if (!message->data) {
ks_log(KS_LOG_DEBUG, "Message cannot be decoded\n");
return KS_STATUS_FAIL;
}
ks_log(KS_LOG_DEBUG, "Message decoded\n");
ks_log(KS_LOG_DEBUG, "%s\n", ben_print(message->data));
t = ben_dict_get_by_str(message->data, "t");
if (!t) {
ks_log(KS_LOG_DEBUG, "Message missing required key 't'\n");
return KS_STATUS_FAIL;
}
tv = ben_str_val(t);
tv_len = ben_str_len(t);
if (tv_len > KS_DHT_MESSAGE_TRANSACTIONID_MAX_SIZE) {
ks_log(KS_LOG_DEBUG, "Message 't' value has an unexpectedly large size of %d\n", tv_len);
return KS_STATUS_FAIL;
}
memcpy(message->transactionid, tv, tv_len);
message->transactionid_length = tv_len;
// @todo hex output of transactionid
//ks_log(KS_LOG_DEBUG, "Message transaction id is %d\n", message->transactionid);
y = ben_dict_get_by_str(message->data, "y");
if (!y) {
ks_log(KS_LOG_DEBUG, "Message missing required key 'y'\n");
return KS_STATUS_FAIL;
}
yv = ben_str_val(y);
yv_len = ben_str_len(y);
if (yv_len >= KS_DHT_MESSAGE_TYPE_MAX_SIZE) {
ks_log(KS_LOG_DEBUG, "Message 'y' value has an unexpectedly large size of %d\n", yv_len);
return KS_STATUS_FAIL;
}
memcpy(message->type, yv, yv_len);
message->type[yv_len] = '\0';
//ks_log(KS_LOG_DEBUG, "Message type is '%s'\n", message->type);
return KS_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,62 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
KS_DECLARE(ks_status_t) ks_dht_publish_create(ks_dht_publish_t **publish,
ks_pool_t *pool,
ks_dht_job_callback_t callback,
void *data,
int64_t cas,
ks_dht_storageitem_t *item)
{
ks_dht_publish_t *p;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(publish);
ks_assert(pool);
ks_assert(cas >= 0);
ks_assert(item);
*publish = p = ks_pool_alloc(pool, sizeof(ks_dht_publish_t));
ks_assert(p);
p->pool = pool;
p->callback = callback;
p->data = data;
p->cas = cas;
p->item = item;
ks_dht_storageitem_reference(p->item);
// done:
if (ret != KS_STATUS_SUCCESS) {
if (p) ks_dht_publish_destroy(publish);
}
return ret;
}
KS_DECLARE(void) ks_dht_publish_destroy(ks_dht_publish_t **publish)
{
ks_dht_publish_t *p;
ks_assert(publish);
ks_assert(*publish);
p = *publish;
ks_dht_storageitem_dereference(p->item);
ks_pool_free(p->pool, publish);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,71 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
KS_DECLARE(ks_status_t) ks_dht_search_create(ks_dht_search_t **search,
ks_pool_t *pool,
ks_dhtrt_routetable_t *table,
const ks_dht_nodeid_t *target,
ks_dht_job_callback_t callback,
void *data)
{
ks_dht_search_t *s;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(search);
ks_assert(pool);
ks_assert(table);
ks_assert(target);
*search = s = ks_pool_alloc(pool, sizeof(ks_dht_search_t));
ks_assert(s);
s->pool = pool;
ks_mutex_create(&s->mutex, KS_MUTEX_FLAG_DEFAULT, s->pool);
ks_assert(s->mutex);
s->table = table;
memcpy(s->target.id, target->id, KS_DHT_NODEID_SIZE);
s->callback = callback;
s->data = data;
ks_hash_create(&s->searched, KS_HASH_MODE_ARBITRARY, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, s->pool);
ks_assert(s->searched);
ks_hash_set_keysize(s->searched, KS_DHT_NODEID_SIZE);
s->searching = 0;
// done:
if (ret != KS_STATUS_SUCCESS) {
if (s) ks_dht_search_destroy(search);
}
return ret;
}
KS_DECLARE(void) ks_dht_search_destroy(ks_dht_search_t **search)
{
ks_dht_search_t *s;
ks_assert(search);
ks_assert(*search);
s = *search;
if (s->searched) ks_hash_destroy(&s->searched);
if (s->mutex) ks_mutex_destroy(&s->mutex);
ks_pool_free(s->pool, search);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,214 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
#include "sodium.h"
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable_internal(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
struct bencode *v,
ks_bool_t clone_v)
{
ks_dht_storageitem_t *si;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(item);
ks_assert(pool);
ks_assert(v);
ks_assert(SHA_DIGEST_LENGTH == KS_DHT_NODEID_SIZE);
*item = si = ks_pool_alloc(pool, sizeof(ks_dht_storageitem_t));
ks_assert(si);
si->pool = pool;
si->id = *target;
si->mutable = KS_FALSE;
si->expiration = ks_time_now() + ((ks_time_t)KS_DHT_STORAGEITEM_EXPIRATION * KS_USEC_PER_SEC);
si->keepalive = ks_time_now() + ((ks_time_t)KS_DHT_STORAGEITEM_KEEPALIVE * KS_USEC_PER_SEC);
si->v = clone_v ? ben_clone(v) : v;
ks_assert(si->v);
si->refc = 1;
// done:
if (ret != KS_STATUS_SUCCESS) {
if (si) ks_dht_storageitem_destroy(item);
}
return ret;
}
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
const uint8_t *value,
ks_size_t value_length)
{
struct bencode *v = NULL;
ks_assert(item);
ks_assert(pool);
ks_assert(value);
ks_assert(value_length > 0);
ks_assert(SHA_DIGEST_LENGTH == KS_DHT_NODEID_SIZE);
v = ben_blob(value, value_length);
ks_assert(v);
return ks_dht_storageitem_create_immutable_internal(item, pool, target, v, KS_FALSE);
}
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable_internal(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
struct bencode *v,
ks_bool_t clone_v,
ks_dht_storageitem_pkey_t *pk,
struct bencode *salt,
ks_bool_t clone_salt,
int64_t sequence,
ks_dht_storageitem_signature_t *signature)
{
ks_dht_storageitem_t *si;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(item);
ks_assert(pool);
ks_assert(v);
ks_assert(SHA_DIGEST_LENGTH == KS_DHT_NODEID_SIZE);
ks_assert(pk);
ks_assert(signature);
*item = si = ks_pool_alloc(pool, sizeof(ks_dht_storageitem_t));
ks_assert(si);
si->pool = pool;
si->id = *target;
si->mutable = KS_TRUE;
si->expiration = ks_time_now() + ((ks_time_t)KS_DHT_STORAGEITEM_EXPIRATION * KS_USEC_PER_SEC);
si->keepalive = ks_time_now() + ((ks_time_t)KS_DHT_STORAGEITEM_KEEPALIVE * KS_USEC_PER_SEC);
si->v = clone_v ? ben_clone(v) : v;
ks_assert(si->v);
si->refc = 1;
ks_mutex_create(&si->mutex, KS_MUTEX_FLAG_DEFAULT, si->pool);
ks_assert(si->mutex);
si->pk = *pk;
if (salt) {
si->salt = clone_salt ? ben_clone(salt) : salt;
ks_assert(si->salt);
}
si->seq = sequence;
si->sig = *signature;
// done:
if (ret != KS_STATUS_SUCCESS) {
if (si) ks_dht_storageitem_destroy(item);
}
return ret;
}
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
const uint8_t *value,
ks_size_t value_length,
ks_dht_storageitem_pkey_t *pk,
const uint8_t *salt,
ks_size_t salt_length,
int64_t sequence,
ks_dht_storageitem_signature_t *signature)
{
struct bencode *v = NULL;
struct bencode *s = NULL;
ks_assert(item);
ks_assert(pool);
ks_assert(value);
ks_assert(value_length > 0);
ks_assert(SHA_DIGEST_LENGTH == KS_DHT_NODEID_SIZE);
ks_assert(pk);
ks_assert(signature);
v = ben_blob(value, value_length);
if (salt && salt_length > 0) s = ben_blob(salt, salt_length);
return ks_dht_storageitem_create_mutable_internal(item, pool, target, v, KS_FALSE, pk, s, KS_FALSE, sequence, signature);
}
KS_DECLARE(void) ks_dht_storageitem_update_mutable(ks_dht_storageitem_t *item, struct bencode *v, int64_t sequence, ks_dht_storageitem_signature_t *signature)
{
ks_assert(item);
ks_assert(v);
ks_assert(sequence);
ks_assert(signature);
ks_mutex_lock(item->mutex);
ben_free(item->v);
item->v = ben_clone(v);
item->seq = sequence;
item->sig = *signature;
ks_mutex_unlock(item->mutex);
}
/**
*
*/
KS_DECLARE(void) ks_dht_storageitem_destroy(ks_dht_storageitem_t **item)
{
ks_dht_storageitem_t *si;
ks_assert(item);
ks_assert(*item);
si = *item;
if (si->v) {
ben_free(si->v);
si->v = NULL;
}
if (si->mutex) ks_mutex_destroy(&si->mutex);
if (si->salt) {
ben_free(si->salt);
si->salt = NULL;
}
ks_pool_free(si->pool, item);
}
KS_DECLARE(void) ks_dht_storageitem_reference(ks_dht_storageitem_t *item)
{
ks_assert(item);
ks_mutex_lock(item->mutex);
item->refc++;
ks_mutex_unlock(item->mutex);
}
KS_DECLARE(void) ks_dht_storageitem_dereference(ks_dht_storageitem_t *item)
{
ks_assert(item);
ks_mutex_lock(item->mutex);
item->refc--;
ks_mutex_unlock(item->mutex);
ks_assert(item->refc >= 0);
}
KS_DECLARE(void) ks_dht_storageitem_callback(ks_dht_storageitem_t *item, ks_dht_storageitem_callback_t callback)
{
ks_assert(item);
item->callback = callback;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,54 +0,0 @@
#include "ks_dht.h"
#include "ks_dht-int.h"
KS_DECLARE(ks_status_t) ks_dht_transaction_create(ks_dht_transaction_t **transaction,
ks_pool_t *pool,
ks_dht_job_t *job,
uint32_t transactionid,
ks_dht_job_callback_t callback)
{
ks_dht_transaction_t *t;
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(transaction);
ks_assert(pool);
ks_assert(job);
*transaction = t = ks_pool_alloc(pool, sizeof(ks_dht_transaction_t));
ks_assert(t);
t->pool = pool;
t->job = job;
t->transactionid = transactionid;
t->callback = callback;
t->expiration = ks_time_now() + ((ks_time_t)KS_DHT_TRANSACTION_EXPIRATION * KS_USEC_PER_SEC);
// done:
if (ret != KS_STATUS_SUCCESS) {
if (t) ks_dht_transaction_destroy(transaction);
}
return ret;
}
KS_DECLARE(void) ks_dht_transaction_destroy(ks_dht_transaction_t **transaction)
{
ks_dht_transaction_t *t;
ks_assert(transaction);
ks_assert(*transaction);
t = *transaction;
ks_pool_free(t->pool, transaction);
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,90 +0,0 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_H_
#define _BLADE_H_
#include <ks.h>
#include <sodium.h>
#include <libconfig.h>
#include <civetweb.h>
#include <pcre.h>
#include "unqlite.h"
#include "blade_types.h"
#include "blade_stack.h"
#include "blade_identity.h"
#include "blade_transport.h"
#include "blade_rpc.h"
#include "blade_connection.h"
#include "blade_session.h"
#include "blade_protocol.h"
#include "blade_channel.h"
#include "blade_subscription.h"
#include "blade_tuple.h"
#include "blade_web.h"
#include "blade_transportmgr.h"
#include "blade_rpcmgr.h"
#include "blade_routemgr.h"
#include "blade_subscriptionmgr.h"
#include "blade_mastermgr.h"
#include "blade_connectionmgr.h"
#include "blade_sessionmgr.h"
#include "blade_restmgr.h"
#include "blade_transport_wss.h"
KS_BEGIN_EXTERN_C
// legacy for libconfig pre 1.5.0
#if (LIBCONFIG_VER_MAJOR <= 1) && (LIBCONFIG_VER_MINOR <= 4)
#define config_setting_lookup config_lookup_from
#endif
KS_DECLARE(ks_status_t) blade_init(void);
KS_DECLARE(ks_status_t) blade_shutdown(void);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_CHANNEL_H_
#define _BLADE_CHANNEL_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name, blade_channel_flags_t flags);
KS_DECLARE(ks_status_t) blade_channel_destroy(blade_channel_t **bcP);
KS_DECLARE(const char *) blade_channel_name_get(blade_channel_t *bc);
KS_DECLARE(blade_channel_flags_t) blade_channel_flags_get(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_read_lock(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_read_unlock(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_write_lock(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_write_unlock(blade_channel_t *bc);
KS_DECLARE(ks_bool_t) blade_channel_authorization_verify(blade_channel_t *bc, const char *target);
KS_DECLARE(ks_status_t) blade_channel_authorization_add(blade_channel_t *bc, const char *target);
KS_DECLARE(ks_bool_t) blade_channel_authorization_remove(blade_channel_t *bc, const char *target);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_CONNECTION_H_
#define _BLADE_CONNECTION_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP);
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc, blade_connection_direction_t direction);
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc);
KS_DECLARE(blade_handle_t *) blade_connection_handle_get(blade_connection_t *bc);
KS_DECLARE(const char *) blade_connection_id_get(blade_connection_t *bc);
KS_DECLARE(ks_status_t) blade_connection_read_lock(blade_connection_t *bc, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_connection_read_unlock(blade_connection_t *bc);
KS_DECLARE(ks_status_t) blade_connection_write_lock(blade_connection_t *bc, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_connection_write_unlock(blade_connection_t *bc);
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc);
KS_DECLARE(void) blade_connection_transport_set(blade_connection_t *bc, void *transport_data, blade_transport_callbacks_t *transport_callbacks);
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state);
KS_DECLARE(blade_connection_state_t) blade_connection_state_get(blade_connection_t *bc);
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc);
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, cJSON *json);
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, cJSON **json);
KS_DECLARE(const char *) blade_connection_session_get(blade_connection_t *bc);
KS_DECLARE(void) blade_connection_session_set(blade_connection_t *bc, const char *id);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_CONNECTIONMGR_H_
#define _BLADE_CONNECTIONMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_connectionmgr_create(blade_connectionmgr_t **bcmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_connectionmgr_destroy(blade_connectionmgr_t **bcmgrP);
KS_DECLARE(blade_handle_t *) blade_connectionmgr_handle_get(blade_connectionmgr_t *bcmgr);
KS_DECLARE(ks_status_t) blade_connectionmgr_shutdown(blade_connectionmgr_t *bcmgr);
KS_DECLARE(blade_connection_t *) blade_connectionmgr_connection_lookup(blade_connectionmgr_t *bcmgr, const char *id);
KS_DECLARE(ks_status_t) blade_connectionmgr_connection_add(blade_connectionmgr_t *bcmgr, blade_connection_t *bc);
KS_DECLARE(ks_status_t) blade_connectionmgr_connection_remove(blade_connectionmgr_t *bcmgr, blade_connection_t *bc);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_IDENTITY_H_
#define _BLADE_IDENTITY_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool);
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP);
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri);
KS_DECLARE(const char *) blade_identity_uri_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_scheme_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_user_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_host_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_port_get(blade_identity_t *bi);
KS_DECLARE(ks_port_t) blade_identity_portnum_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_path_get(blade_identity_t *bi);
KS_DECLARE(const char *) blade_identity_parameter_lookup(blade_identity_t *bi, const char *key);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_MASTERMGR_H_
#define _BLADE_MASTERMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_mastermgr_create(blade_mastermgr_t **bmmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_mastermgr_destroy(blade_mastermgr_t **bmmgrP);
KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_mastermgr_shutdown(blade_mastermgr_t *bmmgr);
KS_DECLARE(blade_handle_t *) blade_mastermgr_handle_get(blade_mastermgr_t *bmmgr);
KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const char *nodeid);
KS_DECLARE(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, ks_bool_t writelocked);
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller);
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller);
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, blade_channel_flags_t flags);
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel);
KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *channel, const char *controller, const char *target);
KS_DECLARE(ks_bool_t) blade_mastermgr_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, const char *target);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_PROTOCOL_H_
#define _BLADE_PROTOCOL_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, const char *name);
KS_DECLARE(ks_status_t) blade_protocol_destroy(blade_protocol_t **bpP);
KS_DECLARE(const char *) blade_protocol_name_get(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_read_lock(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_read_unlock(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_write_lock(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_write_unlock(blade_protocol_t *bp);
KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nodeid);
KS_DECLARE(cJSON *) blade_protocol_controller_pack(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_controller_add(blade_protocol_t *bp, const char *nodeid);
KS_DECLARE(ks_bool_t) blade_protocol_controller_remove(blade_protocol_t *bp, const char *nodeid);
KS_DECLARE(ks_bool_t) blade_protocol_controller_available(blade_protocol_t *bp);
KS_DECLARE(blade_channel_t *) blade_protocol_channel_lookup(blade_protocol_t *bp, const char *channel, ks_bool_t writelocked);
KS_DECLARE(ks_bool_t) blade_protocol_controller_verify(blade_protocol_t *bp, const char *controller);
KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, blade_channel_t *channel);
KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *channel);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_RESTMGR_H_
#define _BLADE_RESTMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_restmgr_create(blade_restmgr_t **brestmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_restmgr_destroy(blade_restmgr_t **brestmgrP);
KS_DECLARE(ks_status_t) blade_restmgr_startup(blade_restmgr_t *brestmgr, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_restmgr_shutdown(blade_restmgr_t *brestmgr);
KS_DECLARE(blade_handle_t *) blade_restmgr_handle_get(blade_restmgr_t *brestmgr);
KS_DECLARE(void *) blade_restmgr_data_get(blade_restmgr_t *brestmgr);
KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void *data);
KS_DECLARE(ks_status_t) blade_restmgr_service_add(blade_restmgr_t *brestmgr, const char *action, const char *route, blade_restmgr_service_callback_t callback);
KS_DECLARE(ks_status_t) blade_restmgr_service_remove(blade_restmgr_t *brestmgr, const char *action, const char *route);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_ROUTEMGR_H_
#define _BLADE_ROUTEMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_routemgr_create(blade_routemgr_t **brmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_routemgr_destroy(blade_routemgr_t **brmgrP);
KS_DECLARE(blade_handle_t *) blade_routemgr_handle_get(blade_routemgr_t *brmgr);
KS_DECLARE(ks_status_t) blade_routemgr_local_set(blade_routemgr_t *brmgr, const char *nodeid);
KS_DECLARE(ks_bool_t) blade_routemgr_local_check(blade_routemgr_t *brmgr, const char *target);
KS_DECLARE(ks_bool_t) blade_routemgr_local_copy(blade_routemgr_t *brmgr, const char **nodeid);
KS_DECLARE(ks_bool_t) blade_routemgr_local_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key);
KS_DECLARE(ks_status_t) blade_routemgr_master_set(blade_routemgr_t *brmgr, const char *nodeid);
KS_DECLARE(ks_bool_t) blade_routemgr_master_check(blade_routemgr_t *brmgr, const char *target);
KS_DECLARE(ks_bool_t) blade_routemgr_master_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key);
KS_DECLARE(ks_bool_t) blade_routemgr_master_local(blade_routemgr_t *brmgr);
KS_DECLARE(blade_session_t *) blade_routemgr_route_lookup(blade_routemgr_t *brmgr, const char *target);
KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const char *target, const char *router);
KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, const char *target);
KS_DECLARE(ks_status_t) blade_routemgr_identity_add(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target);
KS_DECLARE(ks_status_t) blade_routemgr_identity_remove(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_RPC_H_
#define _BLADE_RPC_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, blade_rpc_request_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_rpc_destroy(blade_rpc_t **brpcP);
KS_DECLARE(blade_handle_t *) blade_rpc_handle_get(blade_rpc_t *brpc);
KS_DECLARE(const char *) blade_rpc_method_get(blade_rpc_t *brpc);
KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc);
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc);
KS_DECLARE(void *) blade_rpc_data_get(blade_rpc_t *brpc);
KS_DECLARE(ks_status_t) blade_rpc_request_create(blade_rpc_request_t **brpcreqP,
blade_handle_t *bh,
ks_pool_t *pool,
const char *session_id,
cJSON *json,
blade_rpc_response_callback_t callback,
void *data);
KS_DECLARE(ks_status_t) blade_rpc_request_destroy(blade_rpc_request_t **brpcreqP);
KS_DECLARE(ks_status_t) blade_rpc_request_duplicate(blade_rpc_request_t **brpcreqP, blade_rpc_request_t *brpcreq);
KS_DECLARE(blade_handle_t *) blade_rpc_request_handle_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpc_request_sessionid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(cJSON *) blade_rpc_request_message_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpc_request_messageid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(ks_status_t) blade_rpc_request_ttl_set(blade_rpc_request_t *brpcreq, ks_time_t ttl);
KS_DECLARE(ks_bool_t) blade_rpc_request_expired(blade_rpc_request_t *brpcreq);
KS_DECLARE(blade_rpc_response_callback_t) blade_rpc_request_callback_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(void *) blade_rpc_request_data_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(ks_status_t) blade_rpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
KS_DECLARE(ks_status_t) blade_rpc_response_create(blade_rpc_response_t **brpcresP,
blade_handle_t *bh,
ks_pool_t *pool,
const char *session_id,
blade_rpc_request_t *brpcreq,
cJSON *json);
KS_DECLARE(ks_status_t) blade_rpc_response_destroy(blade_rpc_response_t **brpcresP);
KS_DECLARE(ks_status_t) blade_rpc_response_raw_create(cJSON **json, cJSON **result, const char *id);
KS_DECLARE(blade_handle_t *) blade_rpc_response_handle_get(blade_rpc_response_t *brpcres);
KS_DECLARE(const char *) blade_rpc_response_sessionid_get(blade_rpc_response_t *brpcres);
KS_DECLARE(blade_rpc_request_t *) blade_rpc_response_request_get(blade_rpc_response_t *brpcres);
KS_DECLARE(cJSON *) blade_rpc_response_message_get(blade_rpc_response_t *brpcres);
KS_DECLARE(ks_status_t) blade_rpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_RPCMGR_H_
#define _BLADE_RPCMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_rpcmgr_create(blade_rpcmgr_t **brpcmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_rpcmgr_destroy(blade_rpcmgr_t **brpcmgrP);
KS_DECLARE(blade_handle_t *) blade_rpcmgr_handle_get(blade_rpcmgr_t *brpcmgr);
KS_DECLARE(blade_rpc_t *) blade_rpcmgr_corerpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method);
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol);
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(blade_rpc_request_t *) blade_rpcmgr_request_lookup(blade_rpcmgr_t *brpcmgr, const char *id);
KS_DECLARE(ks_status_t) blade_rpcmgr_request_add(blade_rpcmgr_t *brpcmgr, blade_rpc_request_t *brpcreq);
KS_DECLARE(ks_status_t) blade_rpcmgr_request_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_request_t *brpcreq);
KS_DECLARE(ks_status_t) blade_rpcmgr_request_timeouts(blade_rpcmgr_t *brpcmgr);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_SESSION_H_
#define _BLADE_SESSION_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_session_create(blade_session_t **bsP, blade_handle_t *bh, blade_session_flags_t flags, const char *sessionid);
KS_DECLARE(ks_status_t) blade_session_destroy(blade_session_t **bsP);
KS_DECLARE(ks_status_t) blade_session_startup(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs);
KS_DECLARE(blade_handle_t *) blade_session_handle_get(blade_session_t *bs);
KS_DECLARE(ks_bool_t) blade_session_loopback(blade_session_t *bs);
KS_DECLARE(ks_bool_t) blade_session_upstream(blade_session_t *bs);
KS_DECLARE(const char *) blade_session_id_get(blade_session_t *bs);
KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_route_add(blade_session_t *bs, const char *nodeid);
KS_DECLARE(ks_status_t) blade_session_route_remove(blade_session_t *bs, const char *nodeid);
KS_DECLARE(cJSON *) blade_session_properties_get(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_read_lock(blade_session_t *bs, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_session_read_unlock(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_write_lock(blade_session_t *bs, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_session_write_unlock(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_properties_read_lock(blade_session_t *bs, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_session_properties_read_unlock(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_properties_write_lock(blade_session_t *bs, ks_bool_t block);
KS_DECLARE(ks_status_t) blade_session_properties_write_unlock(blade_session_t *bs);
KS_DECLARE(void) blade_session_state_set(blade_session_t *bs, blade_session_state_t state);
KS_DECLARE(void) blade_session_hangup(blade_session_t *bs);
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs);
KS_DECLARE(const char *) blade_session_connection_get(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_connection_set(blade_session_t *bs, const char *id);
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, ks_time_t ttl, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json);
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json);
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json);
KS_DECLARE(ks_status_t) blade_session_receiving_pop(blade_session_t *bs, cJSON **json);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_SESSIONMGR_H_
#define _BLADE_SESSIONMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_sessionmgr_create(blade_sessionmgr_t **bsmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_sessionmgr_destroy(blade_sessionmgr_t **bsmgrP);
KS_DECLARE(blade_handle_t *) blade_sessionmgr_handle_get(blade_sessionmgr_t *bsmgr);
KS_DECLARE(ks_status_t) blade_sessionmgr_startup(blade_sessionmgr_t *bsmgr, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_sessionmgr_shutdown(blade_sessionmgr_t *bsmgr);
KS_DECLARE(blade_session_t *) blade_sessionmgr_loopback_lookup(blade_sessionmgr_t *bsmgr);
KS_DECLARE(blade_session_t *) blade_sessionmgr_upstream_lookup(blade_sessionmgr_t *bsmgr);
KS_DECLARE(blade_session_t *) blade_sessionmgr_session_lookup(blade_sessionmgr_t *bsmgr, const char *id);
KS_DECLARE(ks_status_t) blade_sessionmgr_session_add(blade_sessionmgr_t *bsmgr, blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmgr, blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_sessionmgr_callback_add(blade_sessionmgr_t *bsmgr, void *data, blade_session_callback_t callback, const char **id);
KS_DECLARE(ks_status_t) blade_sessionmgr_callback_remove(blade_sessionmgr_t *bsmgr, const char *id);
KS_DECLARE(void) blade_sessionmgr_callback_execute(blade_sessionmgr_t *bsmgr, blade_session_t *bs, blade_session_state_condition_t condition);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_STACK_H_
#define _BLADE_STACK_H_
#include <blade.h>
#define BLADE_HANDLE_TPOOL_MIN 2
#define BLADE_HANDLE_TPOOL_MAX 4096
#define BLADE_HANDLE_TPOOL_STACK (1024 * 256)
#define BLADE_HANDLE_TPOOL_IDLE 10
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP);
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP);
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh);
KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
KS_DECLARE(blade_transportmgr_t *) blade_handle_transportmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_rpcmgr_t *) blade_handle_rpcmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_routemgr_t *) blade_handle_routemgr_get(blade_handle_t *bh);
KS_DECLARE(blade_subscriptionmgr_t *) blade_handle_subscriptionmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_mastermgr_t *) blade_handle_mastermgr_get(blade_handle_t *bh);
KS_DECLARE(blade_connectionmgr_t *) blade_handle_connectionmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_sessionmgr_t *) blade_handle_sessionmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_restmgr_t *) blade_handle_restmgr_get(blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id);
KS_DECLARE(ks_status_t) blade_handle_rpcroute(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char *identity, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpublish_command_t command, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_handle_rpcauthorize(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_handle_rpclocate(blade_handle_t *bh, const char *protocol, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_handle_rpcexecute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, cJSON *params, ks_time_t ttl, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(const char *) blade_rpcexecute_request_requester_nodeid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcexecute_request_responder_nodeid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(cJSON *) blade_rpcexecute_request_params_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(cJSON *) blade_rpcexecute_response_result_get(blade_rpc_response_t *brpcres);
KS_DECLARE(void) blade_rpcexecute_response_send(blade_rpc_request_t *brpcreq, cJSON *result);
KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh, blade_rpcsubscribe_command_t command, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data, blade_rpc_request_callback_t channel_callback, void *channel_data);
KS_DECLARE(ks_status_t) blade_handle_rpcbroadcast(blade_handle_t *bh, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(cJSON *) blade_rpcbroadcast_request_params_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_protocol_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_channel_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_event_get(blade_rpc_request_t *brpcreq);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_SUBSCRIPTION_H_
#define _BLADE_SUBSCRIPTION_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *channel);
KS_DECLARE(ks_status_t) blade_subscription_destroy(blade_subscription_t **bsubP);
KS_DECLARE(const char *) blade_subscription_protocol_get(blade_subscription_t *bsub);
KS_DECLARE(const char *) blade_subscription_channel_get(blade_subscription_t *bsub);
KS_DECLARE(ks_hash_t *) blade_subscription_subscribers_get(blade_subscription_t *bsub);
KS_DECLARE(ks_status_t) blade_subscription_subscribers_add(blade_subscription_t *bsub, const char *nodeid);
KS_DECLARE(ks_status_t) blade_subscription_subscribers_remove(blade_subscription_t *bsub, const char *nodeid);
KS_DECLARE(blade_rpc_request_callback_t) blade_subscription_callback_get(blade_subscription_t *bsub);
KS_DECLARE(void) blade_subscription_callback_set(blade_subscription_t *bsub, blade_rpc_request_callback_t callback);
KS_DECLARE(void *) blade_subscription_callback_data_get(blade_subscription_t *bsub);
KS_DECLARE(void) blade_subscription_callback_data_set(blade_subscription_t *bsub, void *data);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_SUBSCRIPTIONMGR_H_
#define _BLADE_SUBSCRIPTIONMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_subscriptionmgr_create(blade_subscriptionmgr_t **bsmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_subscriptionmgr_destroy(blade_subscriptionmgr_t **bsmgrP);
KS_DECLARE(blade_handle_t *) blade_subscriptionmgr_handle_get(blade_subscriptionmgr_t *bsmgr);
KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel);
KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel);
KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber);
KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber);
KS_DECLARE(void) blade_subscriptionmgr_purge(blade_subscriptionmgr_t *bsmgr, const char *target);
KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_sessionid, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_TRANSPORT_H_
#define _BLADE_TRANSPORT_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_transport_create(blade_transport_t **btP, blade_handle_t *bh, ks_pool_t *pool, const char *name, void *data, blade_transport_callbacks_t *callbacks);
KS_DECLARE(ks_status_t) blade_transport_destroy(blade_transport_t **btP);
KS_DECLARE(blade_handle_t *) blade_transport_handle_get(blade_transport_t *bt);
KS_DECLARE(const char *) blade_transport_name_get(blade_transport_t *bt);
KS_DECLARE(void *) blade_transport_data_get(blade_transport_t *bt);
KS_DECLARE(blade_transport_callbacks_t *) blade_transport_callbacks_get(blade_transport_t *bt);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_TRANSPORT_WSS_H_
#define _BLADE_TRANSPORT_WSS_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_transport_wss_create(blade_transport_t **btP, blade_handle_t *bh);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_TRANSPORTMGR_H_
#define _BLADE_TRANSPORTMGR_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_transportmgr_create(blade_transportmgr_t **btmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_transportmgr_destroy(blade_transportmgr_t **btmgrP);
KS_DECLARE(ks_status_t) blade_transportmgr_startup(blade_transportmgr_t *btmgr, config_setting_t *config);
KS_DECLARE(ks_status_t) blade_transportmgr_shutdown(blade_transportmgr_t *btmgr);
KS_DECLARE(blade_handle_t *) blade_transportmgr_handle_get(blade_transportmgr_t *btmgr);
KS_DECLARE(blade_transport_t *) blade_transportmgr_default_get(blade_transportmgr_t *btmgr);
KS_DECLARE(ks_status_t) blade_transportmgr_default_set(blade_transportmgr_t *btmgr, blade_transport_t *bt);
KS_DECLARE(blade_transport_t *) blade_transportmgr_transport_lookup(blade_transportmgr_t *btmgr, const char *name, ks_bool_t ordefault);
KS_DECLARE(ks_status_t) blade_transportmgr_transport_add(blade_transportmgr_t *btmgr, blade_transport_t *bt);
KS_DECLARE(ks_status_t) blade_transportmgr_transport_remove(blade_transportmgr_t *btmgr, blade_transport_t *bt);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_TUPLE_H_
#define _BLADE_TUPLE_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_tuple_create(blade_tuple_t **btP, ks_pool_t *pool, void *value1, void *value2);
KS_DECLARE(ks_status_t) blade_tuple_destroy(blade_tuple_t **btP);
KS_DECLARE(void *) blade_tuple_value1_get(blade_tuple_t *bt);
KS_DECLARE(void *) blade_tuple_value2_get(blade_tuple_t *bt);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,185 +0,0 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_TYPES_H_
#define _BLADE_TYPES_H_
#include <ks.h>
#include <libconfig.h>
KS_BEGIN_EXTERN_C
typedef struct blade_handle_s blade_handle_t;
typedef struct blade_identity_s blade_identity_t;
typedef struct blade_transport_s blade_transport_t;
typedef struct blade_transport_callbacks_s blade_transport_callbacks_t;
typedef struct blade_rpc_s blade_rpc_t;
typedef struct blade_rpc_request_s blade_rpc_request_t;
typedef struct blade_rpc_response_s blade_rpc_response_t;
typedef struct blade_connection_s blade_connection_t;
typedef struct blade_session_s blade_session_t;
typedef struct blade_session_callbacks_s blade_session_callbacks_t;
typedef struct blade_protocol_s blade_protocol_t;
typedef struct blade_channel_s blade_channel_t;
typedef struct blade_subscription_s blade_subscription_t;
typedef struct blade_tuple_s blade_tuple_t;
typedef struct blade_transportmgr_s blade_transportmgr_t;
typedef struct blade_rpcmgr_s blade_rpcmgr_t;
typedef struct blade_routemgr_s blade_routemgr_t;
typedef struct blade_subscriptionmgr_s blade_subscriptionmgr_t;
typedef struct blade_mastermgr_s blade_mastermgr_t;
typedef struct blade_connectionmgr_s blade_connectionmgr_t;
typedef struct blade_sessionmgr_s blade_sessionmgr_t;
typedef struct blade_session_callback_data_s blade_session_callback_data_t;
typedef struct blade_webrequest_s blade_webrequest_t;
typedef struct blade_webresponse_s blade_webresponse_t;
typedef struct blade_restmgr_s blade_restmgr_t;
typedef ks_bool_t (*blade_rpc_request_callback_t)(blade_rpc_request_t *brpcreq, void *data);
typedef ks_bool_t (*blade_rpc_response_callback_t)(blade_rpc_response_t *brpcres, void *data);
typedef int (*blade_restmgr_service_callback_t)(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures);
typedef enum {
BLADE_CONNECTION_STATE_NONE,
BLADE_CONNECTION_STATE_CLEANUP,
BLADE_CONNECTION_STATE_STARTUP,
BLADE_CONNECTION_STATE_SHUTDOWN,
BLADE_CONNECTION_STATE_RUN,
} blade_connection_state_t;
typedef enum {
BLADE_CONNECTION_DIRECTION_INBOUND,
BLADE_CONNECTION_DIRECTION_OUTBOUND,
} blade_connection_direction_t;
typedef enum {
BLADE_CONNECTION_STATE_CONDITION_PRE,
BLADE_CONNECTION_STATE_CONDITION_POST,
} blade_connection_state_condition_t;
typedef enum {
BLADE_CONNECTION_STATE_HOOK_SUCCESS,
BLADE_CONNECTION_STATE_HOOK_DISCONNECT,
BLADE_CONNECTION_STATE_HOOK_BYPASS,
} blade_connection_state_hook_t;
typedef enum {
BLADE_SESSION_FLAGS_NONE = 0 << 0,
BLADE_SESSION_FLAGS_LOOPBACK = 1 << 0,
BLADE_SESSION_FLAGS_UPSTREAM = 1 << 1,
} blade_session_flags_t;
typedef enum {
BLADE_SESSION_STATE_CONDITION_PRE,
BLADE_SESSION_STATE_CONDITION_POST,
} blade_session_state_condition_t;
typedef enum {
BLADE_SESSION_STATE_NONE,
BLADE_SESSION_STATE_CLEANUP,
BLADE_SESSION_STATE_STARTUP,
BLADE_SESSION_STATE_SHUTDOWN,
BLADE_SESSION_STATE_RUN,
} blade_session_state_t;
typedef enum {
BLADE_CHANNEL_FLAGS_NONE = 0 << 0,
BLADE_CHANNEL_FLAGS_PUBLIC = 1 << 0,
} blade_channel_flags_t;
typedef ks_status_t (*blade_transport_startup_callback_t)(blade_transport_t *bt, config_setting_t *config);
typedef ks_status_t (*blade_transport_shutdown_callback_t)(blade_transport_t *bt);
typedef ks_status_t (*blade_transport_connect_callback_t)(blade_connection_t **bcP, blade_transport_t *bt, blade_identity_t *target, const char *session_id);
typedef ks_status_t (*blade_transport_send_callback_t)(blade_connection_t *bc, cJSON *json);
typedef ks_status_t (*blade_transport_receive_callback_t)(blade_connection_t *bc, cJSON **json);
typedef blade_connection_state_hook_t (*blade_transport_state_callback_t)(blade_connection_t *bc, blade_connection_state_condition_t condition);
struct blade_transport_callbacks_s {
blade_transport_startup_callback_t onstartup;
blade_transport_shutdown_callback_t onshutdown;
blade_transport_connect_callback_t onconnect;
blade_transport_send_callback_t onsend;
blade_transport_receive_callback_t onreceive;
blade_transport_state_callback_t onstate_startup_inbound;
blade_transport_state_callback_t onstate_startup_outbound;
blade_transport_state_callback_t onstate_shutdown_inbound;
blade_transport_state_callback_t onstate_shutdown_outbound;
blade_transport_state_callback_t onstate_run_inbound;
blade_transport_state_callback_t onstate_run_outbound;
};
typedef void (*blade_session_callback_t)(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
typedef enum {
BLADE_RPCPUBLISH_COMMAND_NONE,
BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD,
BLADE_RPCPUBLISH_COMMAND_CONTROLLER_REMOVE,
BLADE_RPCPUBLISH_COMMAND_CHANNEL_ADD,
BLADE_RPCPUBLISH_COMMAND_CHANNEL_REMOVE,
} blade_rpcpublish_command_t;
typedef enum {
BLADE_RPCSUBSCRIBE_COMMAND_NONE,
BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD,
BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE,
} blade_rpcsubscribe_command_t;
typedef enum {
BLADE_RPCBROADCAST_COMMAND_NONE,
BLADE_RPCBROADCAST_COMMAND_EVENT,
BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE,
BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE,
} blade_rpcbroadcast_command_t;
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2017, Shane Bryldt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _BLADE_WEB_H_
#define _BLADE_WEB_H_
#include <blade.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_webrequest_create(blade_webrequest_t **bwreqP, const char *action, const char *path);
KS_DECLARE(ks_status_t) blade_webrequest_load(blade_webrequest_t **bwreqP, struct mg_connection *conn);
KS_DECLARE(ks_status_t) blade_webrequest_destroy(blade_webrequest_t **bwreqP);
KS_DECLARE(const char *) blade_webrequest_action_get(blade_webrequest_t *bwreq);
KS_DECLARE(const char *) blade_webrequest_path_get(blade_webrequest_t *bwreq);
KS_DECLARE(ks_status_t) blade_webrequest_query_add(blade_webrequest_t *bwreq, const char *name, const char *value);
KS_DECLARE(const char *) blade_webrequest_query_get(blade_webrequest_t *bwreq, const char *name);
KS_DECLARE(ks_status_t) blade_webrequest_header_add(blade_webrequest_t *bwreq, const char *header, const char *value);
KS_DECLARE(ks_status_t) blade_webrequest_header_printf(blade_webrequest_t *bwreq, const char *header, const char *fmt, ...);
KS_DECLARE(const char *) blade_webrequest_header_get(blade_webrequest_t *bwreq, const char *header);
KS_DECLARE(ks_status_t) blade_webrequest_content_json_append(blade_webrequest_t *bwreq, cJSON *json);
KS_DECLARE(ks_status_t) blade_webrequest_content_string_append(blade_webrequest_t *bwreq, const char *str);
KS_DECLARE(ks_status_t) blade_webrequest_send(blade_webrequest_t *bwreq, ks_bool_t secure, const char *host, ks_port_t port, blade_webresponse_t **bwresP);
KS_DECLARE(ks_status_t) blade_webrequest_oauth2_token_by_credentials_send(ks_bool_t secure, const char *host, ks_port_t port, const char *path, const char *client_id, const char *client_secret, const char **token);
KS_DECLARE(ks_status_t) blade_webrequest_oauth2_token_by_code_send(ks_bool_t secure, const char *host, ks_port_t port, const char *path, const char *client_id, const char *client_secret, const char *code, const char **token);
KS_DECLARE(ks_status_t) blade_webresponse_create(blade_webresponse_t **bwresP, const char *status);
KS_DECLARE(ks_status_t) blade_webresponse_load(blade_webresponse_t **bwresP, struct mg_connection *conn);
KS_DECLARE(ks_status_t) blade_webresponse_destroy(blade_webresponse_t **bwresP);
KS_DECLARE(ks_status_t) blade_webresponse_header_add(blade_webresponse_t *bwres, const char *header, const char *value);
KS_DECLARE(const char *) blade_webresponse_header_get(blade_webresponse_t *bwres, const char *header);
KS_DECLARE(ks_status_t) blade_webresponse_content_json_append(blade_webresponse_t *bwres, cJSON *json);
KS_DECLARE(ks_status_t) blade_webresponse_content_string_append(blade_webresponse_t *bwres, const char *str);
KS_DECLARE(ks_status_t) blade_webresponse_content_json_get(blade_webresponse_t *bwres, cJSON **json);
KS_DECLARE(ks_status_t) blade_webresponse_send(blade_webresponse_t *bwres, struct mg_connection *conn);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,730 +0,0 @@
/*
* libbencodetools
*
* Written by Heikki Orsila <heikki.orsila@iki.fi> and
* Janne Kulmala <janne.t.kulmala@tut.fi> in 2011.
*/
#ifndef TYPEVALIDATOR_BENCODE_H
#define TYPEVALIDATOR_BENCODE_H
#include <stdlib.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Used to verify format strings in compile time */
#ifdef __GNUC__
#define BEN_CHECK_FORMAT(...) __attribute__ ((format( __VA_ARGS__ )))
#else
#define BEN_CHECK_FORMAT(...)
#endif
enum {
BENCODE_BOOL = 1,
BENCODE_DICT,
BENCODE_INT,
BENCODE_LIST,
BENCODE_STR,
BENCODE_USER,
};
enum {
BEN_OK = 0, /* No errors. Set to zero. Non-zero implies an error. */
BEN_INVALID, /* Invalid data was given to decoder */
BEN_INSUFFICIENT, /* Insufficient amount of data for decoding */
BEN_NO_MEMORY, /* Memory allocation failed */
BEN_MISMATCH, /* A given structure did not match unpack format */
};
struct bencode {
char type;
};
struct bencode_bool {
char type;
char b;
};
struct bencode_dict_node {
long long hash;
struct bencode *key;
struct bencode *value;
size_t next;
};
struct bencode_dict {
char type;
char shared; /* non-zero means that the internal data is shared with
other instances and should not be freed */
size_t n;
size_t alloc;
size_t *buckets;
struct bencode_dict_node *nodes;
};
struct bencode_int {
char type;
long long ll;
};
struct bencode_list {
char type;
char shared; /* non-zero means that the internal data is shared with
other instances and should not be freed */
size_t n;
size_t alloc;
struct bencode **values;
};
struct bencode_str {
char type;
size_t len;
char *s;
};
struct ben_decode_ctx;
struct ben_encode_ctx;
struct bencode_type {
size_t size;
struct bencode *(*decode) (struct ben_decode_ctx *ctx);
int (*encode) (struct ben_encode_ctx *ctx, const struct bencode *b);
size_t (*get_size) (const struct bencode *b);
void (*freer) (struct bencode *b);
int (*cmp) (const struct bencode *a, const struct bencode *b);
};
struct bencode_user {
char type;
struct bencode_type *info;
};
struct bencode_error {
int error; /* 0 if no errors */
int line; /* Error line: 0 is the first line */
size_t off; /* Error offset in bytes from the start */
};
/* Allocate an instance of a user-defined type */
void *ben_alloc_user(struct bencode_type *type);
/*
* Try to set capacity of a list or a dict to 'n' objects.
* The function does nothing if 'n' is less than or equal to the number of
* objects in 'b'. That is, nothing happens if n <= ben_{dict|list}_len(b).
*
* This function is used only for advice. The implementation need not obey it.
*
* The function returns 0 if the new capacity is used, otherwise -1.
*
* Note: This can be used to make construction of lists and dicts
* more efficient when the number of inserted items is known in advance.
*/
int ben_allocate(struct bencode *b, size_t n);
/*
* Returns an identical but a separate copy of structure b. Returns NULL if
* there is no memory to make a copy. The copy is made recursively.
*/
struct bencode *ben_clone(const struct bencode *b);
/*
* Returns a weak reference copy of structure b. Only a minimum amount of
* data is copied because the returned structure references to the same
* internal data as the original structure. As a result, the original
* structure must remain valid until the copy is destroyed.
*
* This function is used for optimization for special cases.
*/
struct bencode *ben_shared_clone(const struct bencode *b);
/*
* ben_cmp() is similar to strcmp(). It compares integers, strings and lists
* similar to Python. User-defined types can be also compared.
* Note: an integer is always less than a string.
*
* ben_cmp(a, b) returns a negative value if "a < b", 0 if "a == b",
* or a positive value if "a > b".
*
* Algorithm for comparing dictionaries is:
* If 'a' and 'b' have different number of keys or keys have different values,
* a non-zero value is returned. Otherwise, they have the exact same keys
* and comparison is done in ben_cmp() order of keys. The value for each key
* is compared, and the first inequal value (ben_cmp() != 0) defines the
* return value of the comparison.
*
* Note: recursive dictionaries in depth have the same issues.
*/
int ben_cmp(const struct bencode *a, const struct bencode *b);
/* Same as ben_cmp(), but the second argument is a C string */
int ben_cmp_with_str(const struct bencode *a, const char *s);
/*
* Comparison function suitable for qsort(). Uses ben_cmp(), so this can be
* used to order both integer and string arrays.
*/
int ben_cmp_qsort(const void *a, const void *b);
/*
* Decode 'data' with 'len' bytes of data. Returns NULL on error.
* The encoded data must be exactly 'len' bytes (not less), otherwise NULL
* is returned. ben_decode2() function supports partial decoding ('len' is
* larger than actual decoded message) and gives more accurate error reports.
*/
struct bencode *ben_decode(const void *data, size_t len);
/*
* Same as ben_decode(), but allows one to set start offset for decoding with
* 'off' and reports errors more accurately.
*
* '*off' must point to decoding start offset inside 'data'.
* If decoding is successful, '*off' is updated to point to the next byte
* after the decoded message.
*
* If 'error != NULL', it is updated according to the success and error of
* the decoding. BEN_OK is success, BEN_INVALID means invalid data.
* BEN_INSUFFICIENT means data is invalid but could be valid if more data
* was given for decoding. BEN_NO_MEMORY means decoding ran out of memory.
*/
struct bencode *ben_decode2(const void *data, size_t len, size_t *off, int *error);
/*
* Same as ben_decode2(), but allows one to define user types.
*/
struct bencode *ben_decode3(const void *data, size_t len, size_t *off, int *error, struct bencode_type *types[128]);
/*
* Same as ben_decode(), but decodes data encoded with ben_print(). This is
* whitespace tolerant, so intended Python syntax can also be read.
* The decoder skips comments that begin with a '#' character.
* The comment starts from '#' character and ends at the end of the same line.
*
* For example, this can be used to read in config files written as a Python
* dictionary.
*
* ben_decode_printed2() fills information about the error in
* struct bencode_error.
* error->error is 0 on success, otherwise it is an error code
* (see ben_decode2()).
* error->line is the line number where error occured.
* error->off is the byte offset of error (approximation).
*/
struct bencode *ben_decode_printed(const void *data, size_t len);
struct bencode *ben_decode_printed2(const void *data, size_t len, size_t *off, struct bencode_error *error);
/* Get the serialization size of bencode structure 'b' */
size_t ben_encoded_size(const struct bencode *b);
/* encode 'b'. Return encoded data with a pointer, and length in '*len' */
void *ben_encode(size_t *len, const struct bencode *b);
/*
* encode 'b' into 'data' buffer with at most 'maxlen' bytes.
* Returns the size of encoded data.
*/
size_t ben_encode2(char *data, size_t maxlen, const struct bencode *b);
/*
* You must use ben_free() for all allocated bencode structures after use.
* If b == NULL, ben_free does nothing.
*
* ben_free() frees all the objects contained within the bencoded structure.
* It recursively iterates over lists and dictionaries and frees objects.
*/
void ben_free(struct bencode *b);
long long ben_str_hash(const struct bencode *b);
long long ben_int_hash(const struct bencode *b);
long long ben_hash(const struct bencode *b);
/* Create a string from binary data with len bytes */
struct bencode *ben_blob(const void *data, size_t len);
/* Create a boolean from integer */
struct bencode *ben_bool(int b);
/* Create an empty dictionary */
struct bencode *ben_dict(void);
/*
* Try to locate 'key' in dictionary. Returns the associated value, if found.
* Returns NULL if the key does not exist.
*/
struct bencode *ben_dict_get(const struct bencode *d, const struct bencode *key);
struct bencode *ben_dict_get_by_str(const struct bencode *d, const char *key);
struct bencode *ben_dict_get_by_int(const struct bencode *d, long long key);
struct bencode_keyvalue {
struct bencode *key;
struct bencode *value;
};
/*
* Returns an array of key-value pairs in key order as defined by ben_cmp().
* Array elements are struct bencode_keyvalue members. Returns NULL if
* the array can not be allocated or the bencode object is not a dictionary.
* The returned array must be freed by using free(). The length of the
* array can be determined with ben_dict_len(d).
*
* Warning: key and value pointers in the array are pointers to exact same
* objects in the dictionary. Therefore, the dictionary and its key-values
* must exist while the same keys and values are accessed from the array.
*/
struct bencode_keyvalue *ben_dict_ordered_items(const struct bencode *d);
/*
* Try to locate 'key' in dictionary. Returns the associated value, if found.
* The value must be later freed with ben_free(). Returns NULL if the key
* does not exist.
*/
struct bencode *ben_dict_pop(struct bencode *d, const struct bencode *key);
struct bencode *ben_dict_pop_by_str(struct bencode *d, const char *key);
struct bencode *ben_dict_pop_by_int(struct bencode *d, long long key);
/*
* Set 'key' in dictionary to be 'value'. An old value exists for the key
* is freed if it exists. 'key' and 'value' are owned by the dictionary
* after a successful call (one may not call ben_free() for 'key' or
* 'value'). One may free 'key' and 'value' if the call is unsuccessful.
*
* Returns 0 on success, -1 on failure (no memory).
*/
int ben_dict_set(struct bencode *d, struct bencode *key, struct bencode *value);
/* Same as ben_dict_set(), but the key is a C string */
int ben_dict_set_by_str(struct bencode *d, const char *key, struct bencode *value);
/* Same as ben_dict_set(), but the key and value are C strings */
int ben_dict_set_str_by_str(struct bencode *d, const char *key, const char *value);
struct bencode *ben_int(long long ll);
/* Create an empty list */
struct bencode *ben_list(void);
/*
* Append 'b' to 'list'. Returns 0 on success, -1 on failure (no memory).
* One may not call ben_free(b) after a successful call, because the list owns
* the object 'b'.
*/
int ben_list_append(struct bencode *list, struct bencode *b);
int ben_list_append_str(struct bencode *list, const char *s);
int ben_list_append_int(struct bencode *list, long long ll);
/* Remove and return value at position 'pos' in list */
struct bencode *ben_list_pop(struct bencode *list, size_t pos);
/*
* Returns a Python formatted C string representation of 'b' on success,
* NULL on failure. The returned string should be freed with free().
*
* Note: The string is terminated with '\0'. All instances of '\0' bytes in
* the bencoded data are escaped so that there is only one '\0' byte
* in the generated string at the end.
*/
char *ben_print(const struct bencode *b);
/* Create a string from C string (note bencode string may contain '\0'. */
struct bencode *ben_str(const char *s);
/* Return a human readable explanation of error returned with ben_decode2() */
const char *ben_strerror(int error);
/*
* Unpack a Bencoded structure similar to scanf(). Takes a format string and
* a list of pointers as variable arguments. The given b structure is checked
* against the format and values are unpacked using the given specifiers.
* A specifier begins with a percent (%) that follows a string of specifier
* characters documented below.
* The syntax is similar to Python format for recursive data structures, and
* consists of tokens {, }, [, ] with any number of spaces between them.
* The keys of a dictionary are given as literal strings or integers and
* matched against the keys of the Bencoded structure.
*
* Unpack modifiers:
* l The integer is of type long or unsigned long, and the type of the
* argument is expected to be long * or unsigned long *.
* ll The integer is a long long or an unsigned long long, and the
* argument is long long * or unsigned long long *.
* L Same as ll.
* q Same as ll.
*
* Unpack specifiers:
* %ps The Bencode value must be a string and a pointer to a string
* (char **) is expected to be given as arguments. Note, returns a
* reference to the internal string buffer. The returned memory should
* not be freed and it has the same life time as the Bencode string.
*
* %pb Takes any structure and writes a pointer given as an argument.
* The argument is expected to be "struct bencode **". Note, returns a
* reference to the value inside the structure passed to ben_unpack().
* The returned memory should not be freed and it has the same life
* time as the original structure.
*
* %d The bencode value is expected to be a (signed) integer. The
* preceeding conversion modifiers define the type of the given
* pointer.
* %u The bencode value is expected to be an unsigned integer. The
* preceeding conversion modifiers define the type of the given
* pointer.
*/
int ben_unpack(const struct bencode *b, const char *fmt, ...)
BEN_CHECK_FORMAT(scanf, 2, 3);
int ben_unpack2(const struct bencode *b, size_t *off, struct bencode_error *error, const char *fmt, ...)
BEN_CHECK_FORMAT(scanf, 4, 5);
/*
* Pack a Bencoded structure similar to printf(). Takes a format string and
* a list of values as variable arguments.
* Works similarly to ben_decode_printed(), but allows the string to values
* specifiers which are replaced with values given as arguments.
* A specifier begins with a percent (%) that follows a string of specifier
* characters documented below.
*
* Value modifiers:
* l The integer is of type long or unsigned long.
* ll The integer is a long long or an unsigned long long.
* L Same as ll.
* q Same as ll.
*
* Value specifiers:
* %s A string pointer (char *) expected to be given as argument. A new
* Bencode string is constructed from the given string.
*
* %pb A Bencode structure (struct bencode *) is expected to be given as
* argument. Note, takes ownership of the structure, even when an
* error is returned.
*
* %d Constructs a new integer from the given (signed) integer. The
* preceeding conversion modifiers define the type of the value.
*
* %u Constructs a new integer from the given unsigned integer. The
* preceeding conversion modifiers define the type of the value.
*/
struct bencode *ben_pack(const char *fmt, ...)
BEN_CHECK_FORMAT(printf, 1, 2);
/* ben_is_bool() returns 1 iff b is a boolean, 0 otherwise */
static inline int ben_is_bool(const struct bencode *b)
{
return b->type == BENCODE_BOOL;
}
static inline int ben_is_dict(const struct bencode *b)
{
return b->type == BENCODE_DICT;
}
static inline int ben_is_int(const struct bencode *b)
{
return b->type == BENCODE_INT;
}
static inline int ben_is_list(const struct bencode *b)
{
return b->type == BENCODE_LIST;
}
static inline int ben_is_str(const struct bencode *b)
{
return b->type == BENCODE_STR;
}
static inline int ben_is_user(const struct bencode *b)
{
return b->type == BENCODE_USER;
}
/*
* ben_bool_const_cast(b) returns "(const struct bencode_bool *) b" if the
* underlying object is a boolean, NULL otherwise.
*/
static inline const struct bencode_bool *ben_bool_const_cast(const struct bencode *b)
{
return b->type == BENCODE_BOOL ? ((const struct bencode_bool *) b) : NULL;
}
/*
* ben_bool_cast(b) returns "(struct bencode_bool *) b" if the
* underlying object is a boolean, NULL otherwise.
*/
static inline struct bencode_bool *ben_bool_cast(struct bencode *b)
{
return b->type == BENCODE_BOOL ? ((struct bencode_bool *) b) : NULL;
}
static inline const struct bencode_dict *ben_dict_const_cast(const struct bencode *b)
{
return b->type == BENCODE_DICT ? ((const struct bencode_dict *) b) : NULL;
}
static inline struct bencode_dict *ben_dict_cast(struct bencode *b)
{
return b->type == BENCODE_DICT ? ((struct bencode_dict *) b) : NULL;
}
static inline const struct bencode_int *ben_int_const_cast(const struct bencode *i)
{
return i->type == BENCODE_INT ? ((const struct bencode_int *) i) : NULL;
}
static inline struct bencode_int *ben_int_cast(struct bencode *i)
{
return i->type == BENCODE_INT ? ((struct bencode_int *) i) : NULL;
}
static inline const struct bencode_list *ben_list_const_cast(const struct bencode *list)
{
return list->type == BENCODE_LIST ? ((const struct bencode_list *) list) : NULL;
}
static inline struct bencode_list *ben_list_cast(struct bencode *list)
{
return list->type == BENCODE_LIST ? ((struct bencode_list *) list) : NULL;
}
static inline const struct bencode_str *ben_str_const_cast(const struct bencode *str)
{
return str->type == BENCODE_STR ? ((const struct bencode_str *) str) : NULL;
}
static inline struct bencode_str *ben_str_cast(struct bencode *str)
{
return str->type == BENCODE_STR ? ((struct bencode_str *) str) : NULL;
}
static inline const struct bencode_user *ben_user_const_cast(const struct bencode *user)
{
return user->type == BENCODE_USER ? ((const struct bencode_user *) user) : NULL;
}
static inline struct bencode_user *ben_user_cast(struct bencode *user)
{
return user->type == BENCODE_USER ? ((struct bencode_user *) user) : NULL;
}
static inline int ben_is_user_type(const struct bencode *b, struct bencode_type *type)
{
return b->type == BENCODE_USER ? ((const struct bencode_user *) b)->info == type : 0;
}
static inline const void *ben_user_type_const_cast(const struct bencode *b, struct bencode_type *type)
{
return (b->type == BENCODE_USER && ((const struct bencode_user *) b)->info == type) ? b : NULL;
}
static inline void *ben_user_type_cast(struct bencode *b, struct bencode_type *type)
{
return (b->type == BENCODE_USER && ((const struct bencode_user *) b)->info == type) ? b : NULL;
}
/* Return the number of keys in a dictionary 'b' */
static inline size_t ben_dict_len(const struct bencode *b)
{
return ben_dict_const_cast(b)->n;
}
/* Return the number of items in a list 'b' */
static inline size_t ben_list_len(const struct bencode *b)
{
return ben_list_const_cast(b)->n;
}
/* ben_list_get(list, i) returns object at position i in list */
static inline struct bencode *ben_list_get(const struct bencode *list, size_t i)
{
const struct bencode_list *l = ben_list_const_cast(list);
if (i >= l->n) {
fprintf(stderr, "bencode: List index out of bounds\n");
abort();
}
return l->values[i];
}
/*
* ben_list_set(list, i, b) sets object b to list at position i.
* The old value at position i is freed.
* The program aborts if position i is out of bounds.
*/
void ben_list_set(struct bencode *list, size_t i, struct bencode *b);
/* Return the number of bytes in a string 'b' */
static inline size_t ben_str_len(const struct bencode *b)
{
return ben_str_const_cast(b)->len;
}
/* Return boolean value (0 or 1) of 'b' */
static inline int ben_bool_val(const struct bencode *b)
{
return ben_bool_const_cast(b)->b ? 1 : 0;
}
/* Return integer value of 'b' */
static inline long long ben_int_val(const struct bencode *b)
{
return ben_int_const_cast(b)->ll;
}
/*
* Note: the string is always zero terminated. Also, the string may
* contain more than one zero.
* bencode strings are not compatible with C strings.
*/
static inline const char *ben_str_val(const struct bencode *b)
{
return ben_str_const_cast(b)->s;
}
/*
* ben_list_for_each() is an iterator macro for bencoded lists.
*
* Note, it is not allowed to change the list while iterating except by
* using ben_list_pop_current().
*
* pos is a size_t.
*
* Example:
*
* size_t pos;
* struct bencode *list = xxx;
* struct bencode *value;
* ben_list_for_each(value, pos, list) {
* inspect(value);
* }
*/
#define ben_list_for_each(value, pos, l) \
for ((pos) = (size_t) 0; \
(pos) < (ben_list_const_cast(l))->n && \
((value) = ((const struct bencode_list *) (l))->values[(pos)]) != NULL ; \
(pos)++)
/*
* ben_list_pop_current() returns and removes the current item at 'pos'
* while iterating the list with ben_list_for_each().
* It can be used more than once per walk, but only once per item.
* Example below:
*
* Filter out all items from list whose string value does not begin with "foo".
*
* ben_list_for_each(value, pos, list) {
* if (strncmp(ben_str_val(value), "foo", 3) != 0)
* ben_free(ben_list_pop_current(&pos, list));
* }
*/
static inline struct bencode *ben_list_pop_current(struct bencode *list,
size_t *pos)
{
struct bencode *value = ben_list_pop(list, *pos);
(*pos)--;
return value;
}
/*
* ben_dict_for_each() is an iterator macro for bencoded dictionaries.
*
* Note, it is not allowed to change the dictionary while iterating except
* by using ben_dict_pop_current().
*
* struct bencode *dict = ben_dict();
* size_t pos;
* struct bencode *key;
* struct bencode *value;
* ben_dict_set_str_by_str(dict, "foo", "bar");
*
* ben_dict_for_each(key, value, pos, dict) {
* use(key, value);
* }
*
* pos is a size_t.
*/
#define ben_dict_for_each(bkey, bvalue, pos, d) \
for ((pos) = 0; \
(pos) < (ben_dict_const_cast(d))->n && \
((bkey) = ((const struct bencode_dict *) (d))->nodes[(pos)].key) != NULL && \
((bvalue) = ((const struct bencode_dict *) (d))->nodes[(pos)].value) != NULL; \
(pos)++)
/*
* ben_dict_pop_current() deletes the current item at 'pos' while iterating
* the dictionary with ben_dict_for_each(). It can be used more than once
* per walk, but only once per item. Example below:
*
* Filter out all items from dictionary whose key does not begin with "foo".
*
* ben_dict_for_each(key, value, pos, dict) {
* if (strncmp(ben_str_val(key), "foo", 3) != 0)
* ben_free(ben_dict_pop_current(dict, &pos));
* }
*/
struct bencode *ben_dict_pop_current(struct bencode *dict, size_t *pos);
/* Report an error while decoding. Returns NULL. */
void *ben_insufficient_ptr(struct ben_decode_ctx *ctx);
void *ben_invalid_ptr(struct ben_decode_ctx *ctx);
void *ben_oom_ptr(struct ben_decode_ctx *ctx);
/*
* Decode from the current position of 'ctx'.
*
* This function is used to implement decoders for user-defined types.
*/
struct bencode *ben_ctx_decode(struct ben_decode_ctx *ctx);
/*
* Test whether the input of 'ctx' has at least n bytes left.
* Returns 0 when there is enough bytes left and -1 when there isn't.
*
* This function is used to implement decoders for user-defined types.
*/
int ben_need_bytes(const struct ben_decode_ctx *ctx, size_t n);
/*
* Returns the character in current position of 'ctx'.
*
* This function is used to implement decoders for user-defined types.
*/
char ben_current_char(const struct ben_decode_ctx *ctx);
/*
* Get the next n bytes from input.
* Returns pointer to the data or NULL when there aren't enough bytes left.
*
* This function is used to implement decoders for user-defined types.
*/
const char *ben_current_buf(const struct ben_decode_ctx *ctx, size_t n);
/*
* Increments current position by n.
*
* This function is used to implement decoders for user-defined types.
*/
void ben_skip(struct ben_decode_ctx *ctx, size_t n);
/*
* Encode to the output of 'ctx'. The size of the encoded data can be obtained
* with ben_encoded_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_ctx_encode(struct ben_encode_ctx *ctx, const struct bencode *b);
/*
* Append one character to output of 'ctx'. The amount of bytes written to the
* output must be the same as returned by get_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_put_char(struct ben_encode_ctx *ctx, char c);
/*
* Append data to output of 'ctx'. The amount of bytes written to the output
* must be the same as returned by get_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_put_buffer(struct ben_encode_ctx *ctx, const void *buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,447 +0,0 @@
#ifndef KS_DHT_INT_H
#define KS_DHT_INT_H
#include "ks.h"
KS_BEGIN_EXTERN_C
/**
* Determines the appropriate endpoint to reach a remote address.
* If an endpoint is provided, nothing more needs to be done.
* If no endpoint is provided, first it will check for an active endpoint it can route though.
* If no active endpoint is available and autorouting is enabled it will attempt to bind a usable endpoint.
* @param dht pointer to the dht instance
* @param raddr pointer to the remote address
* @param endpoint dereferenced in/out pointer to the endpoint, if populated then returns immediately
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
* @see ks_ip_route
* @see ks_hash_read_unlock
* @see ks_addr_set
* @see ks_dht_bind
*/
KS_DECLARE(ks_status_t) ks_dht_autoroute_check(ks_dht_t *dht, const ks_sockaddr_t *raddr, ks_dht_endpoint_t **endpoint);
/**
* Called internally to receive datagrams from endpoints.
* Handles datagrams by dispatching each through a threadpool.
* @param dht pointer to the dht instance
* @param timeout time in ms to wait for an incoming datagram on any endpoint
*/
KS_DECLARE(void) ks_dht_pulse_endpoints(ks_dht_t *dht, int32_t timeout);
/**
* Called internally to expire or reannounce storage item data.
* Handles reannouncing and purging of expiring storage items.
* @param dht pointer to the dht instance
*/
KS_DECLARE(void) ks_dht_pulse_storageitems(ks_dht_t *dht);
/**
* Called internally to process job state machine.
* Handles completing and purging of finished jobs.
* @param dht pointer to the dht instance
*/
KS_DECLARE(void) ks_dht_pulse_jobs(ks_dht_t *dht);
/**
* Called internally to send queued messages.
* Handles throttling of message sending to ensure system buffers are not overloaded and messages are not dropped.
* @param dht pointer to the dht instance
*/
KS_DECLARE(void) ks_dht_pulse_send(ks_dht_t *dht);
/**
* Called internally to expire transactions.
* Handles purging of expired and finished transactions.
* @param dht pointer to the dht instance
*/
KS_DECLARE(void) ks_dht_pulse_transactions(ks_dht_t *dht);
/**
* Called internally to expire and cycle tokens.
* Handles cycling new secret entropy for token generation.
* @param dht pointer to the dht instance
*/
KS_DECLARE(void) ks_dht_pulse_tokens(ks_dht_t *dht);
/**
* Converts a ks_dht_nodeid_t into it's hex string representation.
* @param id pointer to the nodeid
* @param buffer pointer to the buffer able to contain at least (KS_DHT_NODEID_SIZE * 2) + 1 characters
* @return The pointer to the front of the populated string buffer
*/
KS_DECLARE(char *) ks_dht_hex(const uint8_t *data, char *buffer, ks_size_t len);
/**
* Compacts address information as per the DHT specifications.
* @param address pointer to the address being compacted from
* @param buffer pointer to the buffer containing compacted data
* @param buffer_length pointer to the buffer length consumed
* @param buffer_size max size of the buffer
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM
*/
KS_DECLARE(ks_status_t) ks_dht_utility_compact_addressinfo(const ks_sockaddr_t *address,
uint8_t *buffer,
ks_size_t *buffer_length,
ks_size_t buffer_size);
/**
* Expands address information as per the DHT specifications.
* @param buffer pointer to the buffer containing compacted data
* @param buffer_length pointer to the buffer length consumed
* @param buffer_size max size of the buffer
* @param address pointer to the address being expanded into
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
* @see ks_addr_set_raw
*/
KS_DECLARE(ks_status_t) ks_dht_utility_expand_addressinfo(const uint8_t *buffer,
ks_size_t *buffer_length,
ks_size_t buffer_size,
ks_sockaddr_t *address);
/**
* Compacts node information as per the DHT specifications.
* Compacts address information after the nodeid.
* @param nodeid pointer to the nodeid being compacted from
* @param address pointer to the address being compacted from
* @param buffer pointer to the buffer containing compacted data
* @param buffer_length pointer to the buffer length consumed
* @param buffer_size max size of the buffer
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
* @see ks_dht_utility_compact_addressinfo
*/
KS_DECLARE(ks_status_t) ks_dht_utility_compact_nodeinfo(const ks_dht_nodeid_t *nodeid,
const ks_sockaddr_t *address,
uint8_t *buffer,
ks_size_t *buffer_length,
ks_size_t buffer_size);
/**
* Expands address information as per the DHT specifications.
* Expands compacted address information after the nodeid.
* @param buffer pointer to the buffer containing compacted data
* @param buffer_length pointer to the buffer length consumed
* @param buffer_size max size of the buffer
* @param address pointer to the address being expanded into
* @param nodeid pointer to the nodeid being expanded into
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM, ...
* @see ks_dht_utility_expand_addressinfo
*/
KS_DECLARE(ks_status_t) ks_dht_utility_expand_nodeinfo(const uint8_t *buffer,
ks_size_t *buffer_length,
ks_size_t buffer_size,
ks_dht_nodeid_t *nodeid,
ks_sockaddr_t *address);
/**
* Extracts a ks_dht_nodeid_t from a bencode dictionary given a string key.
* @param args pointer to the bencode dictionary
* @param key string key in the bencode dictionary to extract the value from
* @param nodeid dereferenced out pointer to the nodeid
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_ARG_INVALID
*/
KS_DECLARE(ks_status_t) ks_dht_utility_extract_nodeid(struct bencode *args, const char *key, ks_dht_nodeid_t **nodeid);
/**
* Extracts a ks_dht_token_t from a bencode dictionary given a string key.
* @param args pointer to the bencode dictionary
* @param key string key in the bencode dictionary to extract the value from
* @param nodeid dereferenced out pointer to the token
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_ARG_INVALID
*/
KS_DECLARE(ks_status_t) ks_dht_utility_extract_token(struct bencode *args, const char *key, ks_dht_token_t **token);
/**
* Generates an opaque write token based on a shifting secret value, the remote address and target nodeid of interest.
* This token ensures that future operations can be verified to the remote peer and target id requested.
* @param secret rotating secret portion of the token hash
* @param raddr pointer to the remote address used for the ip and port in the token hash
* @param target pointer to the nodeid of the target used for the token hash
* @param token pointer to the output token being generated
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_FAIL
*/
KS_DECLARE(ks_status_t) ks_dht_token_generate(uint32_t secret, const ks_sockaddr_t *raddr, ks_dht_nodeid_t *target, ks_dht_token_t *token);
/**
* Verify an opaque write token matches the provided remote address and target nodeid.
* Handles checking against the last two secret values for the token hash.
* @param dht pointer to the dht instance
* @param raddr pointer to the remote address used for the ip and port in the token hash
* @param target pointer to the nodeid of the target used for the token hash
* @param token pointer to the input token being compared
* @return Either KS_TRUE if verification passes, otherwise KS_FALSE
*/
KS_DECLARE(ks_bool_t) ks_dht_token_verify(ks_dht_t *dht, const ks_sockaddr_t *raddr, ks_dht_nodeid_t *target, ks_dht_token_t *token);
/**
* Encodes a message for transmission as a UDP datagram and sends it.
* Uses the internally tracked local endpoint and remote address to route the UDP datagram.
* @param dht pointer to the dht instance
* @param message pointer to the message being sent
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
* @see ks_socket_sendto
*/
KS_DECLARE(ks_status_t) ks_dht_send(ks_dht_t *dht, ks_dht_message_t *message);
/**
* Sets up the common parts of a query message.
* Determines the local endpoint aware of autorouting, assigns the remote address, generates a transaction, and queues a callback.
* @param dht pointer to the dht instance
* @param job pointer to the job
* @param query string value of the query type, for example "ping"
* @param callback callback to be called when response to transaction is received
* @param transaction dereferenced out pointer to the allocated transaction, may be NULL to ignore output
* @param message dereferenced out pointer to the allocated message
* @param args dereferenced out pointer to the allocated bencode args, may be NULL to ignore output
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_FAIL, ...
* @see ks_dht_autoroute_check
* @see ks_dht_transaction_alloc
* @see ks_dht_transaction_init
* @see ks_dht_message_alloc
* @see ks_dht_message_init
* @see ks_dht_message_query
* @see ks_hash_insert
*/
KS_DECLARE(ks_status_t) ks_dht_query_setup(ks_dht_t *dht,
ks_dht_job_t *job,
const char *query,
ks_dht_job_callback_t callback,
ks_dht_transaction_t **transaction,
ks_dht_message_t **message,
struct bencode **args);
/**
* Sets up the common parts of a response message.
* Determines the local endpoint aware of autorouting, assigns the remote address, and assigns the transaction.
* @param dht pointer to the dht instance
* @param ep pointer to the endpoint, may be NULL to find an endpoint or autoroute one
* @param raddr pointer to the remote address
* @param transactionid pointer to the buffer containing the transactionid, may be of variable size depending on the querying node
* @param transactionid_length length of the transactionid buffer
* @param message dereferenced out pointer to the allocated message
* @param args dereferenced out pointer to the allocated bencode args, may be NULL to ignore output
* @return The ks_status_t result: KS_STATUS_SUCCESS, ...
* @see ks_dht_autoroute_check
* @see ks_dht_message_alloc
* @see ks_dht_message_init
* @see ks_dht_message_response
*/
KS_DECLARE(ks_status_t) ks_dht_response_setup(ks_dht_t *dht,
ks_dht_endpoint_t *ep,
const ks_sockaddr_t *raddr,
uint8_t *transactionid,
ks_size_t transactionid_length,
ks_dht_message_t **message,
struct bencode **args);
KS_DECLARE(ks_status_t) ks_dht_error(ks_dht_t *dht,
ks_dht_endpoint_t *ep,
const ks_sockaddr_t *raddr,
uint8_t *transactionid,
ks_size_t transactionid_length,
long long errorcode,
const char *errorstr);
KS_DECLARE(void) ks_dht_pulse_jobs(ks_dht_t *dht);
KS_DECLARE(ks_status_t) ks_dht_query_ping(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_query_findnode(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_query_get(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_query_put(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(void *)ks_dht_process(ks_thread_t *thread, void *data);
KS_DECLARE(ks_status_t) ks_dht_process_query(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_response(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_error(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_query_ping(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_response_ping(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_process_query_findnode(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_response_findnode(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_process_query_get(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_response_get(ks_dht_t *dht, ks_dht_job_t *job);
KS_DECLARE(ks_status_t) ks_dht_process_query_put(ks_dht_t *dht, ks_dht_message_t *message);
KS_DECLARE(ks_status_t) ks_dht_process_response_put(ks_dht_t *dht, ks_dht_job_t *job);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_datagram_create(ks_dht_datagram_t **datagram,
ks_pool_t *pool,
ks_dht_t *dht,
ks_dht_endpoint_t *endpoint,
const ks_sockaddr_t *raddr);
KS_DECLARE(void) ks_dht_datagram_destroy(ks_dht_datagram_t **datagram);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_job_create(ks_dht_job_t **job,
ks_pool_t *pool,
const ks_sockaddr_t *raddr,
int32_t attempts,
void *data);
KS_DECLARE(void) ks_dht_job_build_ping(ks_dht_job_t *job, ks_dht_job_callback_t query_callback, ks_dht_job_callback_t finish_callback);
KS_DECLARE(void) ks_dht_job_build_findnode(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_nodeid_t *target);
KS_DECLARE(void) ks_dht_job_build_get(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_nodeid_t *target,
const uint8_t *salt,
ks_size_t salt_length);
KS_DECLARE(void) ks_dht_job_build_put(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback,
ks_dht_token_t *token,
int64_t cas,
ks_dht_storageitem_t *item);
KS_DECLARE(void) ks_dht_job_build_search(ks_dht_job_t *job,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback);
KS_DECLARE(void) ks_dht_job_build_search_findnode(ks_dht_job_t *job,
ks_dht_nodeid_t *target,
uint32_t family,
ks_dht_job_callback_t query_callback,
ks_dht_job_callback_t finish_callback);
KS_DECLARE(void) ks_dht_job_destroy(ks_dht_job_t **job);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_endpoint_create(ks_dht_endpoint_t **endpoint,
ks_pool_t *pool,
const ks_sockaddr_t *addr,
ks_socket_t sock);
KS_DECLARE(void) ks_dht_endpoint_destroy(ks_dht_endpoint_t **endpoint);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_message_create(ks_dht_message_t **message,
ks_pool_t *pool,
ks_dht_endpoint_t *endpoint,
const ks_sockaddr_t *raddr,
ks_bool_t alloc_data);
/**
*
*/
KS_DECLARE(void) ks_dht_message_destroy(ks_dht_message_t **message);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_message_parse(ks_dht_message_t *message, const uint8_t *buffer, ks_size_t buffer_length);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_search_create(ks_dht_search_t **search,
ks_pool_t *pool,
ks_dhtrt_routetable_t *table,
const ks_dht_nodeid_t *target,
ks_dht_job_callback_t callback,
void *data);
KS_DECLARE(void) ks_dht_search_destroy(ks_dht_search_t **search);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_publish_create(ks_dht_publish_t **publish,
ks_pool_t *pool,
ks_dht_job_callback_t callback,
void *data,
int64_t cas,
ks_dht_storageitem_t *item);
KS_DECLARE(void) ks_dht_publish_destroy(ks_dht_publish_t **publish);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_distribute_create(ks_dht_distribute_t **distribute,
ks_pool_t *pool,
ks_dht_storageitem_callback_t callback,
void *data,
int64_t cas,
ks_dht_storageitem_t *item);
KS_DECLARE(void) ks_dht_distribute_destroy(ks_dht_distribute_t **distribute);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_immutable_internal(struct bencode *value, ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_mutable_internal(ks_dht_storageitem_pkey_t *pk, struct bencode *salt, ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable_internal(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
struct bencode *v,
ks_bool_t clone_v);
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_immutable(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
const uint8_t *value,
ks_size_t value_length);
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable_internal(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
struct bencode *v,
ks_bool_t clone_v,
ks_dht_storageitem_pkey_t *pk,
struct bencode *salt,
ks_bool_t clone_salt,
int64_t sequence,
ks_dht_storageitem_signature_t *signature);
KS_DECLARE(ks_status_t) ks_dht_storageitem_create_mutable(ks_dht_storageitem_t **item,
ks_pool_t *pool,
ks_dht_nodeid_t *target,
const uint8_t *value,
ks_size_t value_length,
ks_dht_storageitem_pkey_t *pk,
const uint8_t *salt,
ks_size_t salt_length,
int64_t sequence,
ks_dht_storageitem_signature_t *signature);
KS_DECLARE(void) ks_dht_storageitem_update_mutable(ks_dht_storageitem_t *item, struct bencode *v, int64_t sequence, ks_dht_storageitem_signature_t *signature);
KS_DECLARE(void) ks_dht_storageitem_destroy(ks_dht_storageitem_t **item);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_transaction_create(ks_dht_transaction_t **transaction,
ks_pool_t *pool,
ks_dht_job_t *job,
uint32_t transactionid,
ks_dht_job_callback_t callback);
KS_DECLARE(void) ks_dht_transaction_destroy(ks_dht_transaction_t **transaction);
KS_END_EXTERN_C
#endif /* KS_DHT_INT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,596 +0,0 @@
#ifndef KS_DHT_H
#define KS_DHT_H
#include "ks.h"
#include "ks_bencode.h"
#include "sodium.h"
KS_BEGIN_EXTERN_C
#define KS_DHT_DEFAULT_PORT 5309
#define KS_DHT_TPOOL_MIN 2
#define KS_DHT_TPOOL_MAX 8
#define KS_DHT_TPOOL_STACK (1024 * 256)
#define KS_DHT_TPOOL_IDLE 10
#define KS_DHT_DATAGRAM_BUFFER_SIZE 1000
//#define KS_DHT_RECV_BUFFER_SIZE 0xFFFF
#define KS_DHT_NODEID_SIZE 20
#define KS_DHT_RESPONSE_NODES_MAX_SIZE 8
#define KS_DHT_MESSAGE_TRANSACTIONID_MAX_SIZE 20
#define KS_DHT_MESSAGE_TYPE_MAX_SIZE 20
#define KS_DHT_MESSAGE_QUERY_MAX_SIZE 20
#define KS_DHT_MESSAGE_ERROR_MAX_SIZE 256
#define KS_DHT_TRANSACTION_EXPIRATION 10
#define KS_DHT_TRANSACTIONS_PULSE 1
#define KS_DHT_SEARCH_RESULTS_MAX_SIZE 8 // @todo replace with KS_DHTRT_BUCKET_SIZE
#define KS_DHT_STORAGEITEM_PKEY_SIZE crypto_sign_PUBLICKEYBYTES
#define KS_DHT_STORAGEITEM_SKEY_SIZE crypto_sign_SECRETKEYBYTES
#define KS_DHT_STORAGEITEM_SALT_MAX_SIZE 64
#define KS_DHT_STORAGEITEM_SIGNATURE_SIZE crypto_sign_BYTES
#define KS_DHT_STORAGEITEM_EXPIRATION 7200
#define KS_DHT_STORAGEITEM_KEEPALIVE 300
#define KS_DHT_STORAGEITEMS_PULSE 10
#define KS_DHT_TOKEN_SIZE SHA_DIGEST_LENGTH
#define KS_DHT_TOKEN_EXPIRATION 300
#define KS_DHT_TOKENS_PULSE 1
#define KS_DHTRT_MAXQUERYSIZE 20
typedef struct ks_dht_s ks_dht_t;
typedef struct ks_dht_datagram_s ks_dht_datagram_t;
typedef struct ks_dht_job_s ks_dht_job_t;
typedef struct ks_dht_nodeid_s ks_dht_nodeid_t;
typedef struct ks_dht_token_s ks_dht_token_t;
typedef struct ks_dht_storageitem_pkey_s ks_dht_storageitem_pkey_t;
typedef struct ks_dht_storageitem_skey_s ks_dht_storageitem_skey_t;
typedef struct ks_dht_storageitem_signature_s ks_dht_storageitem_signature_t;
typedef struct ks_dht_message_s ks_dht_message_t;
typedef struct ks_dht_endpoint_s ks_dht_endpoint_t;
typedef struct ks_dht_transaction_s ks_dht_transaction_t;
typedef struct ks_dht_search_s ks_dht_search_t;
typedef struct ks_dht_publish_s ks_dht_publish_t;
typedef struct ks_dht_distribute_s ks_dht_distribute_t;
typedef struct ks_dht_node_s ks_dht_node_t;
typedef struct ks_dhtrt_routetable_s ks_dhtrt_routetable_t;
typedef struct ks_dhtrt_querynodes_s ks_dhtrt_querynodes_t;
typedef struct ks_dht_storageitem_s ks_dht_storageitem_t;
typedef ks_status_t (*ks_dht_job_callback_t)(ks_dht_t *dht, ks_dht_job_t *job);
typedef ks_status_t (*ks_dht_message_callback_t)(ks_dht_t *dht, ks_dht_message_t *message);
//typedef ks_status_t (*ks_dht_search_callback_t)(ks_dht_t *dht, ks_dht_search_t *search);
typedef ks_status_t (*ks_dht_storageitem_callback_t)(ks_dht_t *dht, ks_dht_storageitem_t *item);
struct ks_dht_datagram_s {
ks_pool_t *pool;
ks_dht_t *dht;
ks_dht_endpoint_t *endpoint;
ks_sockaddr_t raddr;
uint8_t buffer[KS_DHT_DATAGRAM_BUFFER_SIZE];
ks_size_t buffer_length;
};
/**
* Note: This must remain a structure for casting from raw data
*/
struct ks_dht_nodeid_s {
uint8_t id[KS_DHT_NODEID_SIZE];
};
enum ks_afflags_t { ifv4=AF_INET, ifv6=AF_INET6, ifboth=AF_INET+AF_INET6};
enum ks_dht_nodetype_t { KS_DHT_REMOTE=0x01,
KS_DHT_LOCAL=0x02,
KS_DHT_BOTH=KS_DHT_REMOTE+KS_DHT_LOCAL };
enum ks_create_node_flags_t {
KS_DHTRT_CREATE_DEFAULT=0,
KS_DHTRT_CREATE_PING,
KS_DHTRT_CREATE_TOUCH
};
struct ks_dht_node_s {
ks_dht_nodeid_t nodeid;
ks_sockaddr_t addr;
enum ks_dht_nodetype_t type; /* local or remote */
ks_dhtrt_routetable_t* table;
ks_rwl_t *reflock;
};
struct ks_dht_token_s {
uint8_t token[KS_DHT_TOKEN_SIZE];
};
enum ks_dht_job_state_t {
KS_DHT_JOB_STATE_QUERYING,
KS_DHT_JOB_STATE_RESPONDING,
KS_DHT_JOB_STATE_EXPIRING,
KS_DHT_JOB_STATE_COMPLETING,
};
enum ks_dht_job_result_t {
KS_DHT_JOB_RESULT_SUCCESS = 0,
KS_DHT_JOB_RESULT_EXPIRED,
KS_DHT_JOB_RESULT_ERROR,
KS_DHT_JOB_RESULT_FAILURE,
};
struct ks_dht_job_s {
ks_pool_t *pool;
ks_dht_t *dht;
ks_dht_job_t *next;
enum ks_dht_job_state_t state;
enum ks_dht_job_result_t result;
ks_sockaddr_t raddr; // will obtain local endpoint node id when creating message using raddr
int32_t attempts;
//enum ks_dht_job_type_t type;
ks_dht_job_callback_t query_callback;
ks_dht_job_callback_t finish_callback;
void *data;
ks_dht_message_t *response;
// job specific query parameters
ks_dht_nodeid_t query_target;
struct bencode *query_salt;
int64_t query_cas;
ks_dht_token_t query_token;
ks_dht_storageitem_t *query_storageitem;
// error response parameters
int64_t error_code;
struct bencode *error_description;
// job specific response parameters
ks_dht_node_t *response_id;
ks_dht_node_t *response_nodes[KS_DHT_RESPONSE_NODES_MAX_SIZE];
ks_size_t response_nodes_count;
ks_dht_node_t *response_nodes6[KS_DHT_RESPONSE_NODES_MAX_SIZE];
ks_size_t response_nodes6_count;
ks_dht_token_t response_token;
int64_t response_seq;
ks_bool_t response_hasitem;
ks_dht_storageitem_t *response_storageitem;
};
struct ks_dhtrt_routetable_s {
void* internal;
ks_pool_t* pool;
ks_logger_t logger;
};
struct ks_dhtrt_querynodes_s {
ks_dht_nodeid_t nodeid; /* in: id to query */
enum ks_afflags_t family; /* in: AF_INET or AF_INET6 or both */
enum ks_dht_nodetype_t type; /* remote, local, or both */
uint8_t max; /* in: maximum to return */
uint8_t count; /* out: number returned */
ks_dht_node_t* nodes[ KS_DHTRT_MAXQUERYSIZE ]; /* out: array of peers (ks_dht_node_t* nodes[incount]) */
};
struct ks_dht_storageitem_pkey_s {
uint8_t key[KS_DHT_STORAGEITEM_PKEY_SIZE];
};
struct ks_dht_storageitem_skey_s {
uint8_t key[KS_DHT_STORAGEITEM_SKEY_SIZE];
};
struct ks_dht_storageitem_signature_s {
uint8_t sig[KS_DHT_STORAGEITEM_SIGNATURE_SIZE];
};
struct ks_dht_message_s {
ks_pool_t *pool;
ks_dht_endpoint_t *endpoint;
ks_sockaddr_t raddr;
struct bencode *data;
uint8_t transactionid[KS_DHT_MESSAGE_TRANSACTIONID_MAX_SIZE];
ks_size_t transactionid_length;
ks_dht_transaction_t *transaction;
char type[KS_DHT_MESSAGE_TYPE_MAX_SIZE];
struct bencode *args;
ks_dht_nodeid_t args_id;
};
struct ks_dht_endpoint_s {
ks_pool_t *pool;
ks_sockaddr_t addr;
ks_socket_t sock;
};
struct ks_dht_transaction_s {
ks_pool_t *pool;
ks_dht_job_t *job;
uint32_t transactionid;
//ks_dht_nodeid_t target; // @todo look at moving this into job now
ks_dht_job_callback_t callback;
ks_time_t expiration;
ks_bool_t finished;
};
struct ks_dht_search_s {
ks_pool_t *pool;
ks_dhtrt_routetable_t *table;
ks_dht_nodeid_t target;
ks_dht_job_callback_t callback;
void *data;
ks_mutex_t *mutex;
ks_hash_t *searched;
int32_t searching;
ks_dht_node_t *results[KS_DHT_SEARCH_RESULTS_MAX_SIZE];
ks_dht_nodeid_t distances[KS_DHT_SEARCH_RESULTS_MAX_SIZE];
ks_size_t results_length;
};
struct ks_dht_publish_s {
ks_pool_t *pool;
ks_dht_job_callback_t callback;
void *data;
int64_t cas;
ks_dht_storageitem_t *item;
};
struct ks_dht_distribute_s {
ks_pool_t *pool;
ks_dht_storageitem_callback_t callback;
void *data;
ks_mutex_t *mutex;
int32_t publishing;
int64_t cas;
ks_dht_storageitem_t *item;
};
struct ks_dht_storageitem_s {
ks_pool_t *pool;
ks_dht_nodeid_t id;
ks_time_t expiration;
ks_time_t keepalive;
struct bencode *v;
ks_mutex_t *mutex;
volatile int32_t refc;
ks_dht_storageitem_callback_t callback;
ks_bool_t mutable;
ks_dht_storageitem_pkey_t pk;
ks_dht_storageitem_skey_t sk;
struct bencode *salt;
int64_t seq;
ks_dht_storageitem_signature_t sig;
};
struct ks_dht_s {
ks_pool_t *pool;
ks_bool_t pool_alloc;
ks_thread_pool_t *tpool;
ks_bool_t tpool_alloc;
ks_dht_nodeid_t nodeid;
// @todo make sure this node is unlocked, and never gets destroyed, should also never use local nodes in search results as they can be internal
// network addresses, not what others have contacted through
ks_dht_node_t *node;
ks_bool_t autoroute;
ks_port_t autoroute_port;
ks_hash_t *registry_type;
ks_hash_t *registry_query;
ks_hash_t *registry_error;
ks_dht_endpoint_t **endpoints;
int32_t endpoints_length;
int32_t endpoints_size;
ks_hash_t *endpoints_hash;
struct pollfd *endpoints_poll;
ks_q_t *send_q;
ks_dht_message_t *send_q_unsent;
uint8_t recv_buffer[KS_DHT_DATAGRAM_BUFFER_SIZE + 1]; // Add 1, if we receive it then overflow error
ks_size_t recv_buffer_length;
ks_mutex_t *jobs_mutex;
ks_dht_job_t *jobs_first;
ks_dht_job_t *jobs_last;
ks_time_t transactions_pulse;
ks_mutex_t *transactionid_mutex;
volatile uint32_t transactionid_next;
ks_hash_t *transactions_hash;
ks_dhtrt_routetable_t *rt_ipv4;
ks_dhtrt_routetable_t *rt_ipv6;
ks_time_t tokens_pulse;
volatile uint32_t token_secret_current;
volatile uint32_t token_secret_previous;
ks_time_t token_secret_expiration;
ks_time_t storageitems_pulse;
ks_hash_t *storageitems_hash;
};
/**
* Constructor function for ks_dht_t.
* Will allocate and initialize internal state including registration of message handlers.
* @param dht dereferenced out pointer to the allocated dht instance
* @param pool pointer to the memory pool used by the dht instance, may be NULL to create a new memory pool internally
* @param tpool pointer to a thread pool used by the dht instance, may be NULL to create a new thread pool internally
* @param nodeid pointer to the nodeid for this dht instance
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_NO_MEM
*/
KS_DECLARE(ks_status_t) ks_dht_create(ks_dht_t **dht, ks_pool_t *pool, ks_thread_pool_t *tpool, ks_dht_nodeid_t *nodeid);
/**
* Destructor function for ks_dht_t.
* Will deinitialize and deallocate internal state.
* @param dht dereferenced in/out pointer to the dht instance, NULL upon return
*/
KS_DECLARE(void) ks_dht_destroy(ks_dht_t **dht);
/**
* Enable or disable (default) autorouting support.
* When enabled, autorouting will allow sending to remote addresses on interfaces which are not yet bound.
* The address will be bound with the provided autoroute port when this occurs.
* @param dht pointer to the dht instance
* @param autoroute enable or disable autorouting
* @param port when enabling autorouting this port will be used to bind new addresses, may be 0 to use the default DHT port
*/
KS_DECLARE(void) ks_dht_autoroute(ks_dht_t *dht, ks_bool_t autoroute, ks_port_t port);
/**
* Register a callback for a specific message type.
* Will overwrite any duplicate handlers.
* @param dht pointer to the dht instance
* @param value string of the type text under the 'y' key of a message
* @param callback the callback to be called when a message matches
*/
KS_DECLARE(void) ks_dht_register_type(ks_dht_t *dht, const char *value, ks_dht_message_callback_t callback);
/**
* Register a callback for a specific message query.
* Will overwrite any duplicate handlers.
* @param dht pointer to the dht instance
* @param value string of the type text under the 'q' key of a message
* @param callback the callback to be called when a message matches
*/
KS_DECLARE(void) ks_dht_register_query(ks_dht_t *dht, const char *value, ks_dht_message_callback_t callback);
/**
* Register a callback for a specific message error.
* Will overwrite any duplicate handlers.
* @param dht pointer to the dht instance
* @param value string of the errorcode under the first item of the 'e' key of a message
* @param callback the callback to be called when a message matches
*/
KS_DECLARE(void) ks_dht_register_error(ks_dht_t *dht, const char *value, ks_dht_message_callback_t callback);
/**
* Bind a local address and port for receiving UDP datagrams.
* @param dht pointer to the dht instance
* @param addr pointer to the local address information
* @param endpoint dereferenced out pointer to the allocated endpoint, may be NULL to ignore endpoint output
* @return The ks_status_t result: KS_STATUS_SUCCESS, KS_STATUS_FAIL, ...
* @see ks_socket_option
* @see ks_addr_bind
* @see ks_dht_endpoint_alloc
* @see ks_dht_endpoint_init
* @see ks_hash_insert
* @see ks_dhtrt_initroute
* @see ks_dhtrt_create_node
*/
KS_DECLARE(ks_status_t) ks_dht_bind(ks_dht_t *dht, const ks_sockaddr_t *addr, ks_dht_endpoint_t **endpoint);
/**
* Pulse the internals of dht.
* Handles receiving UDP datagrams, dispatching processing, handles expirations, throttled message sending, route table pulsing, etc.
* @param dht pointer to the dht instance
* @param timeout timeout value used when polling sockets for new UDP datagrams
*/
KS_DECLARE(void) ks_dht_pulse(ks_dht_t *dht, int32_t timeout);
KS_DECLARE(char *) ks_dht_hex(const uint8_t *data, char *buffer, ks_size_t len);
KS_DECLARE(uint8_t *) ks_dht_dehex(uint8_t *data, const char *buffer, ks_size_t len);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_immutable(const uint8_t *value, ks_size_t value_length, ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_target_mutable(ks_dht_storageitem_pkey_t *pk, const uint8_t *salt, ks_size_t salt_length, ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitem_signature_generate(ks_dht_storageitem_signature_t *sig,
ks_dht_storageitem_skey_t *sk,
const uint8_t *salt,
ks_size_t salt_length,
int64_t sequence,
const uint8_t *value,
ks_size_t value_length);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitem_reference(ks_dht_storageitem_t *item);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitem_dereference(ks_dht_storageitem_t *item);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitem_callback(ks_dht_storageitem_t *item, ks_dht_storageitem_callback_t callback);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitems_read_lock(ks_dht_t *dht);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitems_read_unlock(ks_dht_t *dht);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitems_write_lock(ks_dht_t *dht);
/**
*
*/
KS_DECLARE(void) ks_dht_storageitems_write_unlock(ks_dht_t *dht);
/**
*
*/
KS_DECLARE(ks_dht_storageitem_t *) ks_dht_storageitems_find(ks_dht_t *dht, ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(ks_status_t) ks_dht_storageitems_insert(ks_dht_t *dht, ks_dht_storageitem_t *item);
/**
*
*/
KS_DECLARE(void) ks_dht_ping(ks_dht_t *dht, const ks_sockaddr_t *raddr, ks_dht_job_callback_t callback, void *data);
/**
*
*/
KS_DECLARE(void) ks_dht_findnode(ks_dht_t *dht,
const ks_sockaddr_t *raddr,
ks_dht_job_callback_t callback,
void *data,
ks_dht_nodeid_t *target);
/**
*
*/
KS_DECLARE(void) ks_dht_get(ks_dht_t *dht,
const ks_sockaddr_t *raddr,
ks_dht_job_callback_t callback,
void *data,
ks_dht_nodeid_t *target,
const uint8_t *salt,
ks_size_t salt_length);
/**
*
*/
KS_DECLARE(void) ks_dht_put(ks_dht_t *dht,
const ks_sockaddr_t *raddr,
ks_dht_job_callback_t callback,
void *data,
ks_dht_token_t *token,
int64_t cas,
ks_dht_storageitem_t *item);
/**
* Create a network search of the closest nodes to a target.
* @param dht pointer to the dht instance
* @param family either AF_INET or AF_INET6 for the appropriate network to search
* @param target pointer to the nodeid for the target to be searched
* @param callback an optional callback to add to the search when it is finished
* @param search dereferenced out pointer to the allocated search, may be NULL to ignore search output
* @see ks_dht_search_create
* @see ks_hash_insert
* @see ks_dht_findnode
*/
KS_DECLARE(void) ks_dht_search(ks_dht_t *dht,
ks_dht_job_callback_t callback,
void *data,
ks_dhtrt_routetable_t *table,
ks_dht_nodeid_t *target);
KS_DECLARE(void) ks_dht_publish(ks_dht_t *dht,
const ks_sockaddr_t *raddr,
ks_dht_job_callback_t callback,
void *data,
int64_t cas,
ks_dht_storageitem_t *item);
KS_DECLARE(void) ks_dht_distribute(ks_dht_t *dht,
ks_dht_storageitem_callback_t callback,
void *data,
ks_dhtrt_routetable_t *table,
int64_t cas,
ks_dht_storageitem_t *item);
/**
* route table methods
*
*/
KS_DECLARE(ks_status_t) ks_dhtrt_initroute(ks_dhtrt_routetable_t **tableP,
ks_dht_t *dht,
ks_pool_t *pool);
KS_DECLARE(void) ks_dhtrt_deinitroute(ks_dhtrt_routetable_t **table);
KS_DECLARE(ks_status_t) ks_dhtrt_create_node(ks_dhtrt_routetable_t* table,
ks_dht_nodeid_t nodeid,
enum ks_dht_nodetype_t type,
char* ip, unsigned short port,
enum ks_create_node_flags_t flags,
ks_dht_node_t** node);
KS_DECLARE(ks_status_t) ks_dhtrt_delete_node(ks_dhtrt_routetable_t* table, ks_dht_node_t* node);
KS_DECLARE(ks_status_t) ks_dhtrt_touch_node(ks_dhtrt_routetable_t* table, ks_dht_nodeid_t nodeid);
KS_DECLARE(ks_status_t) ks_dhtrt_expire_node(ks_dhtrt_routetable_t* table, ks_dht_nodeid_t nodeid);
KS_DECLARE(uint8_t) ks_dhtrt_findclosest_nodes(ks_dhtrt_routetable_t* table, ks_dhtrt_querynodes_t* query);
KS_DECLARE(ks_dht_node_t*) ks_dhtrt_find_node(ks_dhtrt_routetable_t* table, ks_dht_nodeid_t id);
KS_DECLARE(ks_status_t) ks_dhtrt_sharelock_node(ks_dht_node_t* node);
KS_DECLARE(ks_status_t) ks_dhtrt_release_node(ks_dht_node_t* node);
KS_DECLARE(ks_status_t) ks_dhtrt_release_querynodes(ks_dhtrt_querynodes_t* query);
KS_DECLARE(void) ks_dhtrt_process_table(ks_dhtrt_routetable_t* table);
KS_DECLARE(uint32_t) ks_dhtrt_serialize(ks_dhtrt_routetable_t* table, void** ptr);
KS_DECLARE(ks_status_t) ks_dhtrt_deserialize(ks_dhtrt_routetable_t* table, void* ptr);
/* debugging aids */
KS_DECLARE(void) ks_dhtrt_dump(ks_dhtrt_routetable_t* table, int level);
KS_END_EXTERN_C
#endif /* KS_DHT_H */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,950 +0,0 @@
/* This file was automatically generated. Do not edit (Except for compile time directives)! */
#ifndef _UNQLITE_H_
#define _UNQLITE_H_
/*
* Symisc UnQLite: An Embeddable NoSQL (Post Modern) Database Engine.
* Copyright (C) 2012-2016, Symisc Systems http://unqlite.org/
* Version 1.1.7
* For information on licensing, redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES
* please contact Symisc Systems via:
* legal@symisc.net
* licensing@symisc.net
* contact@symisc.net
* or visit:
* http://unqlite.org/licensing.html
*/
/*
* Copyright (C) 2012, 2016 Symisc Systems, S.U.A.R.L [M.I.A.G Mrad Chems Eddine <chm@symisc.net>].
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $SymiscID: unqlite.h v1.2 Win10 2106-12-02 00:04:12 stable <chm@symisc.net> $ */
#include <stdarg.h> /* needed for the definition of va_list */
/*
* Compile time engine version, signature, identification in the symisc source tree
* and copyright notice.
* Each macro have an equivalent C interface associated with it that provide the same
* information but are associated with the library instead of the header file.
* Refer to [unqlite_lib_version()], [unqlite_lib_signature()], [unqlite_lib_ident()] and
* [unqlite_lib_copyright()] for more information.
*/
/*
* The UNQLITE_VERSION C preprocessor macroevaluates to a string literal
* that is the unqlite version in the format "X.Y.Z" where X is the major
* version number and Y is the minor version number and Z is the release
* number.
*/
#define UNQLITE_VERSION "1.1.7"
/*
* The UNQLITE_VERSION_NUMBER C preprocessor macro resolves to an integer
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
* numbers used in [UNQLITE_VERSION].
*/
#define UNQLITE_VERSION_NUMBER 1001007
/*
* The UNQLITE_SIG C preprocessor macro evaluates to a string
* literal which is the public signature of the unqlite engine.
* This signature could be included for example in a host-application
* generated Server MIME header as follows:
* Server: YourWebServer/x.x unqlite/x.x.x \r\n
*/
#define UNQLITE_SIG "unqlite/1.1.7"
/*
* UnQLite identification in the Symisc source tree:
* Each particular check-in of a particular software released
* by symisc systems have an unique identifier associated with it.
* This macro hold the one associated with unqlite.
*/
#define UNQLITE_IDENT "unqlite:b172a1e2c3f62fb35c8e1fb2795121f82356cad6"
/*
* Copyright notice.
* If you have any questions about the licensing situation, please
* visit http://unqlite.org/licensing.html
* or contact Symisc Systems via:
* legal@symisc.net
* licensing@symisc.net
* contact@symisc.net
*/
#define UNQLITE_COPYRIGHT "Copyright (C) Symisc Systems, S.U.A.R.L [Mrad Chems Eddine <chm@symisc.net>] 2012-2016, http://unqlite.org/"
/* Forward declaration to public objects */
typedef struct unqlite_io_methods unqlite_io_methods;
typedef struct unqlite_kv_methods unqlite_kv_methods;
typedef struct unqlite_kv_engine unqlite_kv_engine;
typedef struct jx9_io_stream unqlite_io_stream;
typedef struct jx9_context unqlite_context;
typedef struct jx9_value unqlite_value;
typedef struct unqlite_vfs unqlite_vfs;
typedef struct unqlite_vm unqlite_vm;
typedef struct unqlite unqlite;
/*
* ------------------------------
* Compile time directives
* ------------------------------
* For most purposes, UnQLite can be built just fine using the default compilation options.
* However, if required, the compile-time options documented below can be used to omit UnQLite
* features (resulting in a smaller compiled library size) or to change the default values
* of some parameters.
* Every effort has been made to ensure that the various combinations of compilation options
* work harmoniously and produce a working library.
*
* UNQLITE_ENABLE_THREADS
* This option controls whether or not code is included in UnQLite to enable it to operate
* safely in a multithreaded environment. The default is not. All mutexing code is omitted
* and it is unsafe to use UnQLite in a multithreaded program. When compiled with the
* UNQLITE_ENABLE_THREADS directive enabled, UnQLite can be used in a multithreaded program
* and it is safe to share the same virtual machine and engine handle between two or more threads.
* The value of UNQLITE_ENABLE_THREADS can be determined at run-time using the unqlite_lib_is_threadsafe()
* interface.
* When UnQLite has been compiled with threading support then the threading mode can be altered
* at run-time using the unqlite_lib_config() interface together with one of these verbs:
* UNQLITE_LIB_CONFIG_THREAD_LEVEL_SINGLE
* UNQLITE_LIB_CONFIG_THREAD_LEVEL_MULTI
* Platforms others than Windows and UNIX systems must install their own mutex subsystem via
* unqlite_lib_config() with a configuration verb set to UNQLITE_LIB_CONFIG_USER_MUTEX.
* Otherwise the library is not threadsafe.
* Note that you must link UnQLite with the POSIX threads library under UNIX systems (i.e: -lpthread).
*
* Options To Omit/Enable Features
*
* The following options can be used to reduce the size of the compiled library by omitting optional
* features. This is probably only useful in embedded systems where space is especially tight, as even
* with all features included the UnQLite library is relatively small. Don't forget to tell your
* compiler to optimize for binary size! (the -Os option if using GCC). Telling your compiler
* to optimize for size usually has a much larger impact on library footprint than employing
* any of these compile-time options.
*
* JX9_DISABLE_BUILTIN_FUNC
* Jx9 is shipped with more than 312 built-in functions suitable for most purposes like
* string and INI processing, ZIP extracting, Base64 encoding/decoding, JSON encoding/decoding
* and so forth.
* If this directive is enabled, then all built-in Jx9 functions are omitted from the build.
* Note that special functions such as db_create(), db_store(), db_fetch(), etc. are not omitted
* from the build and are not affected by this directive.
*
* JX9_ENABLE_MATH_FUNC
* If this directive is enabled, built-in math functions such as sqrt(), abs(), log(), ceil(), etc.
* are included in the build. Note that you may need to link UnQLite with the math library in same
* Linux/BSD flavor (i.e: -lm).
*
* JX9_DISABLE_DISK_IO
* If this directive is enabled, built-in VFS functions such as chdir(), mkdir(), chroot(), unlink(),
* sleep(), etc. are omitted from the build.
*
* UNQLITE_ENABLE_JX9_HASH_IO
* If this directive is enabled, built-in hash functions such as md5(), sha1(), md5_file(), crc32(), etc.
* are included in the build.
*/
/* Symisc public definitions */
#if !defined(SYMISC_STANDARD_DEFS)
#define SYMISC_STANDARD_DEFS
#if defined (_WIN32) || defined (WIN32) || defined(__MINGW32__) || defined (_MSC_VER) || defined (_WIN32_WCE)
/* Windows Systems */
#if !defined(__WINNT__)
#define __WINNT__
#endif
/*
* Determine if we are dealing with WindowsCE - which has a much
* reduced API.
*/
#if defined(_WIN32_WCE)
#ifndef __WIN_CE__
#define __WIN_CE__
#endif /* __WIN_CE__ */
#endif /* _WIN32_WCE */
#else
/*
* By default we will assume that we are compiling on a UNIX systems.
* Otherwise the OS_OTHER directive must be defined.
*/
#if !defined(OS_OTHER)
#if !defined(__UNIXES__)
#define __UNIXES__
#endif /* __UNIXES__ */
#else
#endif /* OS_OTHER */
#endif /* __WINNT__/__UNIXES__ */
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef signed __int64 sxi64; /* 64 bits(8 bytes) signed int64 */
typedef unsigned __int64 sxu64; /* 64 bits(8 bytes) unsigned int64 */
#else
typedef signed long long int sxi64; /* 64 bits(8 bytes) signed int64 */
typedef unsigned long long int sxu64; /* 64 bits(8 bytes) unsigned int64 */
#endif /* _MSC_VER */
/* Signature of the consumer routine */
typedef int (*ProcConsumer)(const void *, unsigned int, void *);
/* Forward reference */
typedef struct SyMutexMethods SyMutexMethods;
typedef struct SyMemMethods SyMemMethods;
typedef struct SyString SyString;
typedef struct syiovec syiovec;
typedef struct SyMutex SyMutex;
typedef struct Sytm Sytm;
/* Scatter and gather array. */
struct syiovec
{
#if defined (__WINNT__)
/* Same fields type and offset as WSABUF structure defined one winsock2 header */
unsigned long nLen;
char *pBase;
#else
void *pBase;
unsigned long nLen;
#endif
};
struct SyString
{
const char *zString; /* Raw string (may not be null terminated) */
unsigned int nByte; /* Raw string length */
};
/* Time structure. */
struct Sytm
{
int tm_sec; /* seconds (0 - 60) */
int tm_min; /* minutes (0 - 59) */
int tm_hour; /* hours (0 - 23) */
int tm_mday; /* day of month (1 - 31) */
int tm_mon; /* month of year (0 - 11) */
int tm_year; /* year + 1900 */
int tm_wday; /* day of week (Sunday = 0) */
int tm_yday; /* day of year (0 - 365) */
int tm_isdst; /* is summer time in effect? */
char *tm_zone; /* abbreviation of timezone name */
long tm_gmtoff; /* offset from UTC in seconds */
};
/* Convert a tm structure (struct tm *) found in <time.h> to a Sytm structure */
#define STRUCT_TM_TO_SYTM(pTM, pSYTM) \
(pSYTM)->tm_hour = (pTM)->tm_hour;\
(pSYTM)->tm_min = (pTM)->tm_min;\
(pSYTM)->tm_sec = (pTM)->tm_sec;\
(pSYTM)->tm_mon = (pTM)->tm_mon;\
(pSYTM)->tm_mday = (pTM)->tm_mday;\
(pSYTM)->tm_year = (pTM)->tm_year + 1900;\
(pSYTM)->tm_yday = (pTM)->tm_yday;\
(pSYTM)->tm_wday = (pTM)->tm_wday;\
(pSYTM)->tm_isdst = (pTM)->tm_isdst;\
(pSYTM)->tm_gmtoff = 0;\
(pSYTM)->tm_zone = 0;
/* Convert a SYSTEMTIME structure (LPSYSTEMTIME: Windows Systems only ) to a Sytm structure */
#define SYSTEMTIME_TO_SYTM(pSYSTIME, pSYTM) \
(pSYTM)->tm_hour = (pSYSTIME)->wHour;\
(pSYTM)->tm_min = (pSYSTIME)->wMinute;\
(pSYTM)->tm_sec = (pSYSTIME)->wSecond;\
(pSYTM)->tm_mon = (pSYSTIME)->wMonth - 1;\
(pSYTM)->tm_mday = (pSYSTIME)->wDay;\
(pSYTM)->tm_year = (pSYSTIME)->wYear;\
(pSYTM)->tm_yday = 0;\
(pSYTM)->tm_wday = (pSYSTIME)->wDayOfWeek;\
(pSYTM)->tm_gmtoff = 0;\
(pSYTM)->tm_isdst = -1;\
(pSYTM)->tm_zone = 0;
/* Dynamic memory allocation methods. */
struct SyMemMethods
{
void * (*xAlloc)(unsigned int); /* [Required:] Allocate a memory chunk */
void * (*xRealloc)(void *, unsigned int); /* [Required:] Re-allocate a memory chunk */
void (*xFree)(void *); /* [Required:] Release a memory chunk */
unsigned int (*xChunkSize)(void *); /* [Optional:] Return chunk size */
int (*xInit)(void *); /* [Optional:] Initialization callback */
void (*xRelease)(void *); /* [Optional:] Release callback */
void *pUserData; /* [Optional:] First argument to xInit() and xRelease() */
};
/* Out of memory callback signature. */
typedef int (*ProcMemError)(void *);
/* Mutex methods. */
struct SyMutexMethods
{
int (*xGlobalInit)(void); /* [Optional:] Global mutex initialization */
void (*xGlobalRelease)(void); /* [Optional:] Global Release callback () */
SyMutex * (*xNew)(int); /* [Required:] Request a new mutex */
void (*xRelease)(SyMutex *); /* [Optional:] Release a mutex */
void (*xEnter)(SyMutex *); /* [Required:] Enter mutex */
int (*xTryEnter)(SyMutex *); /* [Optional:] Try to enter a mutex */
void (*xLeave)(SyMutex *); /* [Required:] Leave a locked mutex */
};
#if defined (_MSC_VER) || defined (__MINGW32__) || defined (__GNUC__) && defined (__declspec)
#define SX_APIIMPORT __declspec(dllimport)
#define SX_APIEXPORT __declspec(dllexport)
#else
#define SX_APIIMPORT
#define SX_APIEXPORT
#endif
/* Standard return values from Symisc public interfaces */
#define SXRET_OK 0 /* Not an error */
#define SXERR_MEM (-1) /* Out of memory */
#define SXERR_IO (-2) /* IO error */
#define SXERR_EMPTY (-3) /* Empty field */
#define SXERR_LOCKED (-4) /* Locked operation */
#define SXERR_ORANGE (-5) /* Out of range value */
#define SXERR_NOTFOUND (-6) /* Item not found */
#define SXERR_LIMIT (-7) /* Limit reached */
#define SXERR_MORE (-8) /* Need more input */
#define SXERR_INVALID (-9) /* Invalid parameter */
#define SXERR_ABORT (-10) /* User callback request an operation abort */
#define SXERR_EXISTS (-11) /* Item exists */
#define SXERR_SYNTAX (-12) /* Syntax error */
#define SXERR_UNKNOWN (-13) /* Unknown error */
#define SXERR_BUSY (-14) /* Busy operation */
#define SXERR_OVERFLOW (-15) /* Stack or buffer overflow */
#define SXERR_WILLBLOCK (-16) /* Operation will block */
#define SXERR_NOTIMPLEMENTED (-17) /* Operation not implemented */
#define SXERR_EOF (-18) /* End of input */
#define SXERR_PERM (-19) /* Permission error */
#define SXERR_NOOP (-20) /* No-op */
#define SXERR_FORMAT (-21) /* Invalid format */
#define SXERR_NEXT (-22) /* Not an error */
#define SXERR_OS (-23) /* System call return an error */
#define SXERR_CORRUPT (-24) /* Corrupted pointer */
#define SXERR_CONTINUE (-25) /* Not an error: Operation in progress */
#define SXERR_NOMATCH (-26) /* No match */
#define SXERR_RESET (-27) /* Operation reset */
#define SXERR_DONE (-28) /* Not an error */
#define SXERR_SHORT (-29) /* Buffer too short */
#define SXERR_PATH (-30) /* Path error */
#define SXERR_TIMEOUT (-31) /* Timeout */
#define SXERR_BIG (-32) /* Too big for processing */
#define SXERR_RETRY (-33) /* Retry your call */
#define SXERR_IGNORE (-63) /* Ignore */
#endif /* SYMISC_PUBLIC_DEFS */
/*
* Marker for exported interfaces.
*/
#define UNQLITE_APIEXPORT SX_APIEXPORT
/*
* If compiling for a processor that lacks floating point
* support, substitute integer for floating-point.
*/
#ifdef UNQLITE_OMIT_FLOATING_POINT
typedef sxi64 uqlite_real;
#else
typedef double unqlite_real;
#endif
typedef sxi64 unqlite_int64;
/* Standard UnQLite return values */
#define UNQLITE_OK SXRET_OK /* Successful result */
/* Beginning of error codes */
#define UNQLITE_NOMEM SXERR_MEM /* Out of memory */
#define UNQLITE_ABORT SXERR_ABORT /* Another thread have released this instance */
#define UNQLITE_IOERR SXERR_IO /* IO error */
#define UNQLITE_CORRUPT SXERR_CORRUPT /* Corrupt pointer */
#define UNQLITE_LOCKED SXERR_LOCKED /* Forbidden Operation */
#define UNQLITE_BUSY SXERR_BUSY /* The database file is locked */
#define UNQLITE_DONE SXERR_DONE /* Operation done */
#define UNQLITE_PERM SXERR_PERM /* Permission error */
#define UNQLITE_NOTIMPLEMENTED SXERR_NOTIMPLEMENTED /* Method not implemented by the underlying Key/Value storage engine */
#define UNQLITE_NOTFOUND SXERR_NOTFOUND /* No such record */
#define UNQLITE_NOOP SXERR_NOOP /* No such method */
#define UNQLITE_INVALID SXERR_INVALID /* Invalid parameter */
#define UNQLITE_EOF SXERR_EOF /* End Of Input */
#define UNQLITE_UNKNOWN SXERR_UNKNOWN /* Unknown configuration option */
#define UNQLITE_LIMIT SXERR_LIMIT /* Database limit reached */
#define UNQLITE_EXISTS SXERR_EXISTS /* Record exists */
#define UNQLITE_EMPTY SXERR_EMPTY /* Empty record */
#define UNQLITE_COMPILE_ERR (-70) /* Compilation error */
#define UNQLITE_VM_ERR (-71) /* Virtual machine error */
#define UNQLITE_FULL (-73) /* Full database (unlikely) */
#define UNQLITE_CANTOPEN (-74) /* Unable to open the database file */
#define UNQLITE_READ_ONLY (-75) /* Read only Key/Value storage engine */
#define UNQLITE_LOCKERR (-76) /* Locking protocol error */
/* end-of-error-codes */
/*
* Database Handle Configuration Commands.
*
* The following set of constants are the available configuration verbs that can
* be used by the host-application to configure an UnQLite database handle.
* These constants must be passed as the second argument to [unqlite_config()].
*
* Each options require a variable number of arguments.
* The [unqlite_config()] interface will return UNQLITE_OK on success, any other
* return value indicates failure.
* For a full discussion on the configuration verbs and their expected
* parameters, please refer to this page:
* http://unqlite.org/c_api/unqlite_config.html
*/
#define UNQLITE_CONFIG_JX9_ERR_LOG 1 /* TWO ARGUMENTS: const char **pzBuf, int *pLen */
#define UNQLITE_CONFIG_MAX_PAGE_CACHE 2 /* ONE ARGUMENT: int nMaxPage */
#define UNQLITE_CONFIG_ERR_LOG 3 /* TWO ARGUMENTS: const char **pzBuf, int *pLen */
#define UNQLITE_CONFIG_KV_ENGINE 4 /* ONE ARGUMENT: const char *zKvName */
#define UNQLITE_CONFIG_DISABLE_AUTO_COMMIT 5 /* NO ARGUMENTS */
#define UNQLITE_CONFIG_GET_KV_NAME 6 /* ONE ARGUMENT: const char **pzPtr */
/*
* UnQLite/Jx9 Virtual Machine Configuration Commands.
*
* The following set of constants are the available configuration verbs that can
* be used by the host-application to configure the Jx9 (Via UnQLite) Virtual machine.
* These constants must be passed as the second argument to the [unqlite_vm_config()]
* interface.
* Each options require a variable number of arguments.
* The [unqlite_vm_config()] interface will return UNQLITE_OK on success, any other return
* value indicates failure.
* There are many options but the most importants are: UNQLITE_VM_CONFIG_OUTPUT which install
* a VM output consumer callback, UNQLITE_VM_CONFIG_HTTP_REQUEST which parse and register
* a HTTP request and UNQLITE_VM_CONFIG_ARGV_ENTRY which populate the $argv array.
* For a full discussion on the configuration verbs and their expected parameters, please
* refer to this page:
* http://unqlite.org/c_api/unqlite_vm_config.html
*/
#define UNQLITE_VM_CONFIG_OUTPUT 1 /* TWO ARGUMENTS: int (*xConsumer)(const void *pOut, unsigned int nLen, void *pUserData), void *pUserData */
#define UNQLITE_VM_CONFIG_IMPORT_PATH 2 /* ONE ARGUMENT: const char *zIncludePath */
#define UNQLITE_VM_CONFIG_ERR_REPORT 3 /* NO ARGUMENTS: Report all run-time errors in the VM output */
#define UNQLITE_VM_CONFIG_RECURSION_DEPTH 4 /* ONE ARGUMENT: int nMaxDepth */
#define UNQLITE_VM_OUTPUT_LENGTH 5 /* ONE ARGUMENT: unsigned int *pLength */
#define UNQLITE_VM_CONFIG_CREATE_VAR 6 /* TWO ARGUMENTS: const char *zName, unqlite_value *pValue */
#define UNQLITE_VM_CONFIG_HTTP_REQUEST 7 /* TWO ARGUMENTS: const char *zRawRequest, int nRequestLength */
#define UNQLITE_VM_CONFIG_SERVER_ATTR 8 /* THREE ARGUMENTS: const char *zKey, const char *zValue, int nLen */
#define UNQLITE_VM_CONFIG_ENV_ATTR 9 /* THREE ARGUMENTS: const char *zKey, const char *zValue, int nLen */
#define UNQLITE_VM_CONFIG_EXEC_VALUE 10 /* ONE ARGUMENT: unqlite_value **ppValue */
#define UNQLITE_VM_CONFIG_IO_STREAM 11 /* ONE ARGUMENT: const unqlite_io_stream *pStream */
#define UNQLITE_VM_CONFIG_ARGV_ENTRY 12 /* ONE ARGUMENT: const char *zValue */
#define UNQLITE_VM_CONFIG_EXTRACT_OUTPUT 13 /* TWO ARGUMENTS: const void **ppOut, unsigned int *pOutputLen */
/*
* Storage engine configuration commands.
*
* The following set of constants are the available configuration verbs that can
* be used by the host-application to configure the underlying storage engine (i.e Hash, B+tree, R+tree).
* These constants must be passed as the first argument to [unqlite_kv_config()].
* Each options require a variable number of arguments.
* The [unqlite_kv_config()] interface will return UNQLITE_OK on success, any other return
* value indicates failure.
* For a full discussion on the configuration verbs and their expected parameters, please
* refer to this page:
* http://unqlite.org/c_api/unqlite_kv_config.html
*/
#define UNQLITE_KV_CONFIG_HASH_FUNC 1 /* ONE ARGUMENT: unsigned int (*xHash)(const void *,unsigned int) */
#define UNQLITE_KV_CONFIG_CMP_FUNC 2 /* ONE ARGUMENT: int (*xCmp)(const void *,const void *,unsigned int) */
/*
* Global Library Configuration Commands.
*
* The following set of constants are the available configuration verbs that can
* be used by the host-application to configure the whole library.
* These constants must be passed as the first argument to [unqlite_lib_config()].
*
* Each options require a variable number of arguments.
* The [unqlite_lib_config()] interface will return UNQLITE_OK on success, any other return
* value indicates failure.
* Notes:
* The default configuration is recommended for most applications and so the call to
* [unqlite_lib_config()] is usually not necessary. It is provided to support rare
* applications with unusual needs.
* The [unqlite_lib_config()] interface is not threadsafe. The application must insure that
* no other [unqlite_*()] interfaces are invoked by other threads while [unqlite_lib_config()]
* is running. Furthermore, [unqlite_lib_config()] may only be invoked prior to library
* initialization using [unqlite_lib_init()] or [unqlite_init()] or after shutdown
* by [unqlite_lib_shutdown()]. If [unqlite_lib_config()] is called after [unqlite_lib_init()]
* or [unqlite_init()] and before [unqlite_lib_shutdown()] then it will return UNQLITE_LOCKED.
* For a full discussion on the configuration verbs and their expected parameters, please
* refer to this page:
* http://unqlite.org/c_api/unqlite_lib.html
*/
#define UNQLITE_LIB_CONFIG_USER_MALLOC 1 /* ONE ARGUMENT: const SyMemMethods *pMemMethods */
#define UNQLITE_LIB_CONFIG_MEM_ERR_CALLBACK 2 /* TWO ARGUMENTS: int (*xMemError)(void *), void *pUserData */
#define UNQLITE_LIB_CONFIG_USER_MUTEX 3 /* ONE ARGUMENT: const SyMutexMethods *pMutexMethods */
#define UNQLITE_LIB_CONFIG_THREAD_LEVEL_SINGLE 4 /* NO ARGUMENTS */
#define UNQLITE_LIB_CONFIG_THREAD_LEVEL_MULTI 5 /* NO ARGUMENTS */
#define UNQLITE_LIB_CONFIG_VFS 6 /* ONE ARGUMENT: const unqlite_vfs *pVfs */
#define UNQLITE_LIB_CONFIG_STORAGE_ENGINE 7 /* ONE ARGUMENT: unqlite_kv_methods *pStorage */
#define UNQLITE_LIB_CONFIG_PAGE_SIZE 8 /* ONE ARGUMENT: int iPageSize */
/*
* These bit values are intended for use in the 3rd parameter to the [unqlite_open()] interface
* and in the 4th parameter to the xOpen method of the [unqlite_vfs] object.
*/
#define UNQLITE_OPEN_READONLY 0x00000001 /* Read only mode. Ok for [unqlite_open] */
#define UNQLITE_OPEN_READWRITE 0x00000002 /* Ok for [unqlite_open] */
#define UNQLITE_OPEN_CREATE 0x00000004 /* Ok for [unqlite_open] */
#define UNQLITE_OPEN_EXCLUSIVE 0x00000008 /* VFS only */
#define UNQLITE_OPEN_TEMP_DB 0x00000010 /* VFS only */
#define UNQLITE_OPEN_NOMUTEX 0x00000020 /* Ok for [unqlite_open] */
#define UNQLITE_OPEN_OMIT_JOURNALING 0x00000040 /* Omit journaling for this database. Ok for [unqlite_open] */
#define UNQLITE_OPEN_IN_MEMORY 0x00000080 /* An in memory database. Ok for [unqlite_open]*/
#define UNQLITE_OPEN_MMAP 0x00000100 /* Obtain a memory view of the whole file. Ok for [unqlite_open] */
/*
* Synchronization Type Flags
*
* When UnQLite invokes the xSync() method of an [unqlite_io_methods] object it uses
* a combination of these integer values as the second argument.
*
* When the UNQLITE_SYNC_DATAONLY flag is used, it means that the sync operation only
* needs to flush data to mass storage. Inode information need not be flushed.
* If the lower four bits of the flag equal UNQLITE_SYNC_NORMAL, that means to use normal
* fsync() semantics. If the lower four bits equal UNQLITE_SYNC_FULL, that means to use
* Mac OS X style fullsync instead of fsync().
*/
#define UNQLITE_SYNC_NORMAL 0x00002
#define UNQLITE_SYNC_FULL 0x00003
#define UNQLITE_SYNC_DATAONLY 0x00010
/*
* File Locking Levels
*
* UnQLite uses one of these integer values as the second
* argument to calls it makes to the xLock() and xUnlock() methods
* of an [unqlite_io_methods] object.
*/
#define UNQLITE_LOCK_NONE 0
#define UNQLITE_LOCK_SHARED 1
#define UNQLITE_LOCK_RESERVED 2
#define UNQLITE_LOCK_PENDING 3
#define UNQLITE_LOCK_EXCLUSIVE 4
/*
* CAPIREF: OS Interface: Open File Handle
*
* An [unqlite_file] object represents an open file in the [unqlite_vfs] OS interface
* layer.
* Individual OS interface implementations will want to subclass this object by appending
* additional fields for their own use. The pMethods entry is a pointer to an
* [unqlite_io_methods] object that defines methods for performing
* I/O operations on the open file.
*/
typedef struct unqlite_file unqlite_file;
struct unqlite_file {
const unqlite_io_methods *pMethods; /* Methods for an open file. MUST BE FIRST */
};
/*
* CAPIREF: OS Interface: File Methods Object
*
* Every file opened by the [unqlite_vfs] xOpen method populates an
* [unqlite_file] object (or, more commonly, a subclass of the
* [unqlite_file] object) with a pointer to an instance of this object.
* This object defines the methods used to perform various operations
* against the open file represented by the [unqlite_file] object.
*
* If the xOpen method sets the unqlite_file.pMethods element
* to a non-NULL pointer, then the unqlite_io_methods.xClose method
* may be invoked even if the xOpen reported that it failed. The
* only way to prevent a call to xClose following a failed xOpen
* is for the xOpen to set the unqlite_file.pMethods element to NULL.
*
* The flags argument to xSync may be one of [UNQLITE_SYNC_NORMAL] or
* [UNQLITE_SYNC_FULL]. The first choice is the normal fsync().
* The second choice is a Mac OS X style fullsync. The [UNQLITE_SYNC_DATAONLY]
* flag may be ORed in to indicate that only the data of the file
* and not its inode needs to be synced.
*
* The integer values to xLock() and xUnlock() are one of
*
* UNQLITE_LOCK_NONE
* UNQLITE_LOCK_SHARED
* UNQLITE_LOCK_RESERVED
* UNQLITE_LOCK_PENDING
* UNQLITE_LOCK_EXCLUSIVE
*
* xLock() increases the lock. xUnlock() decreases the lock.
* The xCheckReservedLock() method checks whether any database connection,
* either in this process or in some other process, is holding a RESERVED,
* PENDING, or EXCLUSIVE lock on the file. It returns true if such a lock exists
* and false otherwise.
*
* The xSectorSize() method returns the sector size of the device that underlies
* the file. The sector size is the minimum write that can be performed without
* disturbing other bytes in the file.
*
*/
struct unqlite_io_methods {
int iVersion; /* Structure version number (currently 1) */
int (*xClose)(unqlite_file*);
int (*xRead)(unqlite_file*, void*, unqlite_int64 iAmt, unqlite_int64 iOfst);
int (*xWrite)(unqlite_file*, const void*, unqlite_int64 iAmt, unqlite_int64 iOfst);
int (*xTruncate)(unqlite_file*, unqlite_int64 size);
int (*xSync)(unqlite_file*, int flags);
int (*xFileSize)(unqlite_file*, unqlite_int64 *pSize);
int (*xLock)(unqlite_file*, int);
int (*xUnlock)(unqlite_file*, int);
int (*xCheckReservedLock)(unqlite_file*, int *pResOut);
int (*xSectorSize)(unqlite_file*);
};
/*
* CAPIREF: OS Interface Object
*
* An instance of the unqlite_vfs object defines the interface between
* the UnQLite core and the underlying operating system. The "vfs"
* in the name of the object stands for "Virtual File System".
*
* Only a single vfs can be registered within the UnQLite core.
* Vfs registration is done using the [unqlite_lib_config()] interface
* with a configuration verb set to UNQLITE_LIB_CONFIG_VFS.
* Note that Windows and UNIX (Linux, FreeBSD, Solaris, Mac OS X, etc.) users
* does not have to worry about registering and installing a vfs since UnQLite
* come with a built-in vfs for these platforms that implements most the methods
* defined below.
*
* Clients running on exotic systems (ie: Other than Windows and UNIX systems)
* must register their own vfs in order to be able to use the UnQLite library.
*
* The value of the iVersion field is initially 1 but may be larger in
* future versions of UnQLite.
*
* The szOsFile field is the size of the subclassed [unqlite_file] structure
* used by this VFS. mxPathname is the maximum length of a pathname in this VFS.
*
* At least szOsFile bytes of memory are allocated by UnQLite to hold the [unqlite_file]
* structure passed as the third argument to xOpen. The xOpen method does not have to
* allocate the structure; it should just fill it in. Note that the xOpen method must
* set the unqlite_file.pMethods to either a valid [unqlite_io_methods] object or to NULL.
* xOpen must do this even if the open fails. UnQLite expects that the unqlite_file.pMethods
* element will be valid after xOpen returns regardless of the success or failure of the
* xOpen call.
*
*/
struct unqlite_vfs {
const char *zName; /* Name of this virtual file system [i.e: Windows, UNIX, etc.] */
int iVersion; /* Structure version number (currently 1) */
int szOsFile; /* Size of subclassed unqlite_file */
int mxPathname; /* Maximum file pathname length */
int (*xOpen)(unqlite_vfs*, const char *zName, unqlite_file*,unsigned int flags);
int (*xDelete)(unqlite_vfs*, const char *zName, int syncDir);
int (*xAccess)(unqlite_vfs*, const char *zName, int flags, int *pResOut);
int (*xFullPathname)(unqlite_vfs*, const char *zName,int buf_len,char *zBuf);
int (*xTmpDir)(unqlite_vfs*,char *zBuf,int buf_len);
int (*xSleep)(unqlite_vfs*, int microseconds);
int (*xCurrentTime)(unqlite_vfs*,Sytm *pOut);
int (*xGetLastError)(unqlite_vfs*, int, char *);
};
/*
* Flags for the xAccess VFS method
*
* These integer constants can be used as the third parameter to
* the xAccess method of an [unqlite_vfs] object. They determine
* what kind of permissions the xAccess method is looking for.
* With UNQLITE_ACCESS_EXISTS, the xAccess method
* simply checks whether the file exists.
* With UNQLITE_ACCESS_READWRITE, the xAccess method
* checks whether the named directory is both readable and writable
* (in other words, if files can be added, removed, and renamed within
* the directory).
* The UNQLITE_ACCESS_READWRITE constant is currently used only by the
* [temp_store_directory pragma], though this could change in a future
* release of UnQLite.
* With UNQLITE_ACCESS_READ, the xAccess method
* checks whether the file is readable. The UNQLITE_ACCESS_READ constant is
* currently unused, though it might be used in a future release of
* UnQLite.
*/
#define UNQLITE_ACCESS_EXISTS 0
#define UNQLITE_ACCESS_READWRITE 1
#define UNQLITE_ACCESS_READ 2
/*
* The type used to represent a page number. The first page in a file
* is called page 1. 0 is used to represent "not a page".
* A page number is an unsigned 64-bit integer.
*/
typedef sxu64 pgno;
/*
* A database disk page is represented by an instance
* of the follwoing structure.
*/
typedef struct unqlite_page unqlite_page;
struct unqlite_page
{
unsigned char *zData; /* Content of this page */
void *pUserData; /* Extra content */
pgno pgno; /* Page number for this page */
};
/*
* UnQLite handle to the underlying Key/Value Storage Engine (See below).
*/
typedef void * unqlite_kv_handle;
/*
* UnQLite pager IO methods.
*
* An instance of the following structure define the exported methods of the UnQLite pager
* to the underlying Key/Value storage engine.
*/
typedef struct unqlite_kv_io unqlite_kv_io;
struct unqlite_kv_io
{
unqlite_kv_handle pHandle; /* UnQLite handle passed as the first parameter to the
* method defined below.
*/
unqlite_kv_methods *pMethods; /* Underlying storage engine */
/* Pager methods */
int (*xGet)(unqlite_kv_handle,pgno,unqlite_page **);
int (*xLookup)(unqlite_kv_handle,pgno,unqlite_page **);
int (*xNew)(unqlite_kv_handle,unqlite_page **);
int (*xWrite)(unqlite_page *);
int (*xDontWrite)(unqlite_page *);
int (*xDontJournal)(unqlite_page *);
int (*xDontMkHot)(unqlite_page *);
int (*xPageRef)(unqlite_page *);
int (*xPageUnref)(unqlite_page *);
int (*xPageSize)(unqlite_kv_handle);
int (*xReadOnly)(unqlite_kv_handle);
unsigned char * (*xTmpPage)(unqlite_kv_handle);
void (*xSetUnpin)(unqlite_kv_handle,void (*xPageUnpin)(void *));
void (*xSetReload)(unqlite_kv_handle,void (*xPageReload)(void *));
void (*xErr)(unqlite_kv_handle,const char *);
};
/*
* Key/Value Storage Engine Cursor Object
*
* An instance of a subclass of the following object defines a cursor
* used to scan through a key-value storage engine.
*/
typedef struct unqlite_kv_cursor unqlite_kv_cursor;
struct unqlite_kv_cursor
{
unqlite_kv_engine *pStore; /* Must be first */
/* Subclasses will typically add additional fields */
};
/*
* Possible seek positions.
*/
#define UNQLITE_CURSOR_MATCH_EXACT 1
#define UNQLITE_CURSOR_MATCH_LE 2
#define UNQLITE_CURSOR_MATCH_GE 3
/*
* Key/Value Storage Engine.
*
* A Key-Value storage engine is defined by an instance of the following
* object.
* UnQLite works with run-time interchangeable storage engines (i.e. Hash, B+Tree, R+Tree, LSM, etc.).
* The storage engine works with key/value pairs where both the key
* and the value are byte arrays of arbitrary length and with no restrictions on content.
* UnQLite come with two built-in KV storage engine: A Virtual Linear Hash (VLH) storage
* engine is used for persistent on-disk databases with O(1) lookup time and an in-memory
* hash-table or Red-black tree storage engine is used for in-memory databases.
* Future versions of UnQLite might add other built-in storage engines (i.e. LSM).
* Registration of a Key/Value storage engine at run-time is done via [unqlite_lib_config()]
* with a configuration verb set to UNQLITE_LIB_CONFIG_STORAGE_ENGINE.
*/
struct unqlite_kv_engine
{
const unqlite_kv_io *pIo; /* IO methods: MUST be first */
/* Subclasses will typically add additional fields */
};
/*
* Key/Value Storage Engine Virtual Method Table.
*
* Key/Value storage engine methods is defined by an instance of the following
* object.
* Registration of a Key/Value storage engine at run-time is done via [unqlite_lib_config()]
* with a configuration verb set to UNQLITE_LIB_CONFIG_STORAGE_ENGINE.
*/
struct unqlite_kv_methods
{
const char *zName; /* Storage engine name [i.e. Hash, B+tree, LSM, R-tree, Mem, etc.]*/
int szKv; /* 'unqlite_kv_engine' subclass size */
int szCursor; /* 'unqlite_kv_cursor' subclass size */
int iVersion; /* Structure version, currently 1 */
/* Storage engine methods */
int (*xInit)(unqlite_kv_engine *,int iPageSize);
void (*xRelease)(unqlite_kv_engine *);
int (*xConfig)(unqlite_kv_engine *,int op,va_list ap);
int (*xOpen)(unqlite_kv_engine *,pgno);
int (*xReplace)(
unqlite_kv_engine *,
const void *pKey,int nKeyLen,
const void *pData,unqlite_int64 nDataLen
);
int (*xAppend)(
unqlite_kv_engine *,
const void *pKey,int nKeyLen,
const void *pData,unqlite_int64 nDataLen
);
void (*xCursorInit)(unqlite_kv_cursor *);
int (*xSeek)(unqlite_kv_cursor *,const void *pKey,int nByte,int iPos); /* Mandatory */
int (*xFirst)(unqlite_kv_cursor *);
int (*xLast)(unqlite_kv_cursor *);
int (*xValid)(unqlite_kv_cursor *);
int (*xNext)(unqlite_kv_cursor *);
int (*xPrev)(unqlite_kv_cursor *);
int (*xDelete)(unqlite_kv_cursor *);
int (*xKeyLength)(unqlite_kv_cursor *,int *);
int (*xKey)(unqlite_kv_cursor *,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
int (*xDataLength)(unqlite_kv_cursor *,unqlite_int64 *);
int (*xData)(unqlite_kv_cursor *,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
void (*xReset)(unqlite_kv_cursor *);
void (*xCursorRelease)(unqlite_kv_cursor *);
};
/*
* UnQLite journal file suffix.
*/
#ifndef UNQLITE_JOURNAL_FILE_SUFFIX
#define UNQLITE_JOURNAL_FILE_SUFFIX "_unqlite_journal"
#endif
/*
* Call Context - Error Message Serverity Level.
*
* The following constans are the allowed severity level that can
* passed as the second argument to the [unqlite_context_throw_error()] or
* [unqlite_context_throw_error_format()] interfaces.
* Refer to the official documentation for additional information.
*/
#define UNQLITE_CTX_ERR 1 /* Call context error such as unexpected number of arguments, invalid types and so on. */
#define UNQLITE_CTX_WARNING 2 /* Call context Warning */
#define UNQLITE_CTX_NOTICE 3 /* Call context Notice */
/*
* C-API-REF: Please refer to the official documentation for interfaces
* purpose and expected parameters.
*/
/* Database Engine Handle */
UNQLITE_APIEXPORT int unqlite_open(unqlite **ppDB,const char *zFilename,unsigned int iMode);
UNQLITE_APIEXPORT int unqlite_config(unqlite *pDb,int nOp,...);
UNQLITE_APIEXPORT int unqlite_close(unqlite *pDb);
/* Key/Value (KV) Store Interfaces */
UNQLITE_APIEXPORT int unqlite_kv_store(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen);
UNQLITE_APIEXPORT int unqlite_kv_append(unqlite *pDb,const void *pKey,int nKeyLen,const void *pData,unqlite_int64 nDataLen);
UNQLITE_APIEXPORT int unqlite_kv_store_fmt(unqlite *pDb,const void *pKey,int nKeyLen,const char *zFormat,...);
UNQLITE_APIEXPORT int unqlite_kv_append_fmt(unqlite *pDb,const void *pKey,int nKeyLen,const char *zFormat,...);
UNQLITE_APIEXPORT int unqlite_kv_fetch(unqlite *pDb,const void *pKey,int nKeyLen,void *pBuf,unqlite_int64 /* in|out */*pBufLen);
UNQLITE_APIEXPORT int unqlite_kv_fetch_callback(unqlite *pDb,const void *pKey,
int nKeyLen,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
UNQLITE_APIEXPORT int unqlite_kv_delete(unqlite *pDb,const void *pKey,int nKeyLen);
UNQLITE_APIEXPORT int unqlite_kv_config(unqlite *pDb,int iOp,...);
/* Document (JSON) Store Interfaces powered by the Jx9 Scripting Language */
UNQLITE_APIEXPORT int unqlite_compile(unqlite *pDb,const char *zJx9,int nByte,unqlite_vm **ppOut);
UNQLITE_APIEXPORT int unqlite_compile_file(unqlite *pDb,const char *zPath,unqlite_vm **ppOut);
UNQLITE_APIEXPORT int unqlite_vm_config(unqlite_vm *pVm,int iOp,...);
UNQLITE_APIEXPORT int unqlite_vm_exec(unqlite_vm *pVm);
UNQLITE_APIEXPORT int unqlite_vm_reset(unqlite_vm *pVm);
UNQLITE_APIEXPORT int unqlite_vm_release(unqlite_vm *pVm);
UNQLITE_APIEXPORT int unqlite_vm_dump(unqlite_vm *pVm, int (*xConsumer)(const void *, unsigned int, void *), void *pUserData);
UNQLITE_APIEXPORT unqlite_value * unqlite_vm_extract_variable(unqlite_vm *pVm,const char *zVarname);
/* Cursor Iterator Interfaces */
UNQLITE_APIEXPORT int unqlite_kv_cursor_init(unqlite *pDb,unqlite_kv_cursor **ppOut);
UNQLITE_APIEXPORT int unqlite_kv_cursor_release(unqlite *pDb,unqlite_kv_cursor *pCur);
UNQLITE_APIEXPORT int unqlite_kv_cursor_seek(unqlite_kv_cursor *pCursor,const void *pKey,int nKeyLen,int iPos);
UNQLITE_APIEXPORT int unqlite_kv_cursor_first_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_last_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_valid_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_next_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_prev_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_key(unqlite_kv_cursor *pCursor,void *pBuf,int *pnByte);
UNQLITE_APIEXPORT int unqlite_kv_cursor_key_callback(unqlite_kv_cursor *pCursor,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
UNQLITE_APIEXPORT int unqlite_kv_cursor_data(unqlite_kv_cursor *pCursor,void *pBuf,unqlite_int64 *pnData);
UNQLITE_APIEXPORT int unqlite_kv_cursor_data_callback(unqlite_kv_cursor *pCursor,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
UNQLITE_APIEXPORT int unqlite_kv_cursor_delete_entry(unqlite_kv_cursor *pCursor);
UNQLITE_APIEXPORT int unqlite_kv_cursor_reset(unqlite_kv_cursor *pCursor);
/* Manual Transaction Manager */
UNQLITE_APIEXPORT int unqlite_begin(unqlite *pDb);
UNQLITE_APIEXPORT int unqlite_commit(unqlite *pDb);
UNQLITE_APIEXPORT int unqlite_rollback(unqlite *pDb);
/* Utility interfaces */
UNQLITE_APIEXPORT int unqlite_util_load_mmaped_file(const char *zFile,void **ppMap,unqlite_int64 *pFileSize);
UNQLITE_APIEXPORT int unqlite_util_release_mmaped_file(void *pMap,unqlite_int64 iFileSize);
UNQLITE_APIEXPORT int unqlite_util_random_string(unqlite *pDb,char *zBuf,unsigned int buf_size);
UNQLITE_APIEXPORT unsigned int unqlite_util_random_num(unqlite *pDb);
/* In-process extending interfaces */
UNQLITE_APIEXPORT int unqlite_create_function(unqlite_vm *pVm,const char *zName,int (*xFunc)(unqlite_context *,int,unqlite_value **),void *pUserData);
UNQLITE_APIEXPORT int unqlite_delete_function(unqlite_vm *pVm, const char *zName);
UNQLITE_APIEXPORT int unqlite_create_constant(unqlite_vm *pVm,const char *zName,void (*xExpand)(unqlite_value *, void *),void *pUserData);
UNQLITE_APIEXPORT int unqlite_delete_constant(unqlite_vm *pVm, const char *zName);
/* On Demand Object allocation interfaces */
UNQLITE_APIEXPORT unqlite_value * unqlite_vm_new_scalar(unqlite_vm *pVm);
UNQLITE_APIEXPORT unqlite_value * unqlite_vm_new_array(unqlite_vm *pVm);
UNQLITE_APIEXPORT int unqlite_vm_release_value(unqlite_vm *pVm,unqlite_value *pValue);
UNQLITE_APIEXPORT unqlite_value * unqlite_context_new_scalar(unqlite_context *pCtx);
UNQLITE_APIEXPORT unqlite_value * unqlite_context_new_array(unqlite_context *pCtx);
UNQLITE_APIEXPORT void unqlite_context_release_value(unqlite_context *pCtx,unqlite_value *pValue);
/* Dynamically Typed Value Object Management Interfaces */
UNQLITE_APIEXPORT int unqlite_value_int(unqlite_value *pVal, int iValue);
UNQLITE_APIEXPORT int unqlite_value_int64(unqlite_value *pVal, unqlite_int64 iValue);
UNQLITE_APIEXPORT int unqlite_value_bool(unqlite_value *pVal, int iBool);
UNQLITE_APIEXPORT int unqlite_value_null(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_double(unqlite_value *pVal, double Value);
UNQLITE_APIEXPORT int unqlite_value_string(unqlite_value *pVal, const char *zString, int nLen);
UNQLITE_APIEXPORT int unqlite_value_string_format(unqlite_value *pVal, const char *zFormat,...);
UNQLITE_APIEXPORT int unqlite_value_reset_string_cursor(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_resource(unqlite_value *pVal, void *pUserData);
UNQLITE_APIEXPORT int unqlite_value_release(unqlite_value *pVal);
/* Foreign Function Parameter Values */
UNQLITE_APIEXPORT int unqlite_value_to_int(unqlite_value *pValue);
UNQLITE_APIEXPORT int unqlite_value_to_bool(unqlite_value *pValue);
UNQLITE_APIEXPORT unqlite_int64 unqlite_value_to_int64(unqlite_value *pValue);
UNQLITE_APIEXPORT double unqlite_value_to_double(unqlite_value *pValue);
UNQLITE_APIEXPORT const char * unqlite_value_to_string(unqlite_value *pValue, int *pLen);
UNQLITE_APIEXPORT void * unqlite_value_to_resource(unqlite_value *pValue);
UNQLITE_APIEXPORT int unqlite_value_compare(unqlite_value *pLeft, unqlite_value *pRight, int bStrict);
/* Setting The Result Of A Foreign Function */
UNQLITE_APIEXPORT int unqlite_result_int(unqlite_context *pCtx, int iValue);
UNQLITE_APIEXPORT int unqlite_result_int64(unqlite_context *pCtx, unqlite_int64 iValue);
UNQLITE_APIEXPORT int unqlite_result_bool(unqlite_context *pCtx, int iBool);
UNQLITE_APIEXPORT int unqlite_result_double(unqlite_context *pCtx, double Value);
UNQLITE_APIEXPORT int unqlite_result_null(unqlite_context *pCtx);
UNQLITE_APIEXPORT int unqlite_result_string(unqlite_context *pCtx, const char *zString, int nLen);
UNQLITE_APIEXPORT int unqlite_result_string_format(unqlite_context *pCtx, const char *zFormat, ...);
UNQLITE_APIEXPORT int unqlite_result_value(unqlite_context *pCtx, unqlite_value *pValue);
UNQLITE_APIEXPORT int unqlite_result_resource(unqlite_context *pCtx, void *pUserData);
/* Dynamically Typed Value Object Query Interfaces */
UNQLITE_APIEXPORT int unqlite_value_is_int(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_float(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_bool(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_string(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_null(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_numeric(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_callable(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_scalar(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_json_array(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_json_object(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_resource(unqlite_value *pVal);
UNQLITE_APIEXPORT int unqlite_value_is_empty(unqlite_value *pVal);
/* JSON Array/Object Management Interfaces */
UNQLITE_APIEXPORT unqlite_value * unqlite_array_fetch(unqlite_value *pArray, const char *zKey, int nByte);
UNQLITE_APIEXPORT int unqlite_array_walk(unqlite_value *pArray, int (*xWalk)(unqlite_value *, unqlite_value *, void *), void *pUserData);
UNQLITE_APIEXPORT int unqlite_array_add_elem(unqlite_value *pArray, unqlite_value *pKey, unqlite_value *pValue);
UNQLITE_APIEXPORT int unqlite_array_add_strkey_elem(unqlite_value *pArray, const char *zKey, unqlite_value *pValue);
UNQLITE_APIEXPORT int unqlite_array_count(unqlite_value *pArray);
/* Call Context Handling Interfaces */
UNQLITE_APIEXPORT int unqlite_context_output(unqlite_context *pCtx, const char *zString, int nLen);
UNQLITE_APIEXPORT int unqlite_context_output_format(unqlite_context *pCtx,const char *zFormat, ...);
UNQLITE_APIEXPORT int unqlite_context_throw_error(unqlite_context *pCtx, int iErr, const char *zErr);
UNQLITE_APIEXPORT int unqlite_context_throw_error_format(unqlite_context *pCtx, int iErr, const char *zFormat, ...);
UNQLITE_APIEXPORT unsigned int unqlite_context_random_num(unqlite_context *pCtx);
UNQLITE_APIEXPORT int unqlite_context_random_string(unqlite_context *pCtx, char *zBuf, int nBuflen);
UNQLITE_APIEXPORT void * unqlite_context_user_data(unqlite_context *pCtx);
UNQLITE_APIEXPORT int unqlite_context_push_aux_data(unqlite_context *pCtx, void *pUserData);
UNQLITE_APIEXPORT void * unqlite_context_peek_aux_data(unqlite_context *pCtx);
UNQLITE_APIEXPORT unsigned int unqlite_context_result_buf_length(unqlite_context *pCtx);
UNQLITE_APIEXPORT const char * unqlite_function_name(unqlite_context *pCtx);
/* Call Context Memory Management Interfaces */
UNQLITE_APIEXPORT void * unqlite_context_alloc_chunk(unqlite_context *pCtx,unsigned int nByte,int ZeroChunk,int AutoRelease);
UNQLITE_APIEXPORT void * unqlite_context_realloc_chunk(unqlite_context *pCtx,void *pChunk,unsigned int nByte);
UNQLITE_APIEXPORT void unqlite_context_free_chunk(unqlite_context *pCtx,void *pChunk);
/* Global Library Management Interfaces */
UNQLITE_APIEXPORT int unqlite_lib_config(int nConfigOp,...);
UNQLITE_APIEXPORT int unqlite_lib_init(void);
UNQLITE_APIEXPORT int unqlite_lib_shutdown(void);
UNQLITE_APIEXPORT int unqlite_lib_is_threadsafe(void);
UNQLITE_APIEXPORT const char * unqlite_lib_version(void);
UNQLITE_APIEXPORT const char * unqlite_lib_signature(void);
UNQLITE_APIEXPORT const char * unqlite_lib_ident(void);
UNQLITE_APIEXPORT const char * unqlite_lib_copyright(void);
#endif /* _UNQLITE_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 -I$(top_srcdir)/../civetweb-1.9.1/include -I$(top_srcdir)/../libks/src/include
TEST_LDADD = $(abs_top_builddir)/libblade.la -L$(top_srcdir)/../civetweb-1.9.1 -L$(top_srcdir)/../libks -lconfig -lm -lpthread -lcivetweb -lks
check_PROGRAMS =
check_PROGRAMS += switchblade
switchblade_SOURCES = switchblade.c
switchblade_CFLAGS = $(AM_CFLAGS)
switchblade_LDADD = $(TEST_LDADD)
sb: $(check_PROGRAMS)

View File

@ -1,14 +0,0 @@
HTTP/1.0 200 OK
Content-Type: text/html
<html><body>
<p>
<span>Today is:</span>
<? mg.write(os.date("%A")) ?>
</p>
<p>
URI is <?=mg.request_info.uri?>
</p>
</body></html>

View File

@ -1,181 +0,0 @@
#include "blade.h"
#define CONSOLE_INPUT_MAX 512
// @todo switch to wait condition once something is being done with the main thread during runtime
ks_bool_t g_shutdown = KS_FALSE;
void loop(blade_handle_t *bh);
void process_console_input(blade_handle_t *bh, char *line);
int rest_service_test(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures);
typedef void(*command_callback)(blade_handle_t *bh, char *args);
struct command_def_s {
const char *cmd;
command_callback callback;
};
void command_quit(blade_handle_t *bh, char *args);
static const struct command_def_s command_defs[] = {
{ "quit", command_quit },
{ NULL, NULL }
};
int main(int argc, char **argv)
{
blade_handle_t *bh = NULL;
config_t config;
config_setting_t *config_blade = NULL;
const char *cfgpath = "switchblade.cfg";
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
blade_init();
blade_handle_create(&bh);
config_init(&config);
if (!config_read_file(&config, cfgpath)) {
ks_log(KS_LOG_ERROR, "%s:%d - %s\n", config_error_file(&config), config_error_line(&config), config_error_text(&config));
config_destroy(&config);
return EXIT_FAILURE;
}
config_blade = config_lookup(&config, "blade");
if (!config_blade) {
ks_log(KS_LOG_ERROR, "Missing 'blade' config group\n");
config_destroy(&config);
return EXIT_FAILURE;
}
if (config_setting_type(config_blade) != CONFIG_TYPE_GROUP) {
ks_log(KS_LOG_ERROR, "The 'blade' config setting is not a group\n");
return EXIT_FAILURE;
}
blade_restmgr_service_add(blade_handle_restmgr_get(bh), "GET", "/test/(\\d+)", rest_service_test);
if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_ERROR, "Blade startup failed\n");
return EXIT_FAILURE;
}
loop(bh);
blade_handle_destroy(&bh);
config_destroy(&config);
blade_shutdown();
return 0;
}
void loop(blade_handle_t *bh)
{
char buf[CONSOLE_INPUT_MAX];
while (!g_shutdown) {
if (!fgets(buf, CONSOLE_INPUT_MAX, stdin)) break;
for (int index = 0; buf[index]; ++index) {
if (buf[index] == '\r' || buf[index] == '\n') {
buf[index] = '\0';
break;
}
}
process_console_input(bh, buf);
ks_sleep_ms(100);
}
}
void parse_argument(char **input, char **arg, char terminator)
{
char *tmp;
ks_assert(input);
ks_assert(*input);
ks_assert(arg);
tmp = *input;
*arg = tmp;
while (*tmp && *tmp != terminator) ++tmp;
if (*tmp == terminator) {
*tmp = '\0';
++tmp;
}
*input = tmp;
}
void process_console_input(blade_handle_t *bh, char *line)
{
char *args = line;
char *cmd = NULL;
ks_bool_t found = KS_FALSE;
parse_argument(&args, &cmd, ' ');
ks_log(KS_LOG_DEBUG, "Command: %s, Args: %s\n", cmd, args);
for (int32_t index = 0; command_defs[index].cmd; ++index) {
if (!strcmp(command_defs[index].cmd, cmd)) {
found = KS_TRUE;
command_defs[index].callback(bh, args);
}
}
if (!found) ks_log(KS_LOG_INFO, "Command '%s' unknown.\n", cmd);
}
void command_quit(blade_handle_t *bh, char *args)
{
//ks_assert(bh);
//ks_assert(args);
g_shutdown = KS_TRUE;
}
int rest_service_test(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures)
{
blade_webrequest_t *request = NULL;
blade_webresponse_t *response = NULL;
cJSON *json = NULL;
cJSON *json_captures = NULL;
//const char *token = NULL;
blade_webrequest_load(&request, conn);
// make a json object to send back
json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "method", blade_webrequest_action_get(request));
cJSON_AddItemToObject(json, "captures", (json_captures = cJSON_CreateArray()));
for (int i = 0; captures[i]; ++i) cJSON_AddItemToArray(json_captures, cJSON_CreateString(captures[i]));
blade_webresponse_create(&response, "200");
blade_webresponse_content_json_append(response, json);
blade_webresponse_send(response, conn);
blade_webresponse_destroy(&response);
cJSON_Delete(json);
blade_webrequest_destroy(&request);
//blade_webrequest_oauth2_token_by_credentials_send(KS_FALSE, "192.168.1.99", 80, "/oauth2/token.php", "testclient", "testpass", &token);
//
//ks_pool_free(&token);
return 200;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -1,32 +0,0 @@
blade:
{
master:
{
enabled = true;
nodeid = "00000000-0000-0000-0000-000000000000";
realms = ( "freeswitch" );
};
rest:
{
enabled = true;
document_root = "./restroot";
};
transport:
{
wss:
{
endpoints:
{
ipv4 = ( { address = "0.0.0.0", port = 2100 } );
ipv6 = ( { address = "::", port = 2100 } );
backlog = 128;
ssl:
{
key = "../test/ca/intermediate/private/master@freeswitch-downstream.key.pem";
cert = "../test/ca/intermediate/certs/master@freeswitch-downstream.cert.pem";
chain = "../test/ca/intermediate/certs/ca-chain.cert.pem";
};
};
};
};
};

View File

@ -1,216 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8330E669-77F3-4F70-A275-6F7BABE050A7}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>switchblade</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\..\..\w32\openssl.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\w32\sodium.props" />
<Import Project="..\..\..\w32\config.props" />
<Import Project="..\..\..\w32\civetweb.props" />
<Import Project="..\..\..\w32\pcre.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\w32\sodium.props" />
<Import Project="..\..\..\w32\config.props" />
<Import Project="..\..\..\w32\civetweb.props" />
<Import Project="..\..\..\w32\pcre.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\w32\sodium.props" />
<Import Project="..\..\..\w32\config.props" />
<Import Project="..\..\..\w32\civetweb.props" />
<Import Project="..\..\..\w32\pcre.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\w32\sodium.props" />
<Import Project="..\..\..\w32\config.props" />
<Import Project="..\..\..\w32\civetweb.props" />
<Import Project="..\..\..\w32\pcre.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<IncludePath>$(SolutionDir);$(SolutionDir)..\libks\src\include;$(SolutionDir)..\libsodium-$(SodiumVersion)\src\libsodium\include;$(SolutionDir)..\libconfig-$(ConfigVersion)\lib;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../src/include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4090</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../src/include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4090</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../src/include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4090</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../src/include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4090</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="switchblade.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libks\libks.vcxproj">
<Project>{70d178d8-1100-4152-86c0-809a91cff832}</Project>
</ProjectReference>
<ProjectReference Include="..\..\win32\libconfig\libconfig.2015.vcxproj">
<Project>{1a234565-926d-49b2-83e4-d56e0c38c9f2}</Project>
</ProjectReference>
<ProjectReference Include="..\..\win32\libsodium\libsodium.2015.vcxproj">
<Project>{a185b162-6cb6-4502-b03f-b56f7699a8d9}</Project>
</ProjectReference>
<ProjectReference Include="..\libblade.vcxproj">
<Project>{a89d6d18-6203-4149-9051-f8e798e7a3e7}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,5 +0,0 @@
Makefile
Makefile.in
*.log
*.trs
testbuild

View File

@ -1,39 +0,0 @@
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 -I$(top_srcdir)/../civetweb-1.9.1/include -I$(top_srcdir)/../libks/src/include
TEST_LDADD = $(abs_top_builddir)/libblade.la -L$(top_srcdir)/../civetweb-1.9.1 -L$(top_srcdir)/../libks -lconfig -lm -lpthread -lcivetweb -lks
check_PROGRAMS =
check_PROGRAMS += testbuild
testbuild_SOURCES = testbuild.c tap.c
testbuild_CFLAGS = $(AM_CFLAGS)
testbuild_LDADD = $(TEST_LDADD)
check_PROGRAMS += testcli
testcli_SOURCES = testcli.c tap.c
testcli_CFLAGS = $(AM_CFLAGS)
testcli_LDADD = $(TEST_LDADD)
check_PROGRAMS += testcon
testcon_SOURCES = testcon.c tap.c
testcon_CFLAGS = $(AM_CFLAGS)
testcon_LDADD = $(TEST_LDADD)
#check_PROGRAMS += testdht2
#testdht2_SOURCES = testdht2.c tap.c
#testdht2_CFLAGS = $(AM_CFLAGS)
#testdht2_LDADD = $(TEST_LDADD)
#check_PROGRAMS += testbuckets
#testbuckets_SOURCES = testbuckets.c tap.c
#testbuckets_CFLAGS = $(AM_CFLAGS)
#testbuckets_LDADD = $(TEST_LDADD)
#check_PROGRAMS += nodeidgen
#nodeidgen_SOURCES = nodeidgen.c tap.c
#nodeidgen_CFLAGS = $(AM_CFLAGS)
#nodeidgen_LDADD = $(TEST_LDADD)
TESTS=$(check_PROGRAMS)
tests: $(check_PROGRAMS)

View File

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFxDCCA6ygAwIBAgIJANi9lXvHAbx4MA0GCSqGSIb3DQEBCwUAMG8xCzAJBgNV
BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzETMBEG
A1UECgwKRnJlZVNXSVRDSDEOMAwGA1UECwwFQmxhZGUxFjAUBgNVBAMMDUJsYWRl
IFJvb3QgQ0EwHhcNMTcwOTA3MDkyNDE2WhcNMjcwOTA1MDkyNDE2WjBvMQswCQYD
VQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xEzAR
BgNVBAoMCkZyZWVTV0lUQ0gxDjAMBgNVBAsMBUJsYWRlMRYwFAYDVQQDDA1CbGFk
ZSBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3Pt3X1j8
YaRuGb4ENkhfazwZl0K4VlaPhGj4h4wiL5S2Tp8E83HoRkoyQRX0fhKCrHtjNucO
ODkVbf+QMlv1mgEwCq+3SIEA6keBzsUv5sahunfPd+Vgh6+lgp1sAfjFuFlxrRvi
ghO/yHHKE6P2BBgIz3t5QSakE/fLPwejZ98dacyAIxklzLvt4xHRVP7rxfiNFXKR
XHsQd1iaWGSUBNMkUspCl8wO5IAPX75RiFGeA80IjZ518YVjiFBjCdzQfJb9iGJC
GzrOcPJahfum+tzyIO/rIj+ldFyLPY0wbpa0wKeF58HWt52p3HmKnK5FUa7L8RNA
fc3/H+6qyDeBFx92+T6J30q61dcmPayKooUJNsTKslrZ5L2OicWZepa/Oc5dagyz
GEUc+Z11Mgl8/4pT4rUOna29v1d8+StJPN8XgWAHxmwpZ/cY/9GluSq5oB+6PTPc
Q0aFHHUAI97QqfpGOeAWjtVd/3YUcNo82Pa3577rRgh55X+XEySQmBiPWNOsfuCZ
ZvYGOkLmby1SYR/LOwH8opKJyG/bOiZq23aaTPkmEQQSLRzsKxWc2jlE/UllpYX3
FCu8nFn+L7Tam495IImi8FrpEX16ZpTGhr7YnfbOkMYw+LaRA36U55e5DToJAB5T
CsC2CLhk8QDVoIMPfpYpY4XpdmA4EfDHOG0CAwEAAaNjMGEwHQYDVR0OBBYEFFoz
OX01zWns+ANZ9/6m9g510yWWMB8GA1UdIwQYMBaAFFozOX01zWns+ANZ9/6m9g51
0yWWMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
CwUAA4ICAQAg74tSgyZKqZtqJPXt/fadZJqWS75cW5TN0rXTKWfzdDXnPfMD2dhZ
h0bH1ZQRamXmXWZni0LpWaOjvqaVNB2TMVStyjEIjLhcBLzR9fhBSXB0BkdVKXvF
Y/pmGN0ZM7BRwbbltgTPYIefftU6BvAyUP5k6y0JJZGy6RTYp7SN2iJ00msqfie/
zmF83arhFAmW8wjDXMPsSz958+TNgeetFeQjrJ5sbMaApCE21QazHcZw6/zPMRvX
Gr+TPyx/p335MViz5SjeFThQ7XES871pZSbOhmIrugCHO8LJOat3oOlnsc8HkZ/T
AfUjka0SSPA/sRqPxjLWw/OwDn7g5GpbXl7RXpRsKR8CDIRMVrzD71Nk0SOEb3T9
Dv7UTl6NDYlyYYqx35t/KsiwWjnPtr6Xcl8O9l/tuzf5Tjt1mz9i80BybE9wXHYi
Y3/1SGloKYVXC+HLLrLm1MEldi9GcYZDzxlydAPfHhSHlYWrvOS/J2Dq6uhH7RHn
JV0nE3bVQE01e6iR4BZMYSj4e3BrhMQvkMX67NndYEmoK6+9d77MsK7wblSXja7t
YyXysfQhcudaN/A00CLJt8VNq+h8Q9BR5PFmvIv6/jzV3kmLO4nX9z0CdERyBBUr
cFXfDn2TBpwlLvOQbEWvZPlEh7Vx2hXRRZr97NstLmFLGTdnVdAl9w==
-----END CERTIFICATE-----

Some files were not shown because too many files have changed in this diff Show More