提交 89940dfc authored 作者: Shane Bryldt's avatar Shane Bryldt 提交者: Mike Jerris

FS-9952: Fixed some stuff to get the blade service tested upto the point of…

FS-9952: Fixed some stuff to get the blade service tested upto the point of processing config and listening on the same port across multiple interfaces
上级 4ec0fbc5
......@@ -130,13 +130,25 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config)
ks_assert(bs);
if (!config) return KS_STATUS_FAIL;
if (!config_setting_is_group(config)) return KS_STATUS_FAIL;
if (!config) {
ks_log(KS_LOG_DEBUG, "!config\n");
return KS_STATUS_FAIL;
}
if (!config_setting_is_group(config)) {
ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
return KS_STATUS_FAIL;
}
websockets = config_setting_get_member(config, "websockets");
if (!websockets) return KS_STATUS_FAIL;
websockets_endpoints = config_setting_get_member(config, "endpoints");
if (!websockets_endpoints) return KS_STATUS_FAIL;
if (!websockets) {
ks_log(KS_LOG_DEBUG, "!websockets\n");
return KS_STATUS_FAIL;
}
websockets_endpoints = config_setting_get_member(websockets, "endpoints");
if (!websockets_endpoints) {
ks_log(KS_LOG_DEBUG, "!websockets_endpoints\n");
return KS_STATUS_FAIL;
}
websockets_endpoints_ipv4 = config_lookup_from(websockets_endpoints, "ipv4");
websockets_endpoints_ipv6 = config_lookup_from(websockets_endpoints, "ipv6");
if (websockets_endpoints_ipv4) {
......@@ -156,6 +168,10 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config)
config_setting_get_string(tmp1),
config_setting_get_int(tmp2),
AF_INET) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
ks_log(KS_LOG_DEBUG,
"Binding to IPV4 %s on port %d\n",
ks_addr_get_host(&config_websockets_endpoints_ipv4[index]),
ks_addr_get_port(&config_websockets_endpoints_ipv4[index]));
}
}
if (websockets_endpoints_ipv6) {
......@@ -175,6 +191,10 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config)
config_setting_get_string(tmp1),
config_setting_get_int(tmp2),
AF_INET6) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
ks_log(KS_LOG_DEBUG,
"Binding to IPV6 %s on port %d\n",
ks_addr_get_host(&config_websockets_endpoints_ipv6[index]),
ks_addr_get_port(&config_websockets_endpoints_ipv6[index]));
}
}
if (config_websockets_endpoints_ipv4_length + config_websockets_endpoints_ipv6_length <= 0) return KS_STATUS_FAIL;
......@@ -212,13 +232,22 @@ KS_DECLARE(ks_status_t) blade_service_startup(blade_service_t *bs, config_settin
// @todo: If the configuration is invalid, and this is a case of reloading a new config, then the service shutdown shouldn't occur
// but the service may use configuration that changes before we shutdown if it is read successfully, may require a config reader/writer mutex?
if (blade_service_config(bs, config) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_service_config(bs, config) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_service_config failed\n");
return KS_STATUS_FAIL;
}
for (int32_t index = 0; index < bs->config_websockets_endpoints_ipv4_length; ++index) {
if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv4[index]) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv4[index]) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_service_listen (v4) failed\n");
return KS_STATUS_FAIL;
}
}
for (int32_t index = 0; index < bs->config_websockets_endpoints_ipv6_length; ++index) {
if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv6[index]) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv6[index]) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_service_listen (v6) failed\n");
return KS_STATUS_FAIL;
}
}
if (ks_thread_create_ex(&bs->listeners_thread,
......@@ -282,20 +311,23 @@ ks_status_t blade_service_listen(blade_service_t *bs, ks_sockaddr_t *addr)
ks_assert(addr);
if ((listener = socket(addr->family, SOCK_STREAM, IPPROTO_TCP)) == KS_SOCK_INVALID) {
ks_log(KS_LOG_DEBUG, "listener == KS_SOCK_INVALID\n");
ret = KS_STATUS_FAIL;
goto done;
}
ks_socket_option(listener, SO_REUSEADDR, KS_TRUE);
ks_socket_option(listener, TCP_NODELAY, KS_TRUE);
// @todo make sure v6 does not automatically map to a v4 using socket option IPV6_V6ONLY?
if (addr->family == AF_INET6) ks_socket_option(listener, IPV6_V6ONLY, KS_TRUE);
if (ks_addr_bind(listener, addr) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "ks_addr_bind(listener, addr) != KS_STATUS_SUCCESS\n");
ret = KS_STATUS_FAIL;
goto done;
}
if (listen(listener, bs->config_websockets_endpoints_backlog) != 0) {
ks_log(KS_LOG_DEBUG, "listen(listener, backlog) != 0\n");
ret = KS_STATUS_FAIL;
goto done;
}
......@@ -327,6 +359,8 @@ void *blade_service_listeners_thread(ks_thread_t *thread, void *data)
ks_assert(data);
service = (blade_service_t *)data;
ks_log(KS_LOG_DEBUG, "Service running\n");
// @todo 1 more callback for blade_service_state_callback_t? providing event up the stack on service startup, shutdown, and service errors?
......
......@@ -147,18 +147,27 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_
{
ks_assert(bh);
if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_handle_config failed\n");
return KS_STATUS_FAIL;
}
if (bh->config_service && !blade_handle_service_available(bh)) {
blade_service_create(&bh->service, bh->pool, bh->tpool, bh, service_peer_state_callback);
ks_assert(bh->service);
if (blade_service_startup(bh->service, bh->config_service) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_service_startup(bh->service, bh->config_service) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_service_startup failed\n");
return KS_STATUS_FAIL;
}
}
if (bh->config_datastore && !blade_handle_datastore_available(bh)) {
blade_datastore_create(&bh->datastore, bh->pool, bh->tpool);
ks_assert(bh->datastore);
if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "blade_datastore_startup failed\n");
return KS_STATUS_FAIL;
}
}
return KS_STATUS_SUCCESS;
......
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0
TEST_LDADD = $(abs_top_builddir)/libblade.la
TEST_LDADD = $(abs_top_builddir)/libblade.la -lconfig -lm -lpthread
check_PROGRAMS =
check_PROGRAMS += testbuild
......
#! /bin/bash
# bladec - temporary wrapper script for .libs/bladec
# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.11
#
# The bladec program cannot be directly executed until all the libtool
# libraries that it depends on are installed.
#
# This wrapper script should never be moved out of the build directory.
# If it is, it will not operate correctly.
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
fi
BIN_SH=xpg4; export BIN_SH # for Tru64
DUALCASE=1; export DUALCASE # for MKS sh
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
relink_command="(cd /usr/src/freeswitch/libs/libblade/test; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/lib/ccache:/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin; export PATH; gcc -fPIC -Wall -std=c99 -pedantic -DUSE_SCHED_SETSCHEDULER=1 -DKS_API_VISIBILITY=1 -fvisibility=hidden -Werror -DHAVE_PTHREAD_SETSCHEDPARAM=1 -DHAVE_OPENSSL -fsanitize=address -fno-omit-frame-pointer -I/usr/src/freeswitch/libs/libblade/src/include -g -ggdb -O0 -g -O2 -fsanitize=address -o \$progdir/\$file bladec-bladec.o bladec-tap.o -L/usr/src/freeswitch/libs/libblade/../libks/.libs/ /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.so -lsodium /usr/src/freeswitch/libs/libblade/.libs/libblade.so -lconfig -lm -lpthread -lssl -lcrypto -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/../libks/.libs/ -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/.libs)"
# This environment variable determines our operation mode.
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
# install mode needs the following variables:
generated_by_libtool_version='2.4.2'
notinst_deplibs=' /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.la /usr/src/freeswitch/libs/libblade/libblade.la'
else
# When we are sourced in execute mode, $file and $ECHO are already set.
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
file="$0"
# A function that is used when there is no print builtin or printf.
func_fallback_echo ()
{
eval 'cat <<_LTECHO_EOF
$1
_LTECHO_EOF'
}
ECHO="printf %s\\n"
fi
# Very basic option parsing. These options are (a) specific to
# the libtool wrapper, (b) are identical between the wrapper
# /script/ and the wrapper /executable/ which is used only on
# windows platforms, and (c) all begin with the string --lt-
# (application programs are unlikely to have options which match
# this pattern).
#
# There are only two supported options: --lt-debug and
# --lt-dump-script. There is, deliberately, no --lt-help.
#
# The first argument to this parsing function should be the
# script's ../libtool value, followed by no.
lt_option_debug=
func_parse_lt_options ()
{
lt_script_arg0=$0
shift
for lt_opt
do
case "$lt_opt" in
--lt-debug) lt_option_debug=1 ;;
--lt-dump-script)
lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
cat "$lt_dump_D/$lt_dump_F"
exit 0
;;
--lt-*)
$ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
exit 1
;;
esac
done
# Print the debug banner immediately:
if test -n "$lt_option_debug"; then
echo "bladec:bladec:${LINENO}: libtool wrapper (GNU libtool) 2.4.2 Debian-2.4.2-1.11" 1>&2
fi
}
# Used when --lt-debug. Prints its arguments to stdout
# (redirection is the responsibility of the caller)
func_lt_dump_args ()
{
lt_dump_args_N=1;
for lt_arg
do
$ECHO "bladec:bladec:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
lt_dump_args_N=`expr $lt_dump_args_N + 1`
done
}
# Core function for launching the target application
func_exec_program_core ()
{
if test -n "$lt_option_debug"; then
$ECHO "bladec:bladec:${LINENO}: newargv[0]: $progdir/$program" 1>&2
func_lt_dump_args ${1+"$@"} 1>&2
fi
exec "$progdir/$program" ${1+"$@"}
$ECHO "$0: cannot exec $program $*" 1>&2
exit 1
}
# A function to encapsulate launching the target application
# Strips options in the --lt-* namespace from $@ and
# launches target application with the remaining arguments.
func_exec_program ()
{
case " $* " in
*\ --lt-*)
for lt_wr_arg
do
case $lt_wr_arg in
--lt-*) ;;
*) set x "$@" "$lt_wr_arg"; shift;;
esac
shift
done ;;
esac
func_exec_program_core ${1+"$@"}
}
# Parse options
func_parse_lt_options "$0" ${1+"$@"}
# Find the directory that this script lives in.
thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
test "x$thisdir" = "x$file" && thisdir=.
# Follow symbolic links until we get to the real thisdir.
file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
while test -n "$file"; do
destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
# If there was a directory component, then change thisdir.
if test "x$destdir" != "x$file"; then
case "$destdir" in
[\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
*) thisdir="$thisdir/$destdir" ;;
esac
fi
file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
done
# Usually 'no', except on cygwin/mingw when embedded into
# the cwrapper.
WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
# special case for '.'
if test "$thisdir" = "."; then
thisdir=`pwd`
fi
# remove .libs from thisdir
case "$thisdir" in
*[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
.libs ) thisdir=. ;;
esac
fi
# Try to get the absolute directory name.
absdir=`cd "$thisdir" && pwd`
test -n "$absdir" && thisdir="$absdir"
program=lt-'bladec'
progdir="$thisdir/.libs"
if test ! -f "$progdir/$program" ||
{ file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
test "X$file" != "X$progdir/$program"; }; then
file="$$-$program"
if test ! -d "$progdir"; then
mkdir "$progdir"
else
rm -f "$progdir/$file"
fi
# relink executable if necessary
if test -n "$relink_command"; then
if relink_command_output=`eval $relink_command 2>&1`; then :
else
printf %s\n "$relink_command_output" >&2
rm -f "$progdir/$file"
exit 1
fi
fi
mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
{ rm -f "$progdir/$program";
mv -f "$progdir/$file" "$progdir/$program"; }
rm -f "$progdir/$file"
fi
if test -f "$progdir/$program"; then
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
# Run the actual program with our arguments.
func_exec_program ${1+"$@"}
fi
else
# The program doesn't exist.
$ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
$ECHO "This script is just a wrapper for $program." 1>&2
$ECHO "See the libtool documentation for more information." 1>&2
exit 1
fi
fi
......@@ -16,6 +16,7 @@ char g_console_input[CONSOLE_INPUT_MAX];
size_t g_console_input_length = 0;
size_t g_console_input_eol = 0;
void service_peer_state_callback(blade_service_t *service, blade_peer_t *peer, blade_peerstate_t state);
void loop(blade_handle_t *bh);
void process_console_input(blade_handle_t *bh, char *line);
......@@ -40,10 +41,11 @@ static const struct command_def_s command_defs[] = {
{ NULL, NULL }
};
int main(int argc, char **argv)
{
blade_handle_t *bh = NULL;
config_t config;
config_setting_t *config_blade = NULL;
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
......@@ -51,8 +53,31 @@ int main(int argc, char **argv)
blade_handle_create(&bh, NULL, NULL);
loop(bh);
// @todo load config file, and lookup "blade" setting to put into config_blade
config_init(&config);
if (!config_read_file(&config, "bladec.cfg")) {
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;
}
if (blade_handle_startup(bh, config_blade, service_peer_state_callback) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_ERROR, "Blade startup failed\n");
return EXIT_FAILURE;
}
loop(bh);
blade_handle_destroy(&bh);
blade_shutdown();
......@@ -60,6 +85,12 @@ int main(int argc, char **argv)
return 0;
}
void service_peer_state_callback(blade_service_t *service, blade_peer_t *peer, blade_peerstate_t state)
{
// @todo log output and pop peer messages if state == BLADE_PEERSTATE_RECEIVING
ks_log(KS_LOG_INFO, "service peer state callback: %d\n", (int)state);
}
void buffer_console_input(void)
{
ssize_t bytes = 0;
......@@ -110,7 +141,6 @@ void loop(blade_handle_t *bh)
// @todo lines must not exceed 512 bytes, treat as error and ignore buffer until next new line?
ks_assert(0);
}
blade_handle_pulse(bh);
}
}
......@@ -175,8 +205,6 @@ void command_store(blade_handle_t *bh, char *args)
ks_assert(args);
blade_handle_datastore_startup(bh, NULL);
parse_argument(&args, &key, ' ');
parse_argument(&args, &data, ' ');
......@@ -195,8 +223,6 @@ void command_fetch(blade_handle_t *bh, char *args)
ks_assert(args);
blade_handle_datastore_startup(bh, NULL);
parse_argument(&args, &key, ' ');
blade_handle_datastore_fetch(bh, blade_datastore_fetch_callback, key, strlen(key), bh);
......
blade:
{
# client stuff, for peers who connect out to services
client:
{
directory:
{
# todo: hints for ways to find a directory service, at least kws client_data for now
# add DNS SRV in the future
uri = "???:127.0.0.1+2100:???"; # todo: confirm expected format, "uri:host:proto"
websocket:
{
# SSL group is optional, disabled when absent
ssl:
{
# todo: client SSL stuffs here
};
};
};
};
# server stuff, for services that peers connect to
# todo: consider encapsulating in a "server" group for organizational structure
datastore:
{
database:
{
path = ":mem:";
};
};
service:
{
websockets:
{
endpoints:
{
ipv4 = ( { address = "0.0.0.0", port = 2100 } );
ipv6 = ( { address = "::", port = 2100 } );
backlog = 128;
};
# SSL group is optional, disabled when absent
ssl:
{
# todo: service SSL stuffs here
};
};
};
};
......@@ -121,6 +121,15 @@ KS_DECLARE(ks_status_t) ks_socket_option(ks_socket_t socket, int option_name, ks
#endif
}
break;
case IPV6_V6ONLY:
#ifdef WIN32
#warning make sure windows works like linux for IPV6 to IPV4 automapping stuff
result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, (char *)&opt, sizeof(opt));
#else
result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
#endif
if (!result) status = KS_STATUS_SUCCESS;
break;
default:
break;
}
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论