mirror of
https://github.com/bmx-routing/bmx7
synced 2025-10-06 00:02:44 +02:00
BMX7 initial release candidate
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
*.o
|
||||
*.so
|
||||
bmx6
|
||||
core
|
||||
gmon.out
|
16
Android.mk
Normal file
16
Android.mk
Normal file
@@ -0,0 +1,16 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
include $(LOCAL_PATH)/Common.mk
|
||||
|
||||
LOCAL_SRC_FILES := $(SRC_C)
|
||||
|
||||
# -pedantic yields a lot of warnings from the NDK includes
|
||||
LOCAL_CFLAGS := $(filter-out -pedantic,$(CFLAGS))
|
||||
|
||||
# Separate, since changing it on its own will break the Android app
|
||||
LOCAL_MODULE := bmx6
|
||||
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
6
Application.mk
Normal file
6
Application.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
# Older platforms don't have fdprintf and vfdprintf
|
||||
APP_PLATFORM := android-8
|
||||
|
||||
# GCC 4.8/4.9 build arm binaries that crashed due to memory alignment issues.
|
||||
# Clang build binaries that ran fine.
|
||||
NDK_TOOLCHAIN_VERSION := clang
|
85
Common.mk
Normal file
85
Common.mk
Normal file
@@ -0,0 +1,85 @@
|
||||
GIT_REV ?= $(shell [ -r .git ] && git --no-pager log -n 1 --oneline | cut -d " " -f 1 || echo 0)
|
||||
|
||||
CFLAGS += -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -DGIT_REV=\"$(GIT_REV)\"
|
||||
# CFLAGS += -DHAVE_CONFIG_H
|
||||
# CFLAGS += -DCRYPTLIB=POLARSSL_1_3_4 # POLARSSL_1_2_5 POLARSSL_1_2_9 POLARSSL_1_3_3 POLARSSL_1_3_4 CYASSL_2_8_0
|
||||
|
||||
# optinal defines:
|
||||
# CFLAGS += -static
|
||||
# CFLAGS += -pg # "-pg" with openWrt causes "gcrt1.o: No such file"! Needs ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p, grep: http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html
|
||||
|
||||
# paranoid defines (helps bug hunting during development):
|
||||
# CFLAGS += -DEXTREME_PARANOIA -DEXIT_ON_ERROR -DPROFILING
|
||||
|
||||
# CFLAGS += -DNO_KEY_GEN # use openssl instead, like:
|
||||
# openssl genrsa -out /etc/bmx6/rsa.pem 1024
|
||||
# openssl rsa -in /etc/bmx6/rsa.pem -inform PEM -out /etc/bmx6/rsa.der -outform DER
|
||||
|
||||
# Some test cases:
|
||||
# CFLAGS += -DTEST_LINK_ID_COLLISION_DETECTION
|
||||
# CFLAGS += -DTEST_DEBUG # (testing syntax of __VA_ARGS__ dbg...() macros)
|
||||
# CFLAGS += -DTEST_DEBUG_MALLOC # allocates a never freed byte which should be reported at bmx6 termination
|
||||
# CFLAGS += -DAVL_5XLINKED -DAVL_DEBUG -DAVL_TEST
|
||||
|
||||
# optional defines (you may disable these features if you dont need them)
|
||||
# CFLAGS += -DNO_DEBUG_TRACK
|
||||
# CFLAGS += -DNO_DEBUG_SYS
|
||||
# CFLAGS += -DLESS_OPTIONS
|
||||
# CFLAGS += -DNO_DYN_PLUGIN
|
||||
# CFLAGS += -DNO_TRACE_FUNCTION_CALLS
|
||||
|
||||
# CFLAGS += -DDEBUG_ALL
|
||||
# CFLAGS += -DTRAFFIC_DUMP
|
||||
# CFLAGS += -DDEBUG_DUMP
|
||||
# CFLAGS += -DDEBUG_MALLOC
|
||||
# CFLAGS += -DMEMORY_USAGE
|
||||
|
||||
# experimental or advanced defines (please dont touch):
|
||||
# CFLAGS += -DNO_ASSERTIONS # (disable syntax error checking and error-code creation!)
|
||||
# CFLAGS += -DEXTREME_PARANOIA # (check difficult syntax errors)
|
||||
# CFLAGS += -DEXIT_ON_ERROR # (exit and return code due to unusual behavior)
|
||||
# CFLAGS += -DTEST_DEBUG
|
||||
# CFLAGS += -DWITH_UNUSED # (includes yet unused stuff and buggy stuff)
|
||||
# CFLAGS += -DPROFILING # (no static functions -> better profiling and cores)
|
||||
# CFLAGS += -DNO_CTAOCRYPT_DIR # for backward compatibility with old cyassl versions
|
||||
# CFLAGS += -DCORE_LIMIT=20000 # equals ulimit -c 20000
|
||||
|
||||
#EXTRA_CFLAGS +=
|
||||
#EXTRA_LDFLAGS +=
|
||||
|
||||
# add as much features and test cases as possible:
|
||||
#EXTRA_CFLAGS += -DMOST
|
||||
|
||||
#for profiling:
|
||||
#EXTRA_CFLAGS="-DPROFILING -pg"
|
||||
|
||||
#for very poor embedded stuff (reducing binary size and cpu footprint):
|
||||
#EXTRA_CFLAGS="-DNO_DEBUG_TRACK -DNO_TRACE_FUNCTION_CALLS -DNO_ASSERTIONS"
|
||||
|
||||
#for small embedded stuff the defaults are just fine.
|
||||
|
||||
#for normal machines (adding features and facilitating debugging):
|
||||
#EXTRA_CFLAGS="-DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DEBUG_MALLOC -DMEMORY_USAGE"
|
||||
|
||||
CFLAGS += $(shell echo "$(EXTRA_CFLAGS)" | grep -q "DMOST" && echo "-pg -DCORE_LIMIT=20000 -DEXTREME_PARANOIA -DEXIT_ON_ERROR -DPROFILING -DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DDEBUG_MALLOC -DMEMORY_USAGE " )
|
||||
|
||||
LDFLAGS += -g3
|
||||
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DNO_DYNPLUGIN" || echo "-Wl,-export-dynamic -ldl" )
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DPROFILING" && echo "-pg -lc" )
|
||||
|
||||
LDFLAGS += -lz -lm
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "CYASSL" && echo "-lcyassl" || echo "-lpolarssl")
|
||||
|
||||
SBINDIR = $(INSTALL_PREFIX)/usr/sbin
|
||||
|
||||
SRC_C = bmx.c key.c node.c crypt.c sec.c content.c msg.c z.c desc.c metrics.c ogm.c link.c iptools.c tools.c plugin.c list.c allocate.c avl.c hna.c control.c schedule.c ip.c prof.c
|
||||
SRC_H = bmx.h key.h node.h crypt.h sec.h content.h msg.h z.h desc.h metrics.h ogm.h link.h iptools.h tools.h plugin.h list.h allocate.h avl.h hna.h control.h schedule.h ip.h prof.h
|
||||
|
||||
SRC_C += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.c )
|
||||
SRC_H += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.h )
|
||||
|
||||
OBJS = $(SRC_C:.c=.o)
|
||||
|
||||
PACKAGE_NAME := bmx6
|
||||
BINARY_NAME := bmx6
|
104
Makefile
104
Makefile
@@ -14,102 +14,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA
|
||||
|
||||
|
||||
GIT_REV = $(shell ( [ "$(REVISION_VERSION)" ] && echo "$(REVISION_VERSION)" ) || ( [ -d .git ] && git --no-pager log -n 1 --oneline|cut -d " " -f 1 ) || echo 0)
|
||||
CFLAGS += -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99
|
||||
CFLAGS += -DHAVE_CONFIG_H
|
||||
CFLAGS += -DGIT_REV=\"$(GIT_REV)\"
|
||||
# CFLAGS += -DCRYPTLIB=POLARSSL_1_2_5 # POLARSSL_1_2_5 POLARSSL_1_2_9 POLARSSL_1_3_3 CYASSL_2_8_0
|
||||
#-DHAVE_CONFIG_H
|
||||
|
||||
# optinal defines:
|
||||
# CFLAGS += -static
|
||||
# CFLAGS += -pg # "-pg" with openWrt causes "gcrt1.o: No such file"! Needs ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p, grep: http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html
|
||||
|
||||
|
||||
# paranoid defines (helps bug hunting during development):
|
||||
# CFLAGS += -DEXTREME_PARANOIA -DEXIT_ON_ERROR -DPROFILING
|
||||
|
||||
# Some test cases:
|
||||
# CFLAGS += -DTEST_LINK_ID_COLLISION_DETECTION
|
||||
# CFLAGS += -DTEST_DEBUG # (testing syntax of __VA_ARGS__ dbg...() macros)
|
||||
# CFLAGS += -DTEST_DEBUG_MALLOC # allocates a never freed byte which should be reported at bmx6 termination
|
||||
# CFLAGS += -DAVL_5XLINKED -DAVL_DEBUG -DAVL_TEST
|
||||
|
||||
# optional defines (you may disable these features if you dont need them)
|
||||
# CFLAGS += -DNO_KEY_GEN # use openssl instead, like:
|
||||
# openssl genrsa -out /etc/bmx6/rsa.pem 1024
|
||||
# openssl rsa -in /etc/bmx6/rsa.pem -inform PEM -out /etc/bmx6/rsa.der -outform DER
|
||||
|
||||
# CFLAGS += -DNO_DEBUG_TRACK
|
||||
# CFLAGS += -DNO_DEBUG_SYS
|
||||
# CFLAGS += -DLESS_OPTIONS
|
||||
# CFLAGS += -DNO_DYN_PLUGIN
|
||||
# CFLAGS += -DNO_TRACE_FUNCTION_CALLS
|
||||
|
||||
# CFLAGS += -DDEBUG_ALL
|
||||
# CFLAGS += -DTRAFFIC_DUMP
|
||||
# CFLAGS += -DDEBUG_DUMP
|
||||
# CFLAGS += -DDEBUG_MALLOC
|
||||
# CFLAGS += -DMEMORY_USAGE
|
||||
|
||||
# experimental or advanced defines (please dont touch):
|
||||
# CFLAGS += -DNO_ASSERTIONS # (disable syntax error checking and error-code creation!)
|
||||
# CFLAGS += -DEXTREME_PARANOIA # (check difficult syntax errors)
|
||||
# CFLAGS += -DEXIT_ON_ERROR # (exit and return code due to unusual behavior)
|
||||
# CFLAGS += -DTEST_DEBUG
|
||||
# CFLAGS += -DWITH_UNUSED # (includes yet unused stuff and buggy stuff)
|
||||
# CFLAGS += -DPROFILING # (no static functions -> better profiling and cores)
|
||||
# CFLAGS += -DNO_CTAOCRYPT_DIR # for backward compatibility with old cyassl versions
|
||||
# CFLAGS += -DCORE_LIMIT=20000 # equals ulimit -c 20000
|
||||
|
||||
#EXTRA_CFLAGS +=
|
||||
#EXTRA_LDFLAGS +=
|
||||
|
||||
# add as much features and test cases as possible:
|
||||
#EXTRA_CFLAGS += -DMOST
|
||||
|
||||
#for profiling:
|
||||
#EXTRA_CFLAGS="-DPROFILING -pg"
|
||||
|
||||
#for very poor embedded stuff (reducing binary size and cpu footprint):
|
||||
#EXTRA_CFLAGS="-DNO_DEBUG_TRACK -DNO_TRACE_FUNCTION_CALLS -DNO_ASSERTIONS"
|
||||
|
||||
#for small embedded stuff the defaults are just fine.
|
||||
|
||||
#for normal machines (adding features and facilitating debugging):
|
||||
#EXTRA_CFLAGS="-DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DEBUG_MALLOC -DMEMORY_USAGE"
|
||||
|
||||
CFLAGS += $(shell echo "$(EXTRA_CFLAGS)" | grep -q "DMOST" && echo "-pg -DCORE_LIMIT=20000 -DEXTREME_PARANOIA -DEXIT_ON_ERROR -DPROFILING -DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DDEBUG_MALLOC -DMEMORY_USAGE " )
|
||||
|
||||
LDFLAGS += -g3
|
||||
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DNO_DYNPLUGIN" || echo "-Wl,-export-dynamic -ldl" )
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DPROFILING" && echo "-pg -lc" )
|
||||
|
||||
LDFLAGS += -lz -lm
|
||||
LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "CYASSL" && echo "-lcyassl" || echo "-lpolarssl")
|
||||
|
||||
|
||||
|
||||
SBINDIR = $(INSTALL_PREFIX)/usr/sbin
|
||||
|
||||
SRC_FILES= "\(\.c\)\|\(\.h\)\|\(Makefile\)\|\(INSTALL\)\|\(LIESMICH\)\|\(README\)\|\(THANKS\)\|\(./posix\)\|\(./linux\)\|\(./man\)\|\(./doc\)"
|
||||
|
||||
SRC_C = bmx.c node.c crypt.c sec.c msg.c z.c metrics.c iptools.c tools.c plugin.c list.c allocate.c avl.c hna.c control.c schedule.c ip.c prof.c
|
||||
SRC_H = bmx.h node.h crypt.h sec.h msg.h z.h metrics.h iptools.h tools.h plugin.h list.h allocate.h avl.h hna.h control.h schedule.h ip.h prof.h
|
||||
|
||||
SRC_C += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.c )
|
||||
SRC_H += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.h )
|
||||
|
||||
OBJS= $(SRC_C:.c=.o)
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
PACKAGE_NAME= bmx6
|
||||
BINARY_NAME= bmx6
|
||||
include Common.mk
|
||||
|
||||
|
||||
all:
|
||||
@@ -120,7 +25,6 @@ libs: all
|
||||
$(MAKE) -C lib all CORE_CFLAGS='$(CFLAGS)'
|
||||
|
||||
|
||||
|
||||
$(BINARY_NAME): $(OBJS) Makefile
|
||||
$(CC) $(OBJS) -o $@ $(LDFLAGS) $(EXTRA_LDFLAGS)
|
||||
|
||||
@@ -132,14 +36,11 @@ $(BINARY_NAME): $(OBJS) Makefile
|
||||
|
||||
|
||||
strip: all
|
||||
strip $(BINARY_NAME)
|
||||
strip $(BINARY_NAME)
|
||||
|
||||
strip_libs: all libs
|
||||
$(MAKE) -C lib strip
|
||||
|
||||
|
||||
|
||||
|
||||
install: all
|
||||
mkdir -p $(SBINDIR)
|
||||
install -m 0755 $(BINARY_NAME) $(SBINDIR)
|
||||
@@ -148,7 +49,6 @@ install_libs: all
|
||||
$(MAKE) -C lib install CORE_CFLAGS='$(CFLAGS)'
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(BINARY_NAME) *.o posix/*.o linux/*.o cyassl/*.o
|
||||
|
||||
|
71
README.md
71
README.md
@@ -12,10 +12,10 @@ The following intro provides kind of tutorial to get started.
|
||||
* [Autoconfiguration](#address-auto-and-manual-configuration)
|
||||
* [Unicast Host Network Announcements (UHNA)](#unicast-host-network-announcements-uhna)
|
||||
* [Tunnel Announcements](#tunnel-announcements)
|
||||
* [Bmx6 Plugins](#bmx6-plugins)
|
||||
* [Bmx6 Plugins](#bmx6-plugins)
|
||||
* [Config Plugin](#config-plugin)
|
||||
* [Json Plugin](#json-plugin)
|
||||
* [SMS Plugin](#sms-plugin)
|
||||
* [SMS Plugin](#sms-plugin)
|
||||
* [Table plugin](#table-plugin)
|
||||
* [Quagga Plugin](#quagga-plugin)
|
||||
|
||||
@@ -23,7 +23,7 @@ The following intro provides kind of tutorial to get started.
|
||||
Note: This document is written using Markdown syntax. Modifications should be
|
||||
synced via README.md file in bmx6 repositories [bmx6.net][bmx6] and [github.com][github].
|
||||
Nice syntax examples are [here][syntax].
|
||||
|
||||
|
||||
[bmx6]: http://bmx6.net
|
||||
[github]: https://github.com/axn/bmx6
|
||||
[syntax]: http://daringfireball.net/projects/markdown/syntax.text
|
||||
@@ -39,18 +39,19 @@ The following tools are needed to obtain, compile, and install bmx6:
|
||||
* make
|
||||
|
||||
The following Linux-kernel modules are needed (depending on used bmx6 features)
|
||||
* ipv6
|
||||
* ipv6
|
||||
* tunnel6
|
||||
* ip6_tunnel
|
||||
|
||||
The polorssl crypto library is needed for cryptographic operations:
|
||||
Tested with debian and cyassl-2.8.0:
|
||||
Tested with debian and polarssl-1.3.3:
|
||||
<pre>
|
||||
wget https://polarssl.org/code/releases/polarssl-1.3.3-gpl.tgz
|
||||
tar xzvf polarssl-1.3.3-gpl.tgz
|
||||
cd polarssl-1.3.3
|
||||
make
|
||||
make install
|
||||
sudo make install
|
||||
# compile bmx6 with: make EXTRA_CFLAGS="-DCRYPTLIB=POLARSSL1_3_3"
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -156,13 +157,13 @@ Status, network, and statistic information are accessible with dedicated paramet
|
||||
|
||||
<pre>
|
||||
root@mlc1001:~# bmx6 -c status
|
||||
version compatibility codeVersion globalId primaryIp myLocalId uptime cpu nodes
|
||||
version compatibility codeVersion globalId primaryIp myLocalId uptime cpu nodes
|
||||
BMX6-0.1-alpha 16 9 mlc1001.7A7422752001EC4AC4C8 fd66:66:66:0:a2cd:efff:fe10:101 24100101 0:00:40:37 0.1 4
|
||||
</pre>
|
||||
|
||||
So apart from version, compatibility number, and code, the status reveals the daemon's [Global ID](wiki#global-id) and [Local ID](wiki#local-id), its primary (self-configured) IPv6 address, the time since when it is running (40 minutes), its current cpu consumption (0.1%) and the total number of 4 learned nodes in the network (including itself).
|
||||
|
||||
These desired types can be combined. Also the above given example shows kind of shortcut.
|
||||
These desired types can be combined. Also the above given example shows kind of shortcut.
|
||||
The long argument would be:
|
||||
`bmx6 connect show=status`. A more informative case using the long form would be:
|
||||
|
||||
@@ -180,10 +181,10 @@ mlc1000.0AE58311046412F248CD fe80::a2cd:efff:fe10:1 eth1 100 100 1
|
||||
mlc1002.91DCF042934B5913BB00 fe80::a2cd:efff:fe10:201 eth1 100 100 1 2 1 BB100201
|
||||
originators:
|
||||
globalId blocked primaryIp routes viaIp viaDev metric lastDesc lastRef
|
||||
mlc1000.0AE58311046412F248CD 0 fd66:66:66:0:a2cd:efff:fe10:1 1 fe80::a2cd:efff:fe10:1 eth1 999M 3193 3
|
||||
mlc1000.0AE58311046412F248CD 0 fd66:66:66:0:a2cd:efff:fe10:1 1 fe80::a2cd:efff:fe10:1 eth1 999M 3193 3
|
||||
mlc1001.7A7422752001EC4AC4C8 0 fd66:66:66:0:a2cd:efff:fe10:101 0 :: --- 128G 3197 0
|
||||
mlc1002.91DCF042934B5913BB00 0 fd66:66:66:0:a2cd:efff:fe10:201 1 fe80::a2cd:efff:fe10:201 eth1 999M 3196 3
|
||||
mlc1003.09E796BC491D386248C3 0 fd66:66:66:0:a2cd:efff:fe10:301 1 fe80::a2cd:efff:fe10:201 eth1 576M 22 3
|
||||
mlc1002.91DCF042934B5913BB00 0 fd66:66:66:0:a2cd:efff:fe10:201 1 fe80::a2cd:efff:fe10:201 eth1 999M 3196 3
|
||||
mlc1003.09E796BC491D386248C3 0 fd66:66:66:0:a2cd:efff:fe10:301 1 fe80::a2cd:efff:fe10:201 eth1 576M 22 3
|
||||
</pre>
|
||||
|
||||
Only if relevant information for a requested type is available it will be shown.
|
||||
@@ -282,19 +283,19 @@ Checking new status of interfaces, links, and originator:
|
||||
<pre>
|
||||
root@mlc1001:~# bmx6 -cd8
|
||||
status:
|
||||
version compatibility codeVersion globalId primaryIp myLocalId uptime cpu nodes
|
||||
BMX6-0.1-alpha 16 9 mlc1001.7A7422752001EC4AC4C8 fd66:66:66:0:a2cd:efff:fe10:102 06100101 0:02:26:00 0.1 4
|
||||
version compatibility codeVersion globalId primaryIp myLocalId uptime cpu nodes
|
||||
BMX6-0.1-alpha 16 9 mlc1001.7A7422752001EC4AC4C8 fd66:66:66:0:a2cd:efff:fe10:102 06100101 0:02:26:00 0.1 4
|
||||
interfaces:
|
||||
devName state type rateMin rateMax llocalIp globalIp multicastIp primary
|
||||
eth2 UP ethernet 100M 100M fe80::a2cd:efff:fe10:102/64 fd66:66:66:0:a2cd:efff:fe10:102/64 ff02::2 1
|
||||
devName state type rateMin rateMax llocalIp globalIp multicastIp primary
|
||||
eth2 UP ethernet 100M 100M fe80::a2cd:efff:fe10:102/64 fd66:66:66:0:a2cd:efff:fe10:102/64 ff02::2 1
|
||||
links:
|
||||
globalId llocalIp viaDev rxRate txRate bestTxLink routes wantsOgms nbLocalId
|
||||
mlc1000.0AE58311046412F248CD fe80::a2cd:efff:fe10:2 eth2 89 88 1 3 1 9B100001
|
||||
globalId llocalIp viaDev rxRate txRate bestTxLink routes wantsOgms nbLocalId
|
||||
mlc1000.0AE58311046412F248CD fe80::a2cd:efff:fe10:2 eth2 89 88 1 3 1 9B100001
|
||||
originators:
|
||||
globalId blocked primaryIp routes viaIp viaDev metric lastDesc lastRef
|
||||
mlc1000.0AE58311046412F248CD 0 fd66:66:66:0:a2cd:efff:fe10:1 1 fe80::a2cd:efff:fe10:2 eth2 81757K 18 0
|
||||
mlc1001.7A7422752001EC4AC4C8 0 fd66:66:66:0:a2cd:efff:fe10:102 0 :: --- 128G 80 0
|
||||
mlc1002.91DCF042934B5913BB00 0 fd66:66:66:0:a2cd:efff:fe10:201 1 fe80::a2cd:efff:fe10:2 eth2 83620K 14 4
|
||||
globalId blocked primaryIp routes viaIp viaDev metric lastDesc lastRef
|
||||
mlc1000.0AE58311046412F248CD 0 fd66:66:66:0:a2cd:efff:fe10:1 1 fe80::a2cd:efff:fe10:2 eth2 81757K 18 0
|
||||
mlc1001.7A7422752001EC4AC4C8 0 fd66:66:66:0:a2cd:efff:fe10:102 0 :: --- 128G 80 0
|
||||
mlc1002.91DCF042934B5913BB00 0 fd66:66:66:0:a2cd:efff:fe10:201 1 fe80::a2cd:efff:fe10:2 eth2 83620K 14 4
|
||||
mlc1003.09E796BC491D386248C3 0 fd66:66:66:0:a2cd:efff:fe10:301 1 fe80::a2cd:efff:fe10:2 eth2 81488K 9 0
|
||||
</pre>
|
||||
|
||||
@@ -346,10 +347,10 @@ the EUI64 suffix (the suffix creation is currently reconsidered and may change s
|
||||
The same first 56 bits but extended with 0xff00 are also used to create tunnel interfaces.
|
||||
|
||||
There are different options to controll the auto configuration.
|
||||
1. A different auto-configuration prefix can be used using the <pre> --ipAutoPrefix </pre>
|
||||
1. A different auto-configuration prefix can be used using the <pre> --ipAutoPrefix </pre>
|
||||
option given with a /56 prefix.
|
||||
|
||||
2. Auto configuratin can be disabled using the <pre> --globalPrefix </pre> option.
|
||||
2. Auto configuratin can be disabled using the <pre> --globalPrefix </pre> option.
|
||||
Then bmx6 checks if an ip in this range is alredy configured on the interfaces and uses it.
|
||||
If no IP is configured in the given range then the inteface will NOT be used.
|
||||
|
||||
@@ -431,7 +432,7 @@ Therefore, each announcements message is decorated with a route-type field indic
|
||||
### Tunnel requirements ###
|
||||
|
||||
The following Linux-kernel modules are needed for tunnel-based overlay networking:
|
||||
* ipv6
|
||||
* ipv6
|
||||
* tunnel6
|
||||
* ip6_tunnel
|
||||
|
||||
@@ -496,11 +497,11 @@ With the above configured tunnel selection policy, tunnels are selected in the f
|
||||
1. prefix-length of announced tunnels (networks that are more specific than others).
|
||||
2. the resulting tunnelMetric (combination of the advertised bandwidth, path metric in the bmx6 cloud, and locally specified prefereces like hysteresis or bonus)
|
||||
|
||||
The disadvantage of this simple config is that other nodes can easily redirect your tunnel selections
|
||||
to specific networks by announcing more precise tunnel networks (larger prefix length).
|
||||
The disadvantage of this simple config is that other nodes can easily redirect your tunnel selections
|
||||
to specific networks by announcing more precise tunnel networks (larger prefix length).
|
||||
To prevent this, the selection policy can be split into several and more precise search directives.
|
||||
|
||||
Imagine the following address assignment policy for IPv4 tunnel addresses in a mesh cloud (the general
|
||||
Imagine the following address assignment policy for IPv4 tunnel addresses in a mesh cloud (the general
|
||||
idea can be straight translated to IPv6).
|
||||
|
||||
* Nodes in the mesh cloud announce their private and local address ranges with a prefix length of 24 and somewhere in the range of 10.254.0.0/16.
|
||||
@@ -531,13 +532,13 @@ idea can be straight translated to IPv6).
|
||||
* The default route announcements from two well known GWs (with hostname pepe and paula) should be strictly preferred over unknown GWs.
|
||||
* So, if available, move them to new table (with lower priority than main and higher priority than used for the backup tunnel rule configured above)
|
||||
<pre>
|
||||
bmx6 -c tunOut=v4DefaultPepe /network=0.0.0.0/0 /maxPrefixLen=0 /name=pepe /hysteresis=30 /tableRule=40000/140
|
||||
bmx6 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /name=paula /hysteresis=30 /tableRule=40000/140
|
||||
bmx6 -c tunOut=v4DefaultPepe /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=pepe /hysteresis=30 /tableRule=40000/140
|
||||
bmx6 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=paula /hysteresis=30 /tableRule=40000/140
|
||||
</pre>
|
||||
|
||||
* Finally, GW Paula turned out to be more stable. Therefore I want to prefer GW Paula over Pepe:
|
||||
<pre>
|
||||
bmx6 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /name=paula /hysteresis=30 /bonus=100
|
||||
bmx6 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=paula /hysteresis=30 /bonus=100
|
||||
</pre>
|
||||
|
||||
#### Gateway Nodes ####
|
||||
@@ -576,7 +577,7 @@ These requirements are described in the corresponding plugin section.
|
||||
#### Requirements ####
|
||||
|
||||
uci libs are needed for the bmx6-config plugin.
|
||||
To install it do:
|
||||
To install try (old version):
|
||||
<pre>
|
||||
wget http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz
|
||||
tar xzvf uci-0.7.5.tar.gz
|
||||
@@ -584,13 +585,15 @@ cd uci-0.7.5
|
||||
make
|
||||
sudo make install
|
||||
</pre>
|
||||
or check: http://www.wakoond.hu/2013/06/using-uci-on-ubuntu.html
|
||||
|
||||
|
||||
Depending on your system there happens to be an error during compilation.
|
||||
Then edit cli.c and change line 465 to: char *argv[MAX_ARGS+2];
|
||||
|
||||
#### Compile and Install ####
|
||||
<pre>
|
||||
make -C lib/bmx6_uci_config/
|
||||
make -C lib/bmx6_uci_config/
|
||||
sudo make -C lib/bmx6_uci_config/ install
|
||||
</pre>
|
||||
|
||||
@@ -621,7 +624,7 @@ cd json-c..
|
||||
|
||||
To compile and install only the bmx6 json plugins:
|
||||
<pre>
|
||||
make -C lib/bmx6_json/
|
||||
make -C lib/bmx6_json/
|
||||
sudo make -C lib/bmx6_json/ install
|
||||
</pre>
|
||||
|
||||
@@ -720,7 +723,7 @@ the file lib/bmx6_quagga/patches/README in the bmx6 sources.
|
||||
|
||||
To compile and install the bmx6 part of the quagga plugin simply do:
|
||||
<pre>
|
||||
make -C lib/bmx6_quagga/
|
||||
make -C lib/bmx6_quagga/
|
||||
sudo make -C lib/bmx6_quagga/ install
|
||||
</pre>
|
||||
|
||||
|
21
allocate.c
21
allocate.c
@@ -209,10 +209,12 @@ void *_debugMalloc(uint32_t length, int32_t tag, uint8_t reset)
|
||||
if (!length)
|
||||
return NULL;
|
||||
|
||||
if (reset)
|
||||
memory = calloc(1, length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T));
|
||||
else
|
||||
if (reset) {
|
||||
memory = malloc(length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T));
|
||||
memset(memory, 0, length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T));
|
||||
} else {
|
||||
memory = malloc(length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T));
|
||||
}
|
||||
|
||||
if (memory == NULL)
|
||||
{
|
||||
@@ -338,7 +340,9 @@ void _debugFree(void *memoryParameter, int tag)
|
||||
|
||||
#endif //#ifdef MEMORY_USAGE
|
||||
|
||||
free(chunkHeader);
|
||||
if (!terminating)
|
||||
free(chunkHeader);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -349,7 +353,9 @@ void * _malloc( size_t length ) {
|
||||
}
|
||||
|
||||
void * _calloc( size_t length ) {
|
||||
return calloc( 1, length );
|
||||
void *mem = malloc( length );
|
||||
memset( mem, 0, length);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void * _realloc( void *mem, size_t length ) {
|
||||
@@ -357,8 +363,9 @@ void * _realloc( void *mem, size_t length ) {
|
||||
}
|
||||
|
||||
void _free( void *mem ) {
|
||||
free( mem );
|
||||
if (!terminating)
|
||||
free( mem );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -29,7 +29,7 @@ extern uint32_t debugMalloc_objects;
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
// currently used memory tags: -300000, -300001 .. -300664
|
||||
// currently used memory tags: -300000, -300001 .. -300768
|
||||
#define debugMalloc( length,tag ) _debugMalloc( (length), (tag), 0 )
|
||||
#define debugMallocReset( length,tag ) _debugMalloc( (length), (tag), 1 )
|
||||
#define debugRealloc( mem,length,tag ) _debugRealloc( (mem), (length), (tag) )
|
||||
|
6
avl.c
6
avl.c
@@ -267,6 +267,7 @@ struct avl_node *avl_rotate_double(struct avl_node *root, int dir)
|
||||
|
||||
void avl_insert(struct avl_tree *tree, void *node, int32_t tag)
|
||||
{
|
||||
ASSERTION(-502234, !avl_find_item(tree, AVL_ITEM_KEY(tree, node)));
|
||||
|
||||
struct avl_node *new = NULL;
|
||||
|
||||
@@ -363,6 +364,7 @@ void avl_insert(struct avl_tree *tree, void *node, int32_t tag)
|
||||
assertion(-502005, (!new->left || avl_next(tree, AVL_ITEM_KEY(tree, new->left->item))==new));
|
||||
assertion(-502006, (!new->right || avl_next(tree, AVL_ITEM_KEY(tree, new->item))==new->right));
|
||||
#endif
|
||||
ASSERTION(-502236, avl_find_item(tree, AVL_ITEM_KEY(tree, node)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -381,7 +383,7 @@ void *avl_remove(struct avl_tree *tree, void *key, int32_t tag)
|
||||
return NULL;
|
||||
|
||||
while (1) {
|
||||
|
||||
/*
|
||||
dbgf_all(DBGT_INFO, "tree.items=%d it->item=%p memcmp(it,key)=%d link[0]=%p link[1]=%p memcmp(link[0],key)=%d memcmp(link[1],key)=%d",
|
||||
tree->items, it->item,
|
||||
memcmp(AVL_NODE_KEY(tree, it), key, tree->key_size),
|
||||
@@ -389,7 +391,7 @@ void *avl_remove(struct avl_tree *tree, void *key, int32_t tag)
|
||||
(it->down[0] ? memcmp(AVL_NODE_KEY(tree, it->down[0]), key, tree->key_size) : -1),
|
||||
(it->down[1] ? memcmp(AVL_NODE_KEY(tree, it->down[1]), key, tree->key_size) : -1)
|
||||
);
|
||||
|
||||
*/
|
||||
if (!(
|
||||
(cmp = memcmp(AVL_NODE_KEY(tree, it), key, tree->key_size)) ||
|
||||
(it->down[0] && !memcmp(AVL_NODE_KEY(tree, it->down[0]), key, tree->key_size))))
|
||||
|
149
bmx.h
149
bmx.h
@@ -17,6 +17,8 @@
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
@@ -33,6 +35,18 @@ typedef int8_t IDM_T; // smallest int which size does NOT matter
|
||||
* dont touch this for compatibility reasons:
|
||||
*/
|
||||
|
||||
/* Android has these under a different name since the NDK target android-8:
|
||||
*
|
||||
* glibc defines dprintf(int, const char*, ...), which is poorly named
|
||||
* and likely to conflict with locally defined debugging printfs
|
||||
* fdprintf is a better name, and some programs that use fdprintf use a
|
||||
* #define fdprintf dprintf for compatibility
|
||||
*/
|
||||
#ifdef __ANDROID__
|
||||
#define dprintf fdprintf
|
||||
#define vdprintf vfdprintf
|
||||
#endif
|
||||
|
||||
#define BMX_BRANCH "BMX6"
|
||||
#define BRANCH_VERSION "0.1-alpha" //put exactly one distinct word inside the string like "0.3-pre-alpha" or "0.3-rc1" or "0.3"
|
||||
|
||||
@@ -54,12 +68,12 @@ typedef int8_t IDM_T; // smallest int which size does NOT matter
|
||||
#define ARG_COMPATIBILITY "compatibility"
|
||||
extern int32_t my_compatibility;
|
||||
|
||||
#define MIN_PETTINESS 0
|
||||
#define MAX_PETTINESS 1
|
||||
#define DEF_PETTINESS 0
|
||||
#define ARG_PETTINESS "pettiness"
|
||||
#define MIN_CONFORMANCE_TOLERANCE 0
|
||||
#define MAX_CONFORMANCE_TOLERANCE 1
|
||||
#define DEF_CONFORMANCE_TOLERANCE 0
|
||||
#define ARG_CONFORMANCE_TOLERANCE "conformanceTolerance"
|
||||
|
||||
extern int32_t my_pettiness;
|
||||
extern int32_t my_conformance_tolerance;
|
||||
extern uint32_t my_runtimeKey;
|
||||
|
||||
#define MAX_HOSTNAME_LEN 32
|
||||
@@ -86,17 +100,8 @@ extern uint32_t rev_u32;
|
||||
#define IPX_STR_LEN INET6_ADDRSTRLEN
|
||||
#define IPX_PREFIX_STR_LEN (INET6_ADDRSTRLEN + 4)
|
||||
|
||||
typedef uint16_t DEVADV_SQN_T;
|
||||
#define DEVADV_SQN_DISABLED 0 // dev-adv are not provided by this node!
|
||||
#define DEVADV_SQN_DAD_RANGE 256
|
||||
#define DEVADV_SQN_MAX ((DEVADV_SQN_T)-1)
|
||||
|
||||
typedef uint8_t DEVADV_IDX_T;
|
||||
//#define DEVADV_IDX_BIT_SIZE (8*sizeof(DEVADV_IDX_T))
|
||||
#define DEVADV_IDX_INVALID 0
|
||||
#define DEVADV_IDX_ALL 0
|
||||
#define DEVADV_IDX_MIN 1
|
||||
#define DEVADV_IDX_MAX ((DEVADV_IDX_T)-1)
|
||||
typedef struct in6_addr LOCAL_IP_T;
|
||||
|
||||
typedef uint32_t IP4_T;
|
||||
|
||||
@@ -110,11 +115,6 @@ struct net_key {
|
||||
IPX_T ip; //address
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dev_ip_key {
|
||||
IPX_T ip; // copy of dev->if_llocal_addr->ip_addr
|
||||
DEVADV_IDX_T idx;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
typedef union {
|
||||
uint8_t u8[GEN_ADDR_LEN];
|
||||
@@ -153,35 +153,19 @@ extern const struct net_key ZERO_NET6_KEY;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define ARG_HOSTNAME "hostname"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define MY_DESC_CAPABILITIES_CV16 0x0200 //capability flag for compatibility with CV16 txInterval field
|
||||
#define MY_DESC_CAPABILITIES (MY_DESC_CAPABILITIES_CV16 | 0)
|
||||
extern uint16_t my_desc_capabilities;
|
||||
|
||||
#define MIN_TX_INTERVAL 35
|
||||
#define MAX_TX_INTERVAL 10000 // < U16_MAX due to metricalgo->ogm_interval field
|
||||
#define DEF_TX_INTERVAL 500
|
||||
#define ARG_TX_INTERVAL "txInterval"
|
||||
extern int32_t my_tx_interval;
|
||||
|
||||
#define DEF_TX_DELAY ((2*my_tx_interval) + rand_num(my_tx_interval))
|
||||
|
||||
#define ARG_OGM_INTERVAL "ogmInterval"
|
||||
#define DEF_OGM_INTERVAL 5000
|
||||
#define MIN_OGM_INTERVAL 200
|
||||
#define MAX_OGM_INTERVAL 60000 // 60000 = 1 minutes
|
||||
extern int32_t my_ogm_interval;
|
||||
|
||||
|
||||
|
||||
#define DEF_DAD_TO 20000//(MAX_OGM_INTERVAL + MAX_TX_INTERVAL)
|
||||
#define MIN_DAD_TO 100
|
||||
#define MAX_DAD_TO 360000000
|
||||
@@ -206,6 +190,9 @@ typedef uint16_t SQN_T;
|
||||
#define SQN_MAX ((SQN_T)-1)
|
||||
#define MAX_SQN_RANGE 8192 // the maxumim of all .._SQN_RANGE ranges, should never be more than SQN_MAX/4
|
||||
|
||||
typedef uint32_t PKT_SQN_T;
|
||||
#define PKT_SQN_MAX ((PKT_SQN_T)-1)
|
||||
|
||||
|
||||
// OGMs:
|
||||
typedef uint16_t OGM_SQN_T;
|
||||
@@ -217,37 +204,23 @@ typedef uint16_t OGM_SQN_T;
|
||||
#define OGM_IIDOFFST_MASK ((1<<OGM_IIDOFFST_BIT_SIZE)-1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// aggregations of OGMs:
|
||||
typedef uint8_t AGGREG_SQN_T;
|
||||
#define AGGREG_SQN_BIT_SIZE (8)
|
||||
typedef uint16_t AGGREG_SQN_T;
|
||||
#define AGGREG_SQN_BIT_SIZE (16)
|
||||
#define AGGREG_SQN_MASK ((1<<AGGREG_SQN_BIT_SIZE)-1)
|
||||
#define AGGREG_SQN_MAX AGGREG_SQN_MASK
|
||||
|
||||
#define AGGREG_SQN_CACHE_RANGE 64
|
||||
#define AGGREG_SQN_CACHE_WARN (AGGREG_SQN_CACHE_RANGE/2)
|
||||
#define AGGREG_ARRAY_BYTE_SIZE (AGGREG_SQN_CACHE_RANGE/8)
|
||||
|
||||
typedef uint8_t OGM_DEST_T;
|
||||
#define OGM_DEST_BIT_SIZE (8)
|
||||
#define OGM_DEST_MASK ((1<<OGM_DEST_BIT_SIZE)-1)
|
||||
#define OGM_DEST_MAX OGM_DEST_MASK
|
||||
|
||||
#define OGM_DEST_ARRAY_BIT_SIZE (1<<OGM_DEST_BIT_SIZE)
|
||||
|
||||
#define LOCALS_MAX (1<<OGM_DEST_BIT_SIZE) // because each local needs a bit to be indicated in the ogm.dest_field
|
||||
#define AGGREG_SQN_CACHE_MASK 0xFF
|
||||
#define AGGREG_SQN_CACHE_RANGE (AGGREG_SQN_CACHE_MASK+1) //32
|
||||
|
||||
|
||||
typedef uint32_t PKT_SQN_T;
|
||||
#define PKT_SQN_MAX ((PKT_SQN_T)-1)
|
||||
|
||||
|
||||
typedef uint16_t LINKADV_SQN_T;
|
||||
#define LINKADV_SQN_DAD_RANGE 256
|
||||
#define LINKADV_SQN_MAX ((LINKADV_SQN_T)-1)
|
||||
typedef uint16_t INT_NEIGH_ID_T;
|
||||
#define INT_NEIGH_ID_BIT_SIZE (12)
|
||||
|
||||
#define LOCALS_MAX (1<<INT_NEIGH_ID_BIT_SIZE) // because each local needs a bit to be indicated in the ogm.dest_field
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -272,15 +245,15 @@ typedef uint16_t HELLO_SQN_T;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef uint32_t BURST_SQN_T;
|
||||
|
||||
|
||||
// descriptions
|
||||
typedef uint32_t DESC_SQN_T;
|
||||
#define DESC_SQN_SAVE_INTERVAL 100
|
||||
#define DESC_SQN_REBOOT_ADDS 10
|
||||
|
||||
|
||||
#define ARG_DSQN_PATH "descSqnPath"
|
||||
#define DEF_DSQN_PATH "/etc/bmx6/descSqn"
|
||||
|
||||
|
||||
|
||||
@@ -299,8 +272,7 @@ typedef uint32_t DESC_SQN_T;
|
||||
|
||||
|
||||
|
||||
#define MAX_UDPD_SIZE 1400
|
||||
|
||||
#define MAX_UDPD_SIZE (1280 /*min IPv6 MTU*/ - sizeof(struct ip6_hdr) - sizeof(struct udphdr))
|
||||
|
||||
|
||||
|
||||
@@ -337,11 +309,10 @@ typedef uint32_t DESC_SQN_T;
|
||||
#define ARG_SHOW "show"
|
||||
#define ARG_ORIGINATORS "originators"
|
||||
#define ARG_STATUS "status"
|
||||
#define ARG_LINKS "links"
|
||||
#define ARG_CREDITS "credits"
|
||||
#define ARG_DESCREFS "references"
|
||||
|
||||
|
||||
|
||||
#define MAX_DBG_STR_SIZE 1500
|
||||
#define MAX_DBG_STR_SIZE 2000
|
||||
#define OUT_SEQNO_OFFSET 1
|
||||
|
||||
enum NoYes {
|
||||
@@ -375,6 +346,9 @@ enum ADGSN {
|
||||
#define XMAX( a, b ) ( (a>b) ? (a) : (b) )
|
||||
#define XMIN( a, b ) ( (a<b) ? (a) : (b) )
|
||||
|
||||
#define XOR2( a, b ) ( (a) ? (a) : (b) )
|
||||
#define XOR3( a, b, c ) ( (a) ? (a) : ( (b) ? (b) : (c) ) )
|
||||
#define XOR4( a, b, c, d ) ( (a) ? (a) : ( (b) ? (b) : ( (c) ? (c) : (d) ) ) )
|
||||
|
||||
#define U64_MAX ((uint64_t)(-1))
|
||||
#define U32_MAX ((uint32_t)(-1))
|
||||
@@ -525,12 +499,12 @@ extern struct avl_tree status_tree;
|
||||
|
||||
int16_t field_format_get_items(const struct field_format *format);
|
||||
|
||||
int64_t field_get_value(const struct field_format *format, uint16_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
|
||||
int64_t field_get_value(const struct field_format *format, uint32_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
|
||||
|
||||
char *field_dbg_value(const struct field_format *format, uint16_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
|
||||
char *field_dbg_value(const struct field_format *format, uint32_t min_msg_size, uint8_t *data, uint32_t pos_bit, uint32_t bits);
|
||||
|
||||
uint32_t fields_dbg_lines(struct ctrl_node *cn, uint16_t relevance, uint16_t data_size, uint8_t *data,
|
||||
uint16_t min_msg_size, const struct field_format *format);
|
||||
uint32_t fields_dbg_lines(struct ctrl_node *cn, uint16_t relevance, uint32_t data_size, uint8_t *data,
|
||||
uint32_t min_msg_size, const struct field_format *format);
|
||||
|
||||
|
||||
uint32_t field_iterate(struct field_iterator *it);
|
||||
@@ -564,6 +538,7 @@ enum {
|
||||
|
||||
|
||||
#define goto_error( where, what ) do { goto_error_code=what; goto where; }while(0)
|
||||
#define goto_error_return( where, what, ret ) do { goto_error_code=what; goto_error_ret=ret; goto where; }while(0)
|
||||
|
||||
#ifdef NO_ASSERTIONS
|
||||
#define paranoia( ... )
|
||||
@@ -578,7 +553,7 @@ enum {
|
||||
/*
|
||||
* ASSERTION / PARANOIA ERROR CODES:
|
||||
* Negative numbers are used as SIGSEV error codes !
|
||||
* Currently used numbers are: -500000 -500001 ... -502230
|
||||
* Currently used numbers are: -500000 -500001 ... -502500
|
||||
*/
|
||||
|
||||
//#define paranoia( code , problem ) do { if ( (problem) ) { cleanup_all( code ); } }while(0)
|
||||
@@ -605,6 +580,11 @@ enum {
|
||||
#define EXITERROR( code , condition )
|
||||
#endif
|
||||
|
||||
#define TEST_FUNCTION(X) ( ((void(*)(void*))&(X)) != NULL )
|
||||
#define TEST_VALUE(X) (((uint32_t)X) != 1234543210)
|
||||
#define TEST_STRUCT(X) (sizeof(X) > 0)
|
||||
#define TEST_VARIABLE(X) ((void*)&X != NULL )
|
||||
|
||||
#endif//NO_ASSERTIONS
|
||||
|
||||
|
||||
@@ -627,22 +607,10 @@ enum {
|
||||
|
||||
#define FUNCTION_CALL_BUFFER_SIZE 64
|
||||
|
||||
//extern char* function_call_buffer_name_array[FUNCTION_CALL_BUFFER_SIZE];
|
||||
//extern TIME_T function_call_buffer_time_array[FUNCTION_CALL_BUFFER_SIZE];
|
||||
//extern uint8_t function_call_buffer_pos;
|
||||
|
||||
void trace_function_call(const char *);
|
||||
|
||||
#define TRACE_FUNCTION_CALL trace_function_call ( __FUNCTION__ )
|
||||
|
||||
extern uint32_t test_magic_number;
|
||||
|
||||
//#define TEST_FUNCTION(X) ( ((void(*)(void*))&trace_function_call) != ((void(*)(void*))&(X)) )
|
||||
#define TEST_FUNCTION(X) ( ((void(*)(void*))&(X)) != NULL )
|
||||
#define TEST_VALUE(X) (((uint32_t)X) != test_magic_number)
|
||||
#define TEST_STRUCT(X) (sizeof(X) > 0)
|
||||
#define TEST_VARIABLE(X) ((void*)&X != NULL )
|
||||
|
||||
#else
|
||||
|
||||
#define TRACE_FUNCTION_CALL
|
||||
@@ -656,7 +624,7 @@ void cleanup_all( int32_t status );
|
||||
|
||||
char *get_human_uptime( uint32_t reference );
|
||||
|
||||
DESC_SQN_T getDescriptionSqn( char* newPath, uint8_t ass );
|
||||
DESC_SQN_T newDescriptionSqn( char* newPath, uint8_t ass );
|
||||
|
||||
|
||||
/***********************************************************
|
||||
@@ -668,5 +636,4 @@ DESC_SQN_T getDescriptionSqn( char* newPath, uint8_t ass );
|
||||
IDM_T validate_param(int32_t probe, int32_t min, int32_t max, char *name);
|
||||
|
||||
int32_t opt_status(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
int32_t opt_update_description(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
int32_t opt_purge_originators(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
int32_t opt_flush_all(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
|
127
content.h
Normal file
127
content.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO: set REQ_TO to 1 (in a non-packet-loss testenvironment this may be set to 1000 for testing)
|
||||
#define DEF_TX_CONTENT_REQ_TO ((DEF_TX_MIN_INTERVAL*3)/2)
|
||||
#define DEF_TX_CONTENT_ADV_TO 200
|
||||
|
||||
#define MAX_DESC_TYPE_CONTENT_OCCURANCE 10
|
||||
#define ARG_CONTENTS "contents"
|
||||
|
||||
#define DEF_UNSOLICITED_CONTENT_ADVS 1
|
||||
#define MIN_UNSOLICITED_CONTENT_ADVS 0
|
||||
#define MAX_UNSOLICITED_CONTENT_ADVS 1
|
||||
#define ARG_UNSOLICITED_CONTENT_ADVS "unsolicitedContentAdvs"
|
||||
|
||||
extern struct avl_tree content_tree;
|
||||
|
||||
|
||||
|
||||
#define DSC_MSG_CHASH_FORMAT { \
|
||||
{FIELD_TYPE_STRING_BINARY, -1, 160, 1, FIELD_RELEVANCE_LOW, "chash"}, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct dsc_msg_chash {
|
||||
SHA1_T chash; // hash over frame data (without frame-header, but including hdr_content_adv and all body data) as transmitted via content_adv
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dsc_hdr_chash {
|
||||
SHA1_T expanded_chash; // hash over zero-frame_hdr_content_adv and frame body data with all resolved, re-assembled, uncompressed.
|
||||
// So for a dsc_hdr/msg_chash frame with a single uncompressed and non-nested chash this would equal the chash of dsc_msg_chash which MUST be omitted.
|
||||
// Otherwise it provides a checksum over the final data.
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int gzip : 1; // only contents are compressed, all resolved and re-assembled contents are compressed (NOT the hashes)
|
||||
unsigned int maxNesting : 2;
|
||||
unsigned int expanded_type : 5;
|
||||
unsigned int expanded_length : 24;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int expanded_length : 24;
|
||||
unsigned int expanded_type : 5;
|
||||
unsigned int maxNesting : 2;
|
||||
unsigned int gzip : 1;
|
||||
#else
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
} __attribute((packed)) i;
|
||||
uint32_t u32;
|
||||
} u;
|
||||
|
||||
struct dsc_msg_chash msg[];
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
struct frame_msg_content_adv {
|
||||
SHA1_T chash; // hash over frame data (without frame-header, but including hdr_content_adv and all body data) as transmitted via content_adv
|
||||
} __attribute__((packed));
|
||||
|
||||
struct frame_hdr_content_adv {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int gzip : 1; // only contents are compressed, all resolved and re-assembled contents are compressed (NOT the hashes)
|
||||
unsigned int maxNesting : 2;
|
||||
unsigned int reserved : 5;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int reserved : 5;
|
||||
unsigned int maxNesting : 2;
|
||||
unsigned int gzip : 1;
|
||||
#else
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
uint8_t content[]; //hashes if nested, otherwise raw content data
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
// for FRAME_TYPE_REF_REQ:
|
||||
|
||||
struct msg_content_req {
|
||||
SHA1_T chash;
|
||||
} __attribute__((packed));
|
||||
|
||||
//TODO: Use this destination header!!!
|
||||
|
||||
struct hdr_content_req { // 20 bytes
|
||||
GLOBAL_ID_T dest_kHash;
|
||||
struct msg_content_req msg[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
void descContent_destroy(struct desc_content *dc);
|
||||
struct desc_content* descContent_create(uint8_t *dsc, uint32_t dlen, struct key_node *key);
|
||||
|
||||
|
||||
struct content_node * content_get(SHA1_T *chash);
|
||||
void *contents_data(struct desc_content *contents, uint8_t type);
|
||||
uint32_t contents_dlen(struct desc_content *contents, uint8_t type);
|
||||
struct content_node * content_add_hash(SHA1_T *chash);
|
||||
struct content_node * content_add_body(uint8_t *body, uint32_t body_len, uint8_t compressed, uint8_t nested, uint8_t force);
|
||||
int32_t create_chash_tlv(struct tlv_hdr *tlv, uint8_t *f_data, uint32_t f_len, uint8_t f_type, uint8_t fzip, uint8_t level);
|
||||
void content_purge_unused(struct content_node *onlyCn);
|
||||
|
||||
|
||||
void init_content(void);
|
20
control.c
20
control.c
@@ -37,11 +37,13 @@
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "link.h"
|
||||
#include "ip.h"
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
#include "allocate.h"
|
||||
#include "hna.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "control"
|
||||
|
||||
@@ -2630,6 +2632,8 @@ int32_t opt_show_parameter(uint8_t cmd, uint8_t _save, struct opt_type *opt, str
|
||||
|
||||
struct opt_type *opt = NULL;
|
||||
|
||||
dbg_printf(cn, "PARAMETERS:\n");
|
||||
|
||||
while ((opt = list_iterate(&opt_list, opt))) {
|
||||
struct opt_parent *p = NULL;
|
||||
|
||||
@@ -2638,13 +2642,18 @@ int32_t opt_show_parameter(uint8_t cmd, uint8_t _save, struct opt_type *opt, str
|
||||
struct opt_child *c = NULL;
|
||||
|
||||
assertion(-501231, (opt->name && opt->cfg_t != A_ARG));
|
||||
|
||||
dbg_printf(cn, " %-22s %-20s %s%s\n", opt->name, p->val,
|
||||
|
||||
char pdef[14];
|
||||
sprintf(pdef, "%d", opt->idef);
|
||||
|
||||
dbg_printf(cn, " %-22s %-20s (%s) %s%s\n", opt->name, p->val, (opt->sdef ? opt->sdef : pdef),
|
||||
(p->ref ? "resolved from " : ""), (p->ref ? p->ref : ""));
|
||||
|
||||
while ((c = list_iterate(&p->childs_instance_list, c))) {
|
||||
dbg_printf(cn, " %s%-18s %-20s %s%s\n",
|
||||
LONG_OPT_ARG_DELIMITER_STR, c->opt->name, c->val,
|
||||
char cdef[14];
|
||||
sprintf(cdef, "%d", c->opt->idef);
|
||||
dbg_printf(cn, " %s%-18s %-20s (%s) %s%s\n",
|
||||
LONG_OPT_ARG_DELIMITER_STR, c->opt->name, c->val, (c->opt->sdef ? c->opt->sdef : cdef),
|
||||
(c->ref ? "resolved from " : ""), (c->ref ? c->ref : ""));
|
||||
}
|
||||
}
|
||||
@@ -2694,6 +2703,7 @@ int32_t opt_debug(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_p
|
||||
check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_SHOW), ARG_STATUS, cn);
|
||||
check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_SHOW), ARG_INTERFACES, cn);
|
||||
check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_SHOW), ARG_LINKS, cn);
|
||||
check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_SHOW), ARG_CREDITS, cn);
|
||||
check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_SHOW), ARG_ORIGINATORS, cn);
|
||||
|
||||
} else if ( ival == DBGL_PROFILE ) {
|
||||
@@ -2739,7 +2749,7 @@ int32_t opt_help(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_pa
|
||||
prog_name, ARG_RESET_CHAR , ARG_RESET_CHAR);
|
||||
dbg_printf(cn, " e.g. %s %s=eth1 %s=wlan0 d=3\n", prog_name, ARG_DEV, ARG_DEV);
|
||||
dbg_printf(cn, " e.g. %s -c %s=%s %s=%s %s=%s %s=%s\n",
|
||||
prog_name, ARG_SHOW, ARG_STATUS, ARG_SHOW, ARG_INTERFACES, ARG_SHOW, ARG_LINKS, ARG_SHOW, ARG_ORIGINATORS);
|
||||
prog_name, ARG_SHOW, ARG_STATUS, ARG_SHOW, ARG_INTERFACES, ARG_SHOW, ARG_LINKS, ARG_SHOW, ARG_ORIGINATORS, ARG_CREDITS);
|
||||
dbg_printf(cn, " e.g. %s -c %s=%cwlan0 %s=%s \n", prog_name, ARG_DEV, ARG_RESET_CHAR, ARG_SHOW, ARG_INTERFACES );
|
||||
dbg_printf(cn, "\n");
|
||||
|
||||
|
6
crypt.c
6
crypt.c
@@ -647,7 +647,7 @@ CRYPTKEY_T *cryptKeyFromDer( char *keyPath ) {
|
||||
(rsa_copy(rsa, pk_rsa(pk))) ||
|
||||
(rsa_check_privkey(rsa))
|
||||
) {
|
||||
dbgf_sys(DBGT_ERR, "failed opening private key=%s err=%d", keyPath, ret);
|
||||
dbgf_sys(DBGT_ERR, "failed opening private key=%s err=-%X", keyPath, -ret);
|
||||
pk_free(&pk);
|
||||
cryptKeyFree(&ckey);
|
||||
return NULL;
|
||||
@@ -708,13 +708,13 @@ int cryptKeyMakeDer( int32_t keyBitSize, char *path ) {
|
||||
(ret = rsa_check_privkey(pk_rsa(pk))))
|
||||
goto_error(finish, "Failed making rsa key! ret=%d");
|
||||
|
||||
if ((derSz = pk_write_key_der(&pk, derBuf, sizeof(derBuf))) < 0)
|
||||
if ((derSz = pk_write_key_der(&pk, derBuf, sizeof(derBuf))) <= 0)
|
||||
goto_error(finish, "Failed translating rsa key to der! derSz=%d");
|
||||
#else
|
||||
# error "Please fix CRYPTLIB"
|
||||
#endif
|
||||
|
||||
unsigned char *derStart = derBuf + sizeof(derBuf) - derSz - 1;
|
||||
unsigned char *derStart = derBuf + sizeof(derBuf) - derSz;
|
||||
|
||||
|
||||
if (!(keyFile = fopen(path, "wb")) || ((int)fwrite(derStart, 1, derSz, keyFile)) != derSz )
|
||||
|
3
crypt.h
3
crypt.h
@@ -28,13 +28,14 @@
|
||||
#define POLARSSL_1_2_5 1125
|
||||
#define POLARSSL_1_2_9 1129
|
||||
#define POLARSSL_1_3_3 1133
|
||||
#define POLARSSL_1_3_4 1134
|
||||
#define POLARSSL_MAX 1999
|
||||
#define CYASSL_MIN 2000
|
||||
#define CYASSL_2_8_0 2280
|
||||
#define CYASSL_MAX 2999
|
||||
|
||||
#ifndef CRYPTLIB
|
||||
#define CRYPTLIB POLARSSL_1_2_5
|
||||
#define CRYPTLIB POLARSSL_1_3_4
|
||||
#endif
|
||||
|
||||
#define CRYPT_DER_BUF_SZ 16000
|
||||
|
961
desc.c
Normal file
961
desc.c
Normal file
@@ -0,0 +1,961 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "control.h"
|
||||
#include "bmx.h"
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "key.h"
|
||||
#include "sec.h"
|
||||
#include "metrics.h"
|
||||
#include "ogm.h"
|
||||
#include "msg.h"
|
||||
#include "desc.h"
|
||||
#include "content.h"
|
||||
#include "z.h"
|
||||
#include "ip.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
#include "iptools.h"
|
||||
#include "plugin.h"
|
||||
#include "allocate.h"
|
||||
#include "prof.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "desc"
|
||||
|
||||
int32_t desc_root_size_out = DEF_DESC_ROOT_SIZE;
|
||||
int32_t vrt_frame_data_size_out = DEF_VRT_FRAME_DATA_SIZE;
|
||||
int32_t vrt_frame_data_size_in = DEF_VRT_FRAME_DATA_SIZE;
|
||||
int32_t desc_vbodies_size_out = DEF_DESC_VBODIES_SIZE;
|
||||
int32_t desc_vbodies_size_in = DEF_DESC_VBODIES_SIZE;
|
||||
|
||||
int32_t vrt_frame_max_nesting = 2;
|
||||
|
||||
int32_t unsolicitedDescAdvs = DEF_UNSOLICITED_DESC_ADVS;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IDM_T process_description_tlvs(struct packet_buff *pb, struct orig_node *on, struct desc_content *dcOld, struct desc_content *dcNew, uint8_t op, uint8_t filter)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-500370, (op == TLV_OP_DEL || op == TLV_OP_TEST || op == TLV_OP_NEW || op == TLV_OP_DEBUG ||
|
||||
(op >= TLV_OP_CUSTOM_MIN && op <= TLV_OP_CUSTOM_MAX) || (op >= TLV_OP_PLUGIN_MIN && op <= TLV_OP_PLUGIN_MAX)));
|
||||
|
||||
|
||||
int32_t result;
|
||||
int8_t blocked = NO;
|
||||
|
||||
assertion(-500807, (dcNew && dcNew->desc_frame && dcNew->dhn));
|
||||
assertion(-502047, IMPLIES(op == TLV_OP_DEL || op == TLV_OP_NEW, on && dcNew));
|
||||
|
||||
if (filter <= description_tlv_db->handl_max && !contents_data(dcNew, filter))
|
||||
return TLV_RX_DATA_DONE;
|
||||
|
||||
struct rx_frame_iterator it = {
|
||||
.caller = __FUNCTION__, .op = op, .pb = pb, .db = description_tlv_db, .process_filter = filter,
|
||||
.on = on, .dcOld = dcOld, .dcNew = dcNew,
|
||||
.f_type = -1, .frames_length = 0, .frames_in = NULL
|
||||
};
|
||||
|
||||
|
||||
dbgf_track(DBGT_INFO, "op=%s nodeId=%s filter=%d",
|
||||
tlv_op_str(op), nodeIdAsStringFromDescAdv(dcNew->desc_frame), filter);
|
||||
|
||||
|
||||
while ((result = rx_frame_iterate(&it)) > TLV_RX_DATA_DONE) {
|
||||
|
||||
if (result == TLV_RX_DATA_BLOCKED)
|
||||
blocked = YES;
|
||||
}
|
||||
|
||||
assertion( -502048, (result==TLV_RX_DATA_DONE || result==TLV_RX_DATA_REBOOTED || result==TLV_RX_DATA_REJECTED || result==TLV_RX_DATA_FAILURE));
|
||||
|
||||
if ((op >= TLV_OP_CUSTOM_MIN && op <= TLV_OP_CUSTOM_MAX) || (op >= TLV_OP_PLUGIN_MIN && op <= TLV_OP_PLUGIN_MAX))
|
||||
return result;
|
||||
|
||||
if (result==TLV_RX_DATA_REBOOTED || result==TLV_RX_DATA_REJECTED || result == TLV_RX_DATA_FAILURE || blocked) {
|
||||
|
||||
assertion(-501355, (op == TLV_OP_TEST));
|
||||
|
||||
dbgf_sys(DBGT_WARN, "problematic description_ltv from %s, near type=%d=%s frame_data_length=%d pos=%d %s %s",
|
||||
pb ? pb->i.llip_str : DBG_NIL,
|
||||
it.f_type, (((uint8_t)it.f_type) <= description_tlv_db->handl_max) ? description_tlv_db->handls[it.f_type].name : "",
|
||||
it.f_dlen, it._f_pos_next, blocked ? "BLOCKED" : "", tlv_rx_result_str(result));
|
||||
|
||||
return (result == TLV_RX_DATA_DONE ? TLV_RX_DATA_BLOCKED : result);
|
||||
}
|
||||
|
||||
return TLV_RX_DATA_DONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IDM_T desc_frame_changed( struct rx_frame_iterator *it, uint8_t type )
|
||||
{
|
||||
struct desc_content *rOld = it->dcOld;
|
||||
struct desc_content *rNew = it->dcNew;
|
||||
struct key_node *kn = (rOld ? rOld->key : (rNew ? rNew->key : NULL));
|
||||
|
||||
assertion(-502274, (kn));
|
||||
|
||||
IDM_T changed = (contents_dlen(rOld, type) != contents_dlen(rNew, type) ||
|
||||
(contents_dlen(rOld, type) && memcmp(contents_data(rOld, type), contents_data(rNew, type), contents_dlen(rNew, type))));
|
||||
|
||||
dbgf_track(DBGT_INFO, "orig=%s %s type=%d (%s) old_len=%d new_len=%d",
|
||||
cryptShaAsString(&kn->kHash), changed ? " CHANGED" : "UNCHANGED",
|
||||
type, it->db->handls[type].name, contents_dlen(rOld, type), contents_dlen(rNew, type));
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SHA1_T *nodeIdFromDescAdv(uint8_t *desc_adv)
|
||||
{
|
||||
return &(((struct dsc_hdr_chash*) (desc_adv + sizeof(struct tlv_hdr)))->expanded_chash);
|
||||
}
|
||||
|
||||
char *nodeIdAsStringFromDescAdv(uint8_t *desc_adv)
|
||||
{
|
||||
return cryptShaAsString(nodeIdFromDescAdv(desc_adv));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void update_orig_dhash(struct desc_content *dcNew)
|
||||
{
|
||||
assertion(-502469, (dcNew->key));
|
||||
|
||||
struct key_node *kn = dcNew->key;
|
||||
struct orig_node *on = kn->currOrig;
|
||||
struct desc_content *dcOld = on ? on->descContent : NULL;
|
||||
|
||||
assertion(-502470, (dcNew && dcNew->key && !dcNew->orig));
|
||||
assertion(-502471, (dcNew && dcNew->unresolvedContentCounter == 0 && dcNew->contentRefs_tree.items));
|
||||
assertion(-502225, IMPLIES(on, on->descContent != dcNew));
|
||||
assertion(-502225, IMPLIES(on, on->descContent->orig == on));
|
||||
assertion(-502472, IMPLIES(on, on->descContent->descSqn < dcNew->descSqn));
|
||||
ASSERTION(-502473, (process_description_tlvs(NULL, on, dcOld, dcNew, TLV_OP_TEST, FRAME_TYPE_PROCESS_ALL) == TLV_RX_DATA_DONE));
|
||||
|
||||
if (on) {
|
||||
cb_plugin_hooks(PLUGIN_CB_DESCRIPTION_DESTROY, on);
|
||||
on->descContent = dcNew;
|
||||
dcNew->orig = on;
|
||||
dcOld->orig = NULL;
|
||||
} else {
|
||||
on = debugMallocReset(sizeof( struct orig_node) + (sizeof(void*) * plugin_data_registries[PLUGIN_DATA_ORIG]), -300128);
|
||||
on->k.nodeId = dcNew->key->kHash;
|
||||
on->key = dcNew->key;
|
||||
|
||||
on->descContent = dcNew;
|
||||
dcNew->orig = on;
|
||||
dcNew->key->currOrig = on;
|
||||
|
||||
init_neighTrust(on);
|
||||
|
||||
avl_insert(&orig_tree, on, -300148);
|
||||
|
||||
cb_plugin_hooks(PLUGIN_CB_STATUS, NULL);
|
||||
}
|
||||
|
||||
kn->nextDesc = NULL;
|
||||
|
||||
process_description_tlvs(NULL, on, dcOld, dcNew, TLV_OP_NEW, FRAME_TYPE_PROCESS_ALL);
|
||||
|
||||
if (dcOld)
|
||||
dhash_node_reject(dcOld->dhn);
|
||||
|
||||
on->updated_timestamp = bmx_time;
|
||||
|
||||
cb_plugin_hooks(PLUGIN_CB_DESCRIPTION_CREATED, on);
|
||||
|
||||
if (unsolicitedDescAdvs) {
|
||||
schedule_tx_task(FRAME_TYPE_DESC_ADVS, NULL, NULL, NULL, dcNew->desc_frame_len, &dcNew->dhn->dhash, sizeof(DHASH_T));
|
||||
schedule_tx_task(FRAME_TYPE_DHASH_ADV, NULL, NULL, NULL, SCHEDULE_MIN_MSG_SIZE, &dcNew->dhn->dhash, sizeof(DHASH_T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void process_description_tlvs_del( struct orig_node *on, struct desc_content *dcOld, uint8_t ft_start, uint8_t ft_end ) {
|
||||
|
||||
int8_t t;
|
||||
|
||||
assertion(-502068, (on && dcOld && dcOld->dhn && dcOld->key));
|
||||
|
||||
for (t = ft_start; t <= ft_end; t++) {
|
||||
|
||||
if ( t== BMX_DSC_TLV_CONTENT_HASH )
|
||||
continue;
|
||||
|
||||
if (contents_data(dcOld, t)) {
|
||||
int tlv_result = process_description_tlvs(NULL, on, NULL, dcOld, TLV_OP_DEL, t);
|
||||
assertion(-501360, (tlv_result == TLV_RX_DATA_DONE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void update_my_description(void)
|
||||
{
|
||||
// MUST be checked here because:
|
||||
// description may have changed (relevantly for ogm_aggregation)
|
||||
// during current call of task_next() in bmx() main loop
|
||||
if (!my_description_changed)
|
||||
return;
|
||||
|
||||
TRACE_FUNCTION_CALL;
|
||||
prof_start(update_my_description, main);
|
||||
|
||||
assertion(-502082, (!terminating));
|
||||
assertion(-502275, (myKey));
|
||||
|
||||
dbgf_track(DBGT_INFO, DBG_NIL);
|
||||
|
||||
// add all tlv options:
|
||||
struct tx_frame_iterator tx = {
|
||||
.caller = __FUNCTION__, .db = description_tlv_db, .prev_out_type = -1,
|
||||
.frames_out_ptr = debugMallocReset(desc_root_size_out, -300627),
|
||||
.frames_out_max = desc_root_size_out,
|
||||
.frames_out_pref = desc_root_size_out,
|
||||
.frame_cache_array = debugMallocReset(vrt_frame_data_size_out, -300586),
|
||||
.frame_cache_size = vrt_frame_data_size_out,
|
||||
};
|
||||
|
||||
for (; tx.frame_type <= tx.db->handl_max; tx.frame_type++) {
|
||||
|
||||
int32_t result;
|
||||
assertion(-502083, IMPLIES((tx.db->handls[tx.frame_type]).name, (tx.db->handls[tx.frame_type]).tx_frame_handler));
|
||||
result = tx_frame_iterate(NO/*iterate_msg*/, &tx);
|
||||
assertion_dbg(-500798, result>=TLV_TX_DATA_DONE, "frame_type=%d result=%s", tx.frame_type, tlv_tx_result_str(result));
|
||||
}
|
||||
|
||||
ASSERTION(-502315, (test_description_signature(tx.frames_out_ptr, tx.frames_out_pos)));
|
||||
|
||||
struct desc_content *dcNew = descContent_create(tx.frames_out_ptr, tx.frames_out_pos, myKey);
|
||||
|
||||
assertion(-502316, (dcNew && dcNew->dhn));
|
||||
assertion(-502317, (dcNew->key == myKey && myKey->nextDesc == dcNew));
|
||||
assertion(-502318, (dcNew->contentRefs_tree.items && !dcNew->unresolvedContentCounter));
|
||||
assertion(-502319, IMPLIES(myKey->currOrig, myKey->currOrig->descContent->dhn));
|
||||
|
||||
dbgf_sys(DBGT_INFO, "nodeId=%s dhashOld=%s dhashNew=%s",
|
||||
cryptShaAsString(&myKey->kHash),
|
||||
cryptShaAsString(myKey->currOrig ? &myKey->currOrig->descContent->dhn->dhash : NULL),
|
||||
cryptShaAsString(&dcNew->dhn->dhash));
|
||||
|
||||
keyNode_updCredits(NULL, myKey, NULL);
|
||||
|
||||
|
||||
assertion(-502320, (myKey->currOrig->descContent == dcNew));
|
||||
|
||||
my_description_changed = NO;
|
||||
|
||||
if (myBurstSqn > ((BURST_SQN_T)(-1000)))
|
||||
myBurstSqn = 0;
|
||||
|
||||
debugFree(tx.frames_out_ptr, -300585);
|
||||
debugFree(tx.frame_cache_array, -300585);
|
||||
prof_stop();
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t opt_show_descriptions(uint8_t cmd, uint8_t _save, struct opt_type *opt,
|
||||
struct opt_parent *patch, struct ctrl_node *cn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
if ( cmd == OPT_APPLY ) {
|
||||
|
||||
struct avl_node *an = NULL;
|
||||
struct dhash_node *dhn;
|
||||
char *name = NULL;
|
||||
int32_t type_filter = DEF_DESCRIPTION_TYPE;
|
||||
int32_t relevance = DEF_RELEVANCE;
|
||||
struct opt_child *c = NULL;
|
||||
|
||||
while ((c = list_iterate(&patch->childs_instance_list, c))) {
|
||||
|
||||
if (!strcmp(c->opt->name, ARG_DESCRIPTION_TYPE)) {
|
||||
type_filter = strtol(c->val, NULL, 10);
|
||||
|
||||
} else if (!strcmp(c->opt->name, ARG_RELEVANCE)) {
|
||||
relevance = strtol(c->val, NULL, 10);
|
||||
|
||||
} else if (!strcmp(c->opt->name, ARG_DESCRIPTION_NAME)) {
|
||||
name = c->val;
|
||||
}
|
||||
}
|
||||
|
||||
dbg_printf( cn, "descriptions:" );
|
||||
|
||||
while ((dhn = avl_iterate_item(&dhash_tree, &an))) {
|
||||
|
||||
struct desc_content *dc = dhn->descContent;
|
||||
if (name && (!dc->orig || strcmp(name, dc->orig->k.hostname)))
|
||||
continue;
|
||||
|
||||
dbg_printf(cn, "\ndescSha=%s nodeId=%s name=%s state=%s contents=%d/%d rejected=%d neighRefs=%d:",
|
||||
cryptShaAsString(&dhn->dhash), cryptShaAsString(dc ? &dc->key->kHash: NULL),
|
||||
dc && dc->orig ? dc->orig->k.hostname : NULL, dc ? dc->key->bookedState->secName : NULL,
|
||||
dc ? dc->contentRefs_tree.items : 0, dc ? (int)(dc->unresolvedContentCounter + dc->contentRefs_tree.items) : -1,
|
||||
dhn->rejected, dhn->neighRefs_tree.items);
|
||||
|
||||
if (!dc || !dc->contentRefs_tree.items || dc->unresolvedContentCounter)
|
||||
continue;
|
||||
|
||||
struct rx_frame_iterator it = {.caller = __FUNCTION__, .on = NULL, .dcNew = dc,
|
||||
.op = TLV_OP_PLUGIN_MIN, .db = description_tlv_db, .process_filter = type_filter, .f_type = -1,};
|
||||
|
||||
int32_t result;
|
||||
while ((result = rx_frame_iterate(&it)) > TLV_RX_DATA_DONE) {
|
||||
|
||||
dbg_printf(cn, "\n %s (%s): ", it.f_handl->name, dc->final[it.f_type].desc_tlv_body_len ? "inline" : "referenced");
|
||||
|
||||
fields_dbg_lines(cn, relevance, it.f_msgs_len, it.f_msg,
|
||||
it.f_handl->min_msg_size, it.f_handl->msg_format);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dbg_printf( cn, "\n" );
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t opt_update_dext_method(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
if ( cmd == OPT_APPLY )
|
||||
my_description_changed = YES;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t create_dsc_tlv_version(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct dsc_msg_version *dsc = (struct dsc_msg_version *)tx_iterator_cache_msg_ptr(it);
|
||||
|
||||
dsc->capabilities = htons(my_desc_capabilities);
|
||||
|
||||
uint32_t rev_u32;
|
||||
sscanf(GIT_REV, "%8X", &rev_u32);
|
||||
dsc->codeRevision = htonl(rev_u32);
|
||||
dsc->comp_version = my_compatibility;
|
||||
dsc->descSqn = newDescriptionSqn( NULL, 1);
|
||||
|
||||
return sizeof(struct dsc_msg_version);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t process_dsc_tlv_version(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-502321, IMPLIES(it->op == TLV_OP_NEW || it->op == TLV_OP_DEL, it->on));
|
||||
|
||||
if (it->op != TLV_OP_TEST && it->op != TLV_OP_NEW)
|
||||
return it->f_dlen;
|
||||
|
||||
DESC_SQN_T newSqn = ntohl(((struct dsc_msg_version*)it->f_data)->descSqn);
|
||||
|
||||
if (it->dcOld && newSqn <= it->dcOld->descSqn)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if (it->op == TLV_OP_NEW && it->on->neigh) {
|
||||
|
||||
it->on->neigh->burstSqn = 0;
|
||||
|
||||
if (it->dcOld && newSqn >= (it->dcOld->descSqn + DESC_SQN_REBOOT_ADDS))
|
||||
keyNode_schedLowerWeight(it->on->key, KCPromoted);
|
||||
}
|
||||
|
||||
return sizeof(struct dsc_msg_version);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t create_dsc_tlv_names(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
dbgf_all(DBGT_INFO, "%s", my_Hostname);
|
||||
|
||||
int32_t nameLen = strlen(my_Hostname);
|
||||
|
||||
if (nameLen<=0 || nameLen>=255 || nameLen >= MAX_HOSTNAME_LEN)
|
||||
return TLV_TX_DATA_IGNORED;
|
||||
|
||||
if (nameLen > tx_iterator_cache_data_space_pref(it, 0, 0))
|
||||
return TLV_TX_DATA_FULL;
|
||||
|
||||
struct description_msg_name *msg = (struct description_msg_name *) tx_iterator_cache_msg_ptr(it);
|
||||
|
||||
msg->type = 0;
|
||||
msg->len = nameLen;
|
||||
memcpy(msg->name, my_Hostname, nameLen);
|
||||
|
||||
return sizeof(struct description_msg_name) + nameLen;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t process_dsc_tlv_names(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
char name[MAX_HOSTNAME_LEN];
|
||||
|
||||
dbgf_all(DBGT_INFO, "op=%s", tlv_op_str(it->op) );
|
||||
|
||||
struct description_msg_name *msg = (struct description_msg_name *) it->f_msg;
|
||||
|
||||
if (msg->type != 0 || msg->len >= MAX_HOSTNAME_LEN)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
memcpy(name, msg->name, msg->len);
|
||||
name[msg->len]=0;
|
||||
|
||||
if (validate_name_string(name, msg->len+1, NULL) == FAILURE)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if (IMPLIES(!my_conformance_tolerance, it->f_dlen != (int)(sizeof(struct description_msg_name) + msg->len)))
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if ((it->op==TLV_OP_NEW || it->op == TLV_OP_DEL)) {
|
||||
memset(it->on->k.hostname, 0, sizeof(it->on->k.hostname));
|
||||
}
|
||||
|
||||
if (it->op == TLV_OP_NEW) {
|
||||
strcpy(it->on->k.hostname, name);
|
||||
}
|
||||
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_description_request(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct tx_task_node *ttn = it->ttn;
|
||||
struct hdr_description_request *hdr = ((struct hdr_description_request*) tx_iterator_cache_hdr_ptr(it));
|
||||
struct msg_description_request *msg = ((struct msg_description_request*) tx_iterator_cache_msg_ptr(it));
|
||||
DHASH_T *dhash = NULL;
|
||||
IDM_T wanted = NO;;
|
||||
|
||||
if (memcmp((((uint8_t*) ttn->key.data) + sizeof(DESC_SQN_T)), ((uint8_t *) & ZERO_CYRYPSHA1), (sizeof(CRYPTSHA1_T) - sizeof(DESC_SQN_T)))) {
|
||||
|
||||
struct dhash_node *dhn = avl_find_item(&dhash_tree, (dhash = (DHASH_T*) ttn->key.data));
|
||||
wanted = (dhn && !dhn->descContent && !dhn->rejected && dhn->neighRefs_tree.items);
|
||||
} else {
|
||||
DESC_SQN_T *descSqn = (DESC_SQN_T*) ttn->key.data;
|
||||
struct key_node *neighKn = keyNode_get(&ttn->key.f.groupId);
|
||||
assertion(-502322, IMPLIES(neighKn && neighKn->bookedState->i.c >= KCTracked, neighKn->content));
|
||||
wanted = (neighKn && neighKn->bookedState->i.c >= KCTracked && neighKn->content->f_body &&
|
||||
(neighKn->nextDesc ? neighKn->nextDesc->descSqn < *descSqn : (neighKn->currOrig ? neighKn->currOrig->descContent->descSqn < *descSqn : YES)));
|
||||
}
|
||||
|
||||
assertion(-500855, (tx_iterator_cache_data_space_pref(it, 0, 0) >= ((int) (sizeof(struct msg_description_request)))));
|
||||
|
||||
dbgf_track(DBGT_INFO, "%s dev=%s to khash=%s iterations=%d requesting dhash=%s send=%d",
|
||||
it->db->handls[ttn->key.f.type].name, ttn->key.f.p.dev->label_cfg.str, cryptShaAsString(&ttn->key.f.groupId),
|
||||
ttn->tx_iterations, cryptShaAsString(dhash), wanted);
|
||||
|
||||
if (!wanted)
|
||||
return TLV_TX_DATA_DONE;
|
||||
|
||||
msg->dhash = dhash ? *dhash : ZERO_CYRYPSHA1;
|
||||
|
||||
if (hdr->msg == msg) {
|
||||
assertion(-500854, (is_zero(hdr, sizeof(*hdr))));
|
||||
hdr->dest_kHash = ttn->key.f.groupId;
|
||||
} else {
|
||||
assertion(-500871, (cryptShasEqual(&hdr->dest_kHash, &ttn->key.f.groupId)));
|
||||
}
|
||||
|
||||
dbgf_track(DBGT_INFO, "created msg=%d", ((int) ((((char*) msg) - ((char*) hdr) - sizeof( *hdr)) / sizeof(*msg))));
|
||||
|
||||
|
||||
return sizeof(struct msg_description_request);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_msg_description_request(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct packet_buff *pb = it->pb;
|
||||
struct hdr_description_request *hdr = (struct hdr_description_request*) (it->f_data);
|
||||
struct msg_description_request *msg = (struct msg_description_request*) (it->f_msg);
|
||||
|
||||
assertion(-502171, (pb->i.iif));
|
||||
|
||||
if (cryptShasEqual(&hdr->dest_kHash, &myKey->kHash)) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "%s NB %s destination_dhash=%s requested_dhash=%s",
|
||||
it->f_handl->name, pb->i.llip_str, cryptShaAsString(&hdr->dest_kHash), cryptShaAsString(&msg->dhash));
|
||||
|
||||
struct dhash_node *dhn = cryptShasEqual(&msg->dhash, (void*) &ZERO_CYRYPSHA1) ? myKey->currOrig->descContent->dhn : avl_find_item(&dhash_tree, &msg->dhash);
|
||||
|
||||
if (dhn && dhn->descContent && dhn->descContent->orig && (((TIME_T) (bmx_time - dhn->referred_by_me_timestamp)) <= DEF_DESC0_REFERRED_TO) &&
|
||||
(pb->i.verifiedLink|| dhn == myKey->currOrig->descContent->dhn)) {
|
||||
|
||||
dhn->referred_by_me_timestamp = bmx_time;
|
||||
|
||||
schedule_tx_task(FRAME_TYPE_DESC_ADVS, NULL, NULL, pb->i.iif, dhn->descContent->desc_frame_len, &dhn->dhash, sizeof(DHASH_T));
|
||||
|
||||
|
||||
} else {
|
||||
dbgf_sys(DBGT_WARN, "UNVERIFIED neigh=%s llip=%s or UNKNOWN dhash=%s or OUTDATED dhn=%d dc=%d on=%d",
|
||||
pb->i.verifiedLink? cryptShaAsString(&pb->i.verifiedLink->k.linkDev->key.local->local_id) : NULL,
|
||||
pb->i.llip_str, cryptShaAsString(&msg->dhash), !!dhn, (dhn && dhn->descContent), (dhn && dhn->descContent && dhn->descContent->orig));
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof(struct msg_description_request);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_frame_description_adv(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
DHASH_T *dhash = (DHASH_T*)it->ttn->key.data;
|
||||
struct dhash_node *dhn = avl_find_item(&dhash_tree, dhash);
|
||||
struct desc_content *dc = dhn ? dhn->descContent : NULL;
|
||||
|
||||
if (!dc || !dc->orig) {
|
||||
dbgf_sys(DBGT_WARN, "%s dhash=%s!", dc ? "UnKnown" : "UnPromoted", cryptShaAsString(dhash));
|
||||
return TLV_TX_DATA_DONE;
|
||||
}
|
||||
|
||||
assertion(-502060, (dc->desc_frame_len == it->ttn->frame_msgs_length));
|
||||
assertion(-502061, (dc->desc_frame_len <= tx_iterator_cache_data_space_max(it, 0, 0)));
|
||||
|
||||
memcpy(tx_iterator_cache_msg_ptr(it), dc->desc_frame, dc->desc_frame_len);
|
||||
dc->dhn->referred_by_me_timestamp = bmx_time;
|
||||
dbgf_track(DBGT_INFO, "dhash=%s id=%s descr_size=%d",
|
||||
cryptShaAsString(dhash), cryptShaAsString(&dc->key->kHash), dc->desc_frame_len);
|
||||
|
||||
return dc->desc_frame_len;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_frame_description_adv(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
int32_t goto_error_code;
|
||||
struct key_node *kn;
|
||||
GLOBAL_ID_T *nodeId = NULL;
|
||||
struct dsc_msg_version *versMsg;
|
||||
DHASH_T dhash;
|
||||
struct dhash_node *dhn = NULL;
|
||||
struct desc_content *dc = NULL;
|
||||
|
||||
cryptShaAtomic(it->f_data, it->f_dlen, &dhash);
|
||||
|
||||
if (!(nodeId = get_desc_id(it->f_data, it->f_dlen, NULL, &versMsg)))
|
||||
goto_error(finish, TLV_RX_DATA_FAILURE);
|
||||
|
||||
if (!(kn = keyNode_get(nodeId)) || (kn->bookedState->i.c < KCTracked) || !kn->content || !kn->content->f_body)
|
||||
goto_error(finish, it->f_dlen);
|
||||
|
||||
if ((kn->nextDesc && kn->nextDesc->descSqn >= ntohl(versMsg->descSqn)) ||
|
||||
(kn->currOrig && kn->currOrig->descContent->descSqn >= ntohl(versMsg->descSqn)))
|
||||
goto_error(finish, it->f_dlen);
|
||||
|
||||
if ((dhn = avl_find_item(&dhash_tree, &dhash)) && (dhn->descContent || dhn->rejected))
|
||||
goto_error(finish, it->f_dlen);
|
||||
|
||||
if (!test_description_signature(it->f_data, it->f_dlen))
|
||||
goto_error(finish, TLV_RX_DATA_FAILURE);
|
||||
|
||||
if ((dc = descContent_create(it->f_data, it->f_dlen, kn)) && !dc->unresolvedContentCounter)
|
||||
keyNode_updCredits(NULL, kn, NULL);
|
||||
|
||||
goto_error(finish, it->f_dlen);
|
||||
|
||||
finish:
|
||||
if (dhn)
|
||||
dhn->referred_by_others_timestamp = bmx_time;
|
||||
|
||||
dbgf_track(DBGT_INFO, "rcvd dhash=%s nodeId=%s via_dev=%s via_ip=%s dc=%d",
|
||||
memAsHexString(&dhash, sizeof(SHA1_T)), cryptShaAsString(nodeId),
|
||||
it->pb->i.iif->label_cfg.str, it->pb->i.llip_str, !!dc);
|
||||
|
||||
return goto_error_code;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_dhash_request(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct hdr_dhash_request *hdr = ((struct hdr_dhash_request*) tx_iterator_cache_hdr_ptr(it));
|
||||
struct msg_dhash_request *msg = ((struct msg_dhash_request*) tx_iterator_cache_msg_ptr(it));
|
||||
DHASH_T *dhash = ((DHASH_T*) it->ttn->key.data);
|
||||
struct dhash_node *dhn = avl_find_item(&dhash_tree, dhash);
|
||||
struct reference_node *ref;
|
||||
|
||||
if (!dhn || dhn->rejected || !dhn->neighRefs_tree.items || ((ref = avl_find_item(&it->ttn->neigh->refsByDhash_tree, &dhn)) && ref->claimedKey))
|
||||
return TLV_TX_DATA_DONE;
|
||||
|
||||
if (hdr->msg == msg) {
|
||||
assertion(-502287, (is_zero(hdr, sizeof(*hdr))));
|
||||
hdr->dest_nodeId = it->ttn->key.f.groupId;
|
||||
} else {
|
||||
assertion(-502288, (cryptShasEqual(&hdr->dest_nodeId, &it->ttn->key.f.groupId)));
|
||||
}
|
||||
|
||||
msg->dhash = *dhash;
|
||||
|
||||
return sizeof(struct msg_dhash_request);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_frame_dhash_request(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct neigh_node *nn = it->pb->i.verifiedLink->k.linkDev->key.local;
|
||||
struct hdr_dhash_request *hdr = (struct hdr_dhash_request*) (it->f_data);
|
||||
struct msg_dhash_request *msg = (struct msg_dhash_request*) (it->f_msg);
|
||||
|
||||
if (cryptShasEqual(&hdr->dest_nodeId, &myKey->kHash)) {
|
||||
|
||||
for (; msg < &(hdr->msg[it->f_msgs_fixed]); msg++) {
|
||||
|
||||
if ((avl_find(&dhash_tree, &msg->dhash)))
|
||||
schedule_tx_task(FRAME_TYPE_DHASH_ADV, NULL, NULL, nn->best_tp_link->k.myDev, SCHEDULE_MIN_MSG_SIZE, &msg->dhash, sizeof(DHASH_T));
|
||||
}
|
||||
}
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void dhash_tree_maintain(void)
|
||||
{
|
||||
struct dhash_node *dhn = NULL;
|
||||
DHASH_T dhash = ZERO_CYRYPSHA1;
|
||||
|
||||
while ((dhn = avl_next_item(&dhash_tree, &dhash))) {
|
||||
|
||||
dhash = dhn->dhash;
|
||||
|
||||
if (dhn->descContent || dhn->rejected)
|
||||
continue;
|
||||
|
||||
struct neigh_node *nn = NULL;
|
||||
struct reference_node *ref;
|
||||
|
||||
while (dhn && (ref = avl_next_item(&dhn->neighRefs_tree, &nn))) {
|
||||
|
||||
struct key_node *claimedKey = ref->claimedKey;
|
||||
nn = ref->neigh;
|
||||
|
||||
assertion(-502500, IMPLIES(claimedKey, avl_find(&claimedKey->neighRefs_tree, &nn)));
|
||||
|
||||
if (((AGGREG_SQN_T) ((nn->ogm_aggreg_max - ref->aggSqn)) >= nn->ogm_aggreg_size) && !claimedKey) {
|
||||
|
||||
if (dhn->neighRefs_tree.items == 1)
|
||||
dhn = NULL;
|
||||
|
||||
refNode_destroy(ref, NO);
|
||||
|
||||
} else if (!claimedKey) {
|
||||
|
||||
schedule_tx_task(FRAME_TYPE_DHASH_REQ, &nn->local_id, nn, nn->best_tp_link->k.myDev, SCHEDULE_MIN_MSG_SIZE, &dhn->dhash, sizeof(dhn->dhash));
|
||||
|
||||
} else if (claimedKey->content && !claimedKey->content->f_body) {
|
||||
|
||||
assertion(-502323, (claimedKey->bookedState->i.c >= KCTracked));
|
||||
|
||||
//schedule_tx_task(FRAME_TYPE_CONTENT_REQ, &nn->local_id, nn, nn->best_tp_link->k.myDev, SCHEDULE_MIN_MSG_SIZE, &ck->kHash, sizeof(ck->kHash));
|
||||
|
||||
} else if (claimedKey->content) {
|
||||
|
||||
assertion(-502324, (claimedKey->bookedState->i.c >= KCTracked && claimedKey->content->f_body));
|
||||
|
||||
schedule_tx_task(FRAME_TYPE_DESC_REQ, &nn->local_id, nn, nn->best_tp_link->k.myDev, SCHEDULE_MIN_MSG_SIZE, &dhn->dhash, sizeof(dhn->dhash));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_dhash_adv(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct msg_dhash_adv *msg = ((struct msg_dhash_adv*) tx_iterator_cache_msg_ptr(it));
|
||||
struct dhash_node *dhn;
|
||||
|
||||
if ((dhn = avl_find_item(&dhash_tree, ((DHASH_T*)it->ttn->key.data)))) {
|
||||
|
||||
msg->dhash = dhn->dhash;
|
||||
|
||||
if (dhn->descContent) {
|
||||
msg->descSqn = htonl(dhn->descContent->descSqn);
|
||||
msg->kHash = dhn->descContent->key->kHash;
|
||||
} //else: notify requesting node of stale dhash.
|
||||
|
||||
return sizeof(struct msg_dhash_adv);
|
||||
}
|
||||
|
||||
return TLV_TX_DATA_DONE;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_msg_dhash_adv(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct msg_dhash_adv *msg = (struct msg_dhash_adv*) (it->f_msg);
|
||||
struct neigh_node *nn = it->pb->i.verifiedLink->k.linkDev->key.local;
|
||||
AGGREG_SQN_T aggSqnInvalidMax = (nn->ogm_aggreg_max - AGGREG_SQN_CACHE_RANGE);
|
||||
struct reference_node *ref;
|
||||
|
||||
if (!msg->descSqn) {
|
||||
|
||||
if ((ref = avl_find_item(&nn->refsByDhash_tree, &msg->dhash)))
|
||||
ref->aggSqn = aggSqnInvalidMax; // do not try to resolve this anymore
|
||||
|
||||
} else {
|
||||
refNode_update(nn, aggSqnInvalidMax, &msg->dhash, &msg->kHash, ntohl(msg->descSqn));
|
||||
}
|
||||
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t opt_dsqn_path(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn)
|
||||
{
|
||||
static uint8_t checked = NO;
|
||||
|
||||
if ( (cmd == OPT_CHECK || cmd == OPT_SET_POST) && initializing && !checked ) {
|
||||
|
||||
if (!newDescriptionSqn((cmd==OPT_CHECK ? patch->val : DEF_DSQN_PATH), 0))
|
||||
return FAILURE;
|
||||
|
||||
checked = YES;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t opt_update_description(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
if ( cmd == OPT_APPLY )
|
||||
my_description_changed = YES;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
struct opt_type desc_options[]=
|
||||
{
|
||||
// ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help
|
||||
|
||||
#ifndef LESS_OPTIONS
|
||||
{ODI,0,ARG_DESC_ROOT_SIZE, 0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &desc_root_size_out,MIN_DESC_ROOT_SIZE, MAX_DESC_ROOT_SIZE, DEF_DESC_ROOT_SIZE,0, opt_update_dext_method,
|
||||
ARG_VALUE_FORM, HLP_DESC_ROOT_SIZE},
|
||||
{ODI,0,ARG_VRT_FRAME_DATA_SIZE_OUT,0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &vrt_frame_data_size_out,MIN_VRT_FRAME_DATA_SIZE,MAX_VRT_FRAME_DATA_SIZE,DEF_VRT_FRAME_DATA_SIZE,0, opt_update_dext_method,
|
||||
ARG_VALUE_FORM, HLP_VRT_FRAME_DATA_SIZE_OUT},
|
||||
{ODI,0,ARG_VRT_FRAME_DATA_SIZE_IN, 0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &vrt_frame_data_size_in,MIN_VRT_FRAME_DATA_SIZE,MAX_VRT_FRAME_DATA_SIZE,DEF_VRT_FRAME_DATA_SIZE,0, opt_update_dext_method,
|
||||
ARG_VALUE_FORM, HLP_VRT_FRAME_DATA_SIZE_IN},
|
||||
{ODI,0,ARG_DESC_VBODIES_SIZE_OUT, 0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &desc_vbodies_size_out,MIN_DESC_VBODIES_SIZE,MAX_DESC_VBODIES_SIZE,DEF_DESC_VBODIES_SIZE,0, opt_update_dext_method,
|
||||
ARG_VALUE_FORM, HLP_DESC_VBODIES_SIZE_OUT},
|
||||
{ODI,0,ARG_DESC_VBODIES_SIZE_IN, 0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &desc_vbodies_size_in,MIN_DESC_VBODIES_SIZE,MAX_DESC_VBODIES_SIZE,DEF_DESC_VBODIES_SIZE,0, opt_update_dext_method,
|
||||
ARG_VALUE_FORM, HLP_DESC_VBODIES_SIZE_IN},
|
||||
{ODI,0,ARG_UNSOLICITED_DESC_ADVS, 0, 9,0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &unsolicitedDescAdvs,MIN_UNSOLICITED_DESC_ADVS,MAX_UNSOLICITED_DESC_ADVS,DEF_UNSOLICITED_DESC_ADVS,0,0,
|
||||
ARG_VALUE_FORM, NULL},
|
||||
#endif
|
||||
{ODI, 0, ARG_DESCRIPTIONS, 0, 9,2, A_PS0N,A_USR, A_DYN, A_ARG, A_ANY, 0, 0, 0, 0,0, opt_show_descriptions,
|
||||
0, HLP_DESCRIPTIONS}
|
||||
,
|
||||
{ODI,ARG_DESCRIPTIONS,ARG_DESCRIPTION_TYPE,'t',9,2,A_CS1,A_USR,A_DYN,A_ARG,A_ANY,0, MIN_DESCRIPTION_TYPE,MAX_DESCRIPTION_TYPE,DEF_DESCRIPTION_TYPE,0,opt_show_descriptions,
|
||||
"<TYPE>", HLP_DESCRIPTION_TYPE}
|
||||
,
|
||||
{ODI,ARG_DESCRIPTIONS,ARG_DESCRIPTION_NAME,'n',9,2,A_CS1,A_USR,A_DYN,A_ARG,A_ANY,0, 0, 0, 0,0, opt_show_descriptions,
|
||||
"<NAME>", "only show description of nodes with given name"}
|
||||
,
|
||||
{ODI,ARG_DESCRIPTIONS,ARG_RELEVANCE, 'r',9,2,A_CS1,A_USR,A_DYN,A_ARG,A_ANY,0, MIN_RELEVANCE, MAX_RELEVANCE, DEF_RELEVANCE,0, opt_show_descriptions,
|
||||
ARG_VALUE_FORM, HLP_ARG_RELEVANCE},
|
||||
|
||||
{ODI,0,ARG_DSQN_PATH, 0, 9,1,A_PS1,A_ADM,A_INI,A_CFA,A_ANY, 0, 0, 0, 0,DEF_DSQN_PATH,opt_dsqn_path,
|
||||
ARG_DIR_FORM, "set path to file containing latest used description SQN of this node"},
|
||||
|
||||
{ODI,0,"descUpdate", 0, 9,1,A_PS0,A_ADM,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0,0, opt_update_description,
|
||||
0, "update own description"}
|
||||
,
|
||||
|
||||
};
|
||||
|
||||
void init_desc( void )
|
||||
{
|
||||
register_options_array( desc_options, sizeof( desc_options ), CODE_CATEGORY_NAME );
|
||||
|
||||
|
||||
struct frame_handl handl;
|
||||
memset(&handl, 0, sizeof ( handl));
|
||||
|
||||
static const struct field_format version_format[] = VERSION_MSG_FORMAT;
|
||||
handl.name = "DSC_VERSION";
|
||||
handl.alwaysMandatory = 1;
|
||||
handl.min_msg_size = sizeof (struct dsc_msg_version);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.dextReferencing = (int32_t*)&fref_never;
|
||||
handl.dextCompression = (int32_t*)&never_fzip;
|
||||
handl.tx_frame_handler = create_dsc_tlv_version;
|
||||
handl.rx_frame_handler = process_dsc_tlv_version;
|
||||
handl.msg_format = version_format;
|
||||
register_frame_handler(description_tlv_db, BMX_DSC_TLV_VERSION, &handl);
|
||||
|
||||
|
||||
static const struct field_format names_format[] = DESCRIPTION_MSG_NAME_FORMAT;
|
||||
handl.name = "DSC_NAMES";
|
||||
handl.min_msg_size = sizeof(struct description_msg_name);
|
||||
handl.fixed_msg_size = 0;
|
||||
handl.dextReferencing = (int32_t*)&fref_dflt;
|
||||
handl.dextCompression = (int32_t*)&dflt_fzip;
|
||||
handl.tx_frame_handler = create_dsc_tlv_names;
|
||||
handl.rx_frame_handler = process_dsc_tlv_names;
|
||||
handl.msg_format = names_format;
|
||||
register_frame_handler(description_tlv_db, BMX_DSC_TLV_NAMES, &handl);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
handl.name = "DESC_REQ";
|
||||
handl.rx_processUnVerifiedLink = 1;
|
||||
handl.data_header_size = sizeof( struct hdr_description_request);
|
||||
handl.min_msg_size = sizeof(struct msg_description_request);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_msg_handler = tx_msg_description_request;
|
||||
handl.rx_msg_handler = rx_msg_description_request;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_DESC_REQ, &handl);
|
||||
|
||||
handl.name = "DESC_ADV";
|
||||
handl.rx_processUnVerifiedLink = 1;
|
||||
handl.min_msg_size = (
|
||||
sizeof(struct tlv_hdr) + sizeof(struct dsc_hdr_chash) +
|
||||
sizeof(struct tlv_hdr) + sizeof(struct dsc_msg_signature) +
|
||||
sizeof(struct tlv_hdr) + sizeof(struct dsc_msg_version) );
|
||||
handl.tx_packet_prepare_always = update_my_description;
|
||||
handl.tx_frame_handler = tx_frame_description_adv;
|
||||
handl.rx_frame_handler = rx_frame_description_adv;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_DESC_ADVS, &handl);
|
||||
|
||||
|
||||
handl.name = "DHASH_REQ";
|
||||
handl.data_header_size = sizeof( struct hdr_dhash_request);
|
||||
handl.min_msg_size = sizeof (struct msg_dhash_request);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_packet_prepare_always = dhash_tree_maintain;
|
||||
handl.tx_msg_handler = tx_msg_dhash_request;
|
||||
handl.rx_frame_handler = rx_frame_dhash_request;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_DHASH_REQ, &handl);
|
||||
|
||||
handl.name = "DHASH_ADV";
|
||||
handl.min_msg_size = sizeof (struct msg_dhash_adv);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_msg_handler = tx_msg_dhash_adv;
|
||||
handl.rx_msg_handler = rx_msg_dhash_adv;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_DHASH_ADV, &handl);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
155
desc.h
Normal file
155
desc.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#define ARG_DESC_ROOT_SIZE "descRootSizeOut"
|
||||
extern int32_t desc_root_size_out;
|
||||
#define HLP_DESC_ROOT_SIZE "set maximum size for own description and references"
|
||||
#define MIN_DESC_ROOT_SIZE (MIN_UDPD_SIZE - sizeof(struct packet_header) - (2*sizeof(struct tlv_hdr)))
|
||||
#define MAX_DESC_ROOT_SIZE (MAX_UDPD_SIZE - sizeof(struct packet_header) - (2*sizeof(struct tlv_hdr)))
|
||||
#define DEF_DESC_ROOT_SIZE MAX_DESC_ROOT_SIZE
|
||||
#define REF_CONTENT_BODY_SIZE_OUT (desc_root_size_out - sizeof(struct frame_hdr_content_adv))
|
||||
#define REF_CONTENT_BODY_SIZE_MAX (MAX_DESC_ROOT_SIZE - sizeof(struct frame_hdr_content_adv))
|
||||
|
||||
extern int32_t vrt_frame_max_nesting;
|
||||
|
||||
|
||||
#define ARG_VRT_FRAME_DATA_SIZE_OUT "descVirtFrameSizeOut"
|
||||
#define HLP_VRT_FRAME_DATA_SIZE_OUT "set maximum virtual size for own description frames"
|
||||
#define ARG_VRT_FRAME_DATA_SIZE_IN "descVirtFrameSizeIn"
|
||||
#define HLP_VRT_FRAME_DATA_SIZE_IN "set maximum virtual size for other description frames"
|
||||
#define MIN_VRT_FRAME_DATA_SIZE (MIN_DESC_ROOT_SIZE)
|
||||
#define MAX_VRT_FRAME_DATA_SIZE (4*((REF_CONTENT_BODY_SIZE_MAX / sizeof(SHA1_T)) * REF_CONTENT_BODY_SIZE_MAX))
|
||||
#define DEF_VRT_FRAME_DATA_SIZE (2*((REF_CONTENT_BODY_SIZE_MAX / sizeof(SHA1_T)) * REF_CONTENT_BODY_SIZE_MAX))
|
||||
extern int32_t vrt_frame_data_size_in;
|
||||
extern int32_t vrt_frame_data_size_out;
|
||||
|
||||
|
||||
|
||||
#define ARG_DESC_VBODIES_SIZE_OUT "descVirtSizeOut"
|
||||
#define HLP_DESC_VBODIES_SIZE_OUT "set maximum virtual size for own description"
|
||||
#define ARG_DESC_VBODIES_SIZE_IN "descVirtSizeIn"
|
||||
#define HLP_DESC_VBODIES_SIZE_IN "set maximum virtual size for other node descriptions"
|
||||
#define MIN_DESC_VBODIES_SIZE (MIN_DESC_ROOT_SIZE)
|
||||
// this should be the max possible with a reference depth of 1 :
|
||||
#define MAX_DESC_VBODIES_SIZE (10 * MAX_VRT_FRAME_DATA_SIZE)
|
||||
#define DEF_DESC_VBODIES_SIZE ( 4 * MAX_VRT_FRAME_DATA_SIZE)
|
||||
|
||||
extern int32_t desc_vbodies_size_in;
|
||||
extern int32_t desc_vbodies_size_out;
|
||||
|
||||
#define MIN_DESC0_REFERRED_TO 10000
|
||||
#define MAX_DESC0_REFERRED_TO 100000
|
||||
#define DEF_DESC0_REFERRED_TO 10000
|
||||
|
||||
#define DEF_UNSOLICITED_DESC_ADVS 1
|
||||
#define MIN_UNSOLICITED_DESC_ADVS 0
|
||||
#define MAX_UNSOLICITED_DESC_ADVS 1
|
||||
#define ARG_UNSOLICITED_DESC_ADVS "unsolicitedDescAdvs"
|
||||
|
||||
#define ARG_DSQN_PATH "descSqnPath"
|
||||
#define DEF_DSQN_PATH "/etc/bmx6/descSqn"
|
||||
|
||||
|
||||
#define ARG_DESCRIPTIONS "descriptions"
|
||||
#define HLP_DESCRIPTIONS "show node descriptions\n"
|
||||
|
||||
#define ARG_DESCRIPTION_NAME "name"
|
||||
|
||||
#define ARG_DESCRIPTION_TYPE "type"
|
||||
#define DEF_DESCRIPTION_TYPE FRAME_TYPE_PROCESS_ALL
|
||||
#define MIN_DESCRIPTION_TYPE 0
|
||||
#define MAX_DESCRIPTION_TYPE FRAME_TYPE_PROCESS_ALL
|
||||
#define HLP_DESCRIPTION_TYPE "show description extension(s) of given type (0..253=type 254=none 255=all) \n"
|
||||
|
||||
struct msg_dhash_adv {
|
||||
DHASH_T dhash;
|
||||
GLOBAL_ID_T kHash;
|
||||
DESC_SQN_T descSqn;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
struct msg_dhash_request {
|
||||
DHASH_T dhash;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hdr_dhash_request { // 20 bytes
|
||||
GLOBAL_ID_T dest_nodeId;
|
||||
struct msg_dhash_request msg[];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct msg_description_request { // 2 bytes
|
||||
DHASH_T dhash;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hdr_description_request { // 20 bytes
|
||||
DHASH_T dest_kHash;
|
||||
struct msg_description_request msg[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define VERSION_MSG_FORMAT { \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, "comp_version" }, \
|
||||
{FIELD_TYPE_HEX, -1, 8, 1, FIELD_RELEVANCE_MEDI, "capabilities" }, \
|
||||
{FIELD_TYPE_UINT, -1, (8*sizeof(DESC_SQN_T)), 0, FIELD_RELEVANCE_HIGH, "descSqn" }, \
|
||||
{FIELD_TYPE_HEX, -1, 32, 0, FIELD_RELEVANCE_HIGH, "codeRevision" }, \
|
||||
FIELD_FORMAT_END}
|
||||
|
||||
struct description_msg_name {
|
||||
uint8_t type;
|
||||
uint8_t len;
|
||||
char name[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DESCRIPTION_MSG_NAME_FORMAT { \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, "type"}, \
|
||||
{FIELD_TYPE_STRING_SIZE, -1, 8, 0, FIELD_RELEVANCE_LOW, "len"}, \
|
||||
{FIELD_TYPE_STRING_BINARY, -1, 0, 1, FIELD_RELEVANCE_LOW, "name" }, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void process_description_tlvs_del(struct orig_node *on, struct desc_content *dcOld, uint8_t ft_start, uint8_t ft_end);
|
||||
IDM_T process_description_tlvs(struct packet_buff *pb, struct orig_node *on, struct desc_content *dcOld, struct desc_content *dcNew, uint8_t op, uint8_t filter);
|
||||
void update_my_description(void);
|
||||
|
||||
void update_orig_dhash(struct desc_content *dc);
|
||||
|
||||
SHA1_T *nodeIdFromDescAdv(uint8_t *desc_adv);
|
||||
char *nodeIdAsStringFromDescAdv(uint8_t *desc_adv);
|
||||
IDM_T desc_frame_changed(struct rx_frame_iterator *it, uint8_t type);
|
||||
|
||||
int32_t opt_update_dext_method(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
int32_t opt_update_description(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn);
|
||||
|
||||
void init_desc(void);
|
||||
|
||||
|
60
dump.c
60
dump.c
@@ -44,7 +44,6 @@ static int64_t curr_dump_period = DEF_DUMP_PERIOD;
|
||||
static int32_t next_dump_period = DEF_DUMP_PERIOD;
|
||||
static int32_t prev_dump_period = DEF_DUMP_PERIOD;
|
||||
|
||||
static int32_t dump_regression_exp = DEF_DUMP_REGRESSION_EXP;
|
||||
static uint32_t dump_iteration = 0;
|
||||
|
||||
static IDM_T dump_terminating = NO;
|
||||
@@ -63,8 +62,8 @@ void update_traffic_statistics_data(struct dump_data *data)
|
||||
for (t = 0; t < DUMP_TYPE_ARRSZ; t++) {
|
||||
data->pre_all[i][t] = (((int64_t)(data->tmp_all[i][t])) * 1000) / curr_dump_period;
|
||||
|
||||
data->avg_all[i][t] -= (data->avg_all[i][t] >> dump_regression_exp);
|
||||
data->avg_all[i][t] += ((data->pre_all[i][t]) >> dump_regression_exp);
|
||||
data->avg_all[i][t] -= (data->avg_all[i][t] / devStatRegression);
|
||||
data->avg_all[i][t] += ((data->pre_all[i][t]) / devStatRegression);
|
||||
data->tmp_all[i][t] = 0;
|
||||
}
|
||||
|
||||
@@ -72,8 +71,8 @@ void update_traffic_statistics_data(struct dump_data *data)
|
||||
for (t = 0; t < FRAME_TYPE_ARRSZ; t++) {
|
||||
data->pre_frame[i][t] = (((int64_t)(data->tmp_frame[i][t])) * 1000) / curr_dump_period;
|
||||
|
||||
data->avg_frame[i][t] -= (data->avg_frame[i][t] >> dump_regression_exp);
|
||||
data->avg_frame[i][t] += ((data->pre_frame[i][t]) >> dump_regression_exp);
|
||||
data->avg_frame[i][t] -= (data->avg_frame[i][t] / devStatRegression);
|
||||
data->avg_frame[i][t] += ((data->pre_frame[i][t]) / devStatRegression);
|
||||
data->tmp_frame[i][t] = 0;
|
||||
}
|
||||
}
|
||||
@@ -146,10 +145,10 @@ void dump(struct packet_buff *pb)
|
||||
|
||||
|
||||
struct rx_frame_iterator it = {
|
||||
.caller = __FUNCTION__, .onOld = NULL, .op = 0, .pb = NULL, .dbgl = DBGL_ALL,
|
||||
.caller = __FUNCTION__, .op = 0,
|
||||
.db = packet_frame_db, .process_filter = FRAME_TYPE_PROCESS_NONE,
|
||||
.frame_type = -1, .frames_in = (((uint8_t*) phdr) + sizeof (struct packet_header)),
|
||||
.frames_length = (plength - sizeof (struct packet_header)), .frames_pos = 0 };
|
||||
.f_type = -1, .frames_in = (((uint8_t*) phdr) + sizeof (struct packet_header)),
|
||||
.frames_length = (plength - sizeof (struct packet_header)), ._f_pos_next = 0 };
|
||||
|
||||
int32_t result;
|
||||
uint16_t pkt_pos = sizeof (struct packet_header);
|
||||
@@ -160,46 +159,46 @@ void dump(struct packet_buff *pb)
|
||||
char *tname;
|
||||
int16_t frame_msgs = -1;
|
||||
|
||||
if (!(tname = it.db->handls[it.frame_type].name)) {
|
||||
sprintf(tnum, "%d", it.frame_type);
|
||||
if (!(tname = it.db->handls[it.f_type].name)) {
|
||||
sprintf(tnum, "%d", it.f_type);
|
||||
tname = tnum;
|
||||
}
|
||||
|
||||
if (it.db->handls[it.frame_type].fixed_msg_size) {
|
||||
frame_msgs = it.frame_msgs_length / it.db->handls[it.frame_type].min_msg_size;
|
||||
if (it.db->handls[it.f_type].fixed_msg_size) {
|
||||
frame_msgs = it.f_msgs_len / it.db->handls[it.f_type].min_msg_size;
|
||||
}
|
||||
|
||||
|
||||
dbgf(DBGL_DUMP, DBGT_NONE, "%s frame_type=%-12s data_header_size=%-3d msgs=%-3d frame_length=%-4d",
|
||||
direction == DUMP_DIRECTION_IN ? "in " : "out", tname,
|
||||
it.db->handls[it.frame_type].data_header_size, frame_msgs, it.frame_length);
|
||||
it.db->handls[it.f_type].data_header_size, frame_msgs, it._f_len);
|
||||
|
||||
dbgf(DBGL_DUMP, DBGT_NONE, "%s data [%3d...%3d]:%s",
|
||||
direction == DUMP_DIRECTION_IN ? "in hex" : "out hex",
|
||||
pkt_pos, pkt_pos + it.frame_length - 1, memAsHexString(((uint8_t*) phdr) + pkt_pos, it.frame_length));
|
||||
pkt_pos, pkt_pos + it._f_len - 1, memAsHexString(((uint8_t*) phdr) + pkt_pos, it._f_len));
|
||||
|
||||
//assertion(-500991, (it.hands->hands[it.frame_type].min_msg_size));
|
||||
assertion(-500992, (it.frame_msgs_length >= 0));
|
||||
assertion(-500992, (it.f_msgs_len >= 0));
|
||||
|
||||
(*dev_plugin_data)->tmp_frame[direction][it.frame_type] += (it.frame_length << IMPROVE_ROUNDOFF);
|
||||
(*dev_plugin_data)->tmp_frame[direction][it.f_type] += (it._f_len << IMPROVE_ROUNDOFF);
|
||||
|
||||
dump_all.tmp_frame[direction][it.frame_type] += (it.frame_length << IMPROVE_ROUNDOFF);
|
||||
dump_all.tmp_frame[direction][it.f_type] += (it._f_len << IMPROVE_ROUNDOFF);
|
||||
|
||||
(*dev_plugin_data)->tmp_all[direction][DUMP_TYPE_FRAME_HEADER] += ((it.frame_length - it.frame_data_length) << IMPROVE_ROUNDOFF);
|
||||
(*dev_plugin_data)->tmp_all[direction][DUMP_TYPE_FRAME_HEADER] += ((it._f_len - it.f_dlen) << IMPROVE_ROUNDOFF);
|
||||
|
||||
dump_all.tmp_all[direction][DUMP_TYPE_FRAME_HEADER] += ((it.frame_length - it.frame_data_length) << IMPROVE_ROUNDOFF);
|
||||
dump_all.tmp_all[direction][DUMP_TYPE_FRAME_HEADER] += ((it._f_len - it.f_dlen) << IMPROVE_ROUNDOFF);
|
||||
|
||||
pkt_pos += it.frame_length;
|
||||
pkt_pos += it._f_len;
|
||||
}
|
||||
|
||||
if (result != TLV_RX_DATA_DONE) {
|
||||
|
||||
dbgf(DBGL_DUMP, DBGT_NONE, "%s ERROR frame_type=%d frame_length=%d frame_data_length=%d result=%s - ignoring further frames!!",
|
||||
direction == DUMP_DIRECTION_IN ? "in " : "out", it.frame_type, it.frame_length, it.frame_data_length, tlv_rx_result_str(result));
|
||||
direction == DUMP_DIRECTION_IN ? "in " : "out", it.f_type, it._f_len, it.f_dlen, tlv_rx_result_str(result));
|
||||
|
||||
dbgf(DBGL_DUMP, DBGT_NONE, "%s data [%3d...%3d]:%s",
|
||||
direction == DUMP_DIRECTION_IN ? "in hex" : "out hex",
|
||||
pkt_pos, pkt_pos + it.frame_length - 1, memAsHexString(((uint8_t*) phdr) + pkt_pos, it.frame_length));
|
||||
pkt_pos, pkt_pos + it._f_len - 1, memAsHexString(((uint8_t*) phdr) + pkt_pos, it._f_len));
|
||||
}
|
||||
|
||||
assertion(-500990, (IMPLIES(direction == DUMP_DIRECTION_OUT, result == TLV_RX_DATA_DONE)));
|
||||
@@ -212,11 +211,8 @@ void dbg_traffic_statistics(struct dump_data *data, struct ctrl_node *cn, char*
|
||||
{
|
||||
uint16_t t;
|
||||
|
||||
dbg_printf(cn, "%-20s \n", dbg_name);
|
||||
|
||||
|
||||
for (t = 0; t < DUMP_TYPE_ARRSZ; t++) {
|
||||
dbg_printf(cn, "%13s %5d (%3d) %5d (%3d) %5d (%3d) | %5d (%3d) %5d (%3d) %5d (%3d)\n",
|
||||
dbg_printf(cn, "%-11s %15s %5d (%3d) %5d (%3d) %5d (%3d) | %5d (%3d) %5d (%3d) %5d (%3d)\n", dbg_name,
|
||||
t == DUMP_TYPE_UDP_PAYLOAD ? "UDP_PAYLOAD" : (t == DUMP_TYPE_PACKET_HEADER ? "PACKET_HEADER" : "FRAME_HEADER"),
|
||||
|
||||
|
||||
@@ -270,11 +266,10 @@ void dbg_traffic_statistics(struct dump_data *data, struct ctrl_node *cn, char*
|
||||
if (!tname) {
|
||||
sprintf(tnum, "%d", t);
|
||||
tname = tnum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dbg_printf(cn, "%13s %5d (%3d) %5d (%3d) %5d (%3d) | %5d (%3d) %5d (%3d) %5d (%3d)\n",
|
||||
tname,
|
||||
dbg_printf(cn, "%-11s %15s %5d (%3d) %5d (%3d) %5d (%3d) | %5d (%3d) %5d (%3d) %5d (%3d)\n", dbg_name, tname,
|
||||
|
||||
((data->pre_frame[DUMP_DIRECTION_IN][t] + data->pre_frame[DUMP_DIRECTION_OUT][t]) >> IMPROVE_ROUNDOFF),
|
||||
|
||||
@@ -329,10 +324,10 @@ int32_t opt_traffic_statistics(uint8_t cmd, uint8_t _save, struct opt_type *opt,
|
||||
struct dev_node *dev;
|
||||
struct avl_node *an = NULL;
|
||||
|
||||
dbg_printf(cn, "iteration=%d as [Bytes/sec], averaged over %.1f secs and as weighted averages\n",
|
||||
dbg_printf(cn, "TRAFFIC: iteration=%d as [Bytes/sec], averaged over %.1f secs and as weighted averages\n",
|
||||
dump_iteration, (float)curr_dump_period / 1000);
|
||||
|
||||
dbg_printf(cn, "%20s ( %% ) in ( %% ) out ( %% ) | all ( %% ) in ( %% ) out ( %% )\n"," ");
|
||||
dbg_printf(cn, "%-30s all ( %% ) in ( %% ) out ( %% ) | all ( %% ) in ( %% ) out ( %% )\n", "dev");
|
||||
|
||||
if (!strcmp(patch->val, ARG_DUMP_ALL) || !strcmp(patch->val, ARG_DUMP_SUMMARY))
|
||||
dbg_traffic_statistics(&dump_all, cn, ARG_DUMP_ALL);
|
||||
@@ -366,9 +361,6 @@ struct opt_type dump_options[]=
|
||||
{ODI, 0, ARG_DUMP_PERIOD, 0, 9,1, A_PS1, A_ADM, A_DYI, A_ARG, A_ANY, &next_dump_period, MIN_DUMP_PERIOD, MAX_DUMP_PERIOD, DEF_DUMP_PERIOD,0, 0,
|
||||
ARG_VALUE_FORM, "set duration in ms for how long traffic is measured for calculating interval averages"}
|
||||
,
|
||||
{ODI, 0, ARG_DUMP_REGRESSION_EXP, 0, 9,1, A_PS1, A_ADM, A_DYI, A_ARG, A_ANY, &dump_regression_exp,MIN_DUMP_REGRESSION_EXP,MAX_DUMP_REGRESSION_EXP,DEF_DUMP_REGRESSION_EXP,0,0,
|
||||
ARG_VALUE_FORM, "set regression exponent for traffic-dump statistics "}
|
||||
,
|
||||
{ODI, 0, ARG_DUMP, 0, 9,2, A_PS1, A_USR, A_DYN, A_ARG, A_ANY, 0, 0, 0, 0,0, opt_traffic_statistics,
|
||||
"<DEV>", "show traffic statistics for given device name, summary, or all\n"}
|
||||
|
||||
|
4
dump.h
4
dump.h
@@ -37,10 +37,6 @@
|
||||
#define ARG_DUMP_SUMMARY "summary"
|
||||
|
||||
|
||||
#define DEF_DUMP_REGRESSION_EXP 4
|
||||
#define MIN_DUMP_REGRESSION_EXP 0
|
||||
#define MAX_DUMP_REGRESSION_EXP 20
|
||||
#define ARG_DUMP_REGRESSION_EXP "trafficRegressionExponent"
|
||||
|
||||
|
||||
#define DUMP_TYPE_UDP_PAYLOAD 0
|
||||
|
16
hna.h
16
hna.h
@@ -59,7 +59,7 @@ extern struct avl_tree tun_in_tree;
|
||||
|
||||
#define ARG_TUN_OUT_TIMEOUT "tunOutTimeout"
|
||||
#define MIN_TUN_OUT_TO 0
|
||||
#define MAX_TUN_OUT_TO 3600000
|
||||
#define MAX_TUN_OUT_TO REGISTER_TASK_TIMEOUT_MAX
|
||||
#define DEF_TUN_OUT_TO 60000
|
||||
|
||||
#define TDN_STATE_CATCHALL 1
|
||||
@@ -109,7 +109,7 @@ extern struct avl_tree tun_in_tree;
|
||||
#define MAX_TUN_OUT_IPMETRIC INT32_MAX
|
||||
#define MIN_TUN_OUT_IPMETRIC 0
|
||||
|
||||
#define ARG_TUN_OUT_HOSTNAME "gwName"
|
||||
#define ARG_TUN_OUT_GWNAME "gwName"
|
||||
#define ARG_TUN_OUT_PKID "gwId"
|
||||
|
||||
#define ARG_TUN_OUT_TRULE "tableRule"
|
||||
@@ -394,7 +394,7 @@ struct tun_search_node {
|
||||
|
||||
// struct tun_search_key tunSearchKey;
|
||||
char nameKey[NETWORK_NAME_LEN];
|
||||
uint32_t bmx6RouteBits;
|
||||
uint64_t bmx6RouteBits;
|
||||
uint16_t exportDistance;
|
||||
uint8_t exportOnly;
|
||||
struct net_key net;
|
||||
@@ -411,7 +411,7 @@ struct tun_search_node {
|
||||
uint32_t iprule;
|
||||
|
||||
GLOBAL_ID_T global_id;
|
||||
char nodeName[MAX_HOSTNAME_LEN];
|
||||
char gwName[MAX_HOSTNAME_LEN];
|
||||
struct net_key srcRtNet;
|
||||
// IFNAME_T tunName;
|
||||
|
||||
@@ -496,7 +496,11 @@ struct tun_dev_node {
|
||||
int32_t ifIdx;
|
||||
uint16_t curr_mtu; // DEF_TUN_OUT_MTU == orig_mtu
|
||||
uint16_t orig_mtu;
|
||||
struct avl_tree tun_bit_tree[2];
|
||||
|
||||
struct user_net_device_stats stats;
|
||||
IDM_T stats_captured;
|
||||
|
||||
struct avl_tree tun_bit_tree[2];
|
||||
};
|
||||
|
||||
struct tun_in_node {
|
||||
@@ -523,7 +527,7 @@ struct tun_in_node {
|
||||
struct avl_tree tun_dev_tree;
|
||||
};
|
||||
|
||||
char* bmx6RouteBits2String(uint32_t bmx6_route_bits);
|
||||
char* bmx6RouteBits2String(uint64_t bmx6_route_bits);
|
||||
|
||||
void set_tunXin6_net_adv_list(uint8_t del, struct list_head *adv_list);
|
||||
|
||||
|
428
iid.c
Normal file
428
iid.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/if.h> /* ifr_if, ifr_tun */
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "control.h"
|
||||
#include "bmx.h"
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "iid.h"
|
||||
#include "key.h"
|
||||
#include "sec.h"
|
||||
#include "metrics.h"
|
||||
#include "msg.h"
|
||||
#include "ip.h"
|
||||
#include "hna.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
#include "iptools.h"
|
||||
#include "plugin.h"
|
||||
#include "allocate.h"
|
||||
#include "z.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "iid"
|
||||
|
||||
|
||||
|
||||
/***********************************************************
|
||||
IID Infrastructure
|
||||
************************************************************/
|
||||
|
||||
int32_t ogmIid = DEF_OGM_SQN_RANGE;
|
||||
|
||||
struct iid_repos my_iid_repos = {0, 0, 0, 0,
|
||||
{NULL}};
|
||||
|
||||
int8_t iid_extend_repos(struct iid_repos *rep)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
dbgf_all(DBGT_INFO, "sizeof iid: %zu, tot_used %d arr_size %d ",
|
||||
(rep == &my_iid_repos) ? sizeof(IID_NODE_T__*) : sizeof(IID_T), rep->tot_used, rep->arr_size);
|
||||
|
||||
assertion(-500217, (rep != &my_iid_repos || IID_SPREAD_FK != 1 || rep->tot_used == rep->arr_size));
|
||||
|
||||
if (rep->arr_size + IID_REPOS_SIZE_BLOCK >= IID_REPOS_SIZE_WARN) {
|
||||
|
||||
dbgf_sys(DBGT_WARN, "%d", rep->arr_size);
|
||||
|
||||
if (rep->arr_size + IID_REPOS_SIZE_BLOCK >= IID_REPOS_SIZE_MAX)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
int field_size = (rep == &my_iid_repos) ? sizeof(IID_NODE_T__*) : sizeof(struct iid_ref);
|
||||
|
||||
if (rep->arr_size) {
|
||||
|
||||
rep->arr.u8 = debugRealloc(rep->arr.u8, (rep->arr_size + IID_REPOS_SIZE_BLOCK) * field_size, -300035);
|
||||
|
||||
} else {
|
||||
|
||||
rep->arr.u8 = debugMalloc(IID_REPOS_SIZE_BLOCK * field_size, -300085);
|
||||
rep->tot_used = IID_RSVD_MAX + 1;
|
||||
rep->min_free = IID_RSVD_MAX + 1;
|
||||
rep->max_free = IID_RSVD_MAX + 1;
|
||||
}
|
||||
|
||||
memset(&(rep->arr.u8[rep->arr_size * field_size]), 0, IID_REPOS_SIZE_BLOCK * field_size);
|
||||
|
||||
rep->arr_size += IID_REPOS_SIZE_BLOCK;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void iid_purge_repos(struct iid_repos *rep)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
if (rep->arr.u8)
|
||||
debugFree(rep->arr.u8, -300135);
|
||||
|
||||
memset(rep, 0, sizeof( struct iid_repos));
|
||||
|
||||
}
|
||||
|
||||
void iid_free(struct iid_repos *rep, IID_T iid)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
int m = (rep == &my_iid_repos);
|
||||
|
||||
assertion(-500330, (iid > IID_RSVD_MAX));
|
||||
assertion(-500228, (iid < rep->arr_size && iid < rep->max_free && rep->tot_used > IID_RSVD_MAX));
|
||||
assertion(-500229, ((m ? (rep->arr.node[iid] != NULL) : (rep->arr.ref[iid].myIID4x) != 0)));
|
||||
|
||||
if (m) {
|
||||
rep->arr.node[iid] = NULL;
|
||||
} else {
|
||||
rep->arr.ref[iid].myIID4x = 0;
|
||||
rep->arr.ref[iid].referred_by_neigh_timestamp_sec = 0;
|
||||
}
|
||||
|
||||
rep->min_free = XMIN(rep->min_free, iid);
|
||||
|
||||
if (rep->max_free == iid + 1) {
|
||||
|
||||
IID_T i;
|
||||
|
||||
for (i = iid; i > IID_MIN_USED; i--) {
|
||||
|
||||
if (m ? (rep->arr.node[i - 1] != NULL) : (rep->arr.ref[i - 1].myIID4x) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
rep->max_free = i;
|
||||
}
|
||||
|
||||
rep->tot_used--;
|
||||
|
||||
dbgf_all(DBGT_INFO, "mine %d, iid %d tot_used %d, min_free %d max_free %d",
|
||||
m, iid, rep->tot_used, rep->min_free, rep->max_free);
|
||||
|
||||
if (rep->tot_used > 0 && rep->tot_used <= IID_MIN_USED) {
|
||||
|
||||
assertion(-500362, (rep->tot_used == IID_MIN_USED && rep->max_free == IID_MIN_USED && rep->min_free == IID_MIN_USED));
|
||||
|
||||
iid_purge_repos(rep);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IID_NODE_T__* iid_get_node_by_myIID4x(IID_T myIID4x)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
if (my_iid_repos.max_free <= myIID4x)
|
||||
return NULL;
|
||||
|
||||
IID_NODE_T__ *dhn = my_iid_repos.arr.node[myIID4x];
|
||||
|
||||
assertion(-500328, (!dhn || dhn->myIID4orig == myIID4x));
|
||||
|
||||
if (dhn && !dhn->key__) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "myIID4x %d INVALIDATED %d sec ago",
|
||||
myIID4x, (bmx_time - dhn->referred_by_me_timestamp) / 1000);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return dhn;
|
||||
}
|
||||
|
||||
IID_NODE_T__* iid_get_node_by_neighIID4x(IID_NEIGH_T *nn, IID_T neighIID4x)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-502331, (ogmIid));
|
||||
|
||||
if (!nn || nn->neighIID4x_repos.max_free <= neighIID4x) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "neighIID4x=%d to large for neighIID4x_repos of neigh=%s",
|
||||
neighIID4x, nn ? cryptShaAsString(&nn->local_id) : "???");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct iid_ref *ref = &(nn->neighIID4x_repos.arr.ref[neighIID4x]);
|
||||
|
||||
|
||||
if (!ref->myIID4x) {
|
||||
|
||||
dbgf_all(DBGT_WARN, "neighIID4x=%d not recorded by neighIID4x_repos", neighIID4x);
|
||||
|
||||
} else if (((((uint16_t) bmx_time_sec) - ref->referred_by_neigh_timestamp_sec) >
|
||||
((MIN_DHASH_TO - (MIN_DHASH_TO / DHASH_TO_TOLERANCE_FK)) / 1000))) {
|
||||
|
||||
dbgf_track(DBGT_WARN, "neighIID4x=%d outdated in neighIID4x_repos, now_sec=%d, ref_sec=%d",
|
||||
neighIID4x, bmx_time_sec, ref->referred_by_neigh_timestamp_sec);
|
||||
|
||||
} else {
|
||||
|
||||
ref->referred_by_neigh_timestamp_sec = bmx_time_sec;
|
||||
|
||||
if (ref->myIID4x < my_iid_repos.max_free) {
|
||||
|
||||
IID_NODE_T__ *dhn = my_iid_repos.arr.node[ref->myIID4x];
|
||||
|
||||
if (dhn)
|
||||
return dhn;
|
||||
|
||||
dbgf_track(DBGT_WARN, "neighIID4x=%d -> myIID4x=%d empty!", neighIID4x, ref->myIID4x);
|
||||
|
||||
} else {
|
||||
|
||||
dbgf_track(DBGT_WARN, "neighIID4x=%d -> myIID4x=%d to large!", neighIID4x, ref->myIID4x);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void _iid_set(struct iid_repos *rep, IID_T IIDpos, IID_T myIID4x, IID_NODE_T__ *dhn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-500530, (rep && XOR(myIID4x, dhn))); // eihter the one ore the other !!
|
||||
assertion(-500531, (!dhn || rep == &my_iid_repos));
|
||||
assertion(-500535, (IIDpos >= IID_MIN_USED));
|
||||
|
||||
rep->tot_used++;
|
||||
rep->max_free = XMAX(rep->max_free, IIDpos + 1);
|
||||
|
||||
IID_T min = rep->min_free;
|
||||
|
||||
if (min == IIDpos) {
|
||||
for (min++; min < rep->arr_size; min++) {
|
||||
|
||||
if (myIID4x ? !(rep->arr.ref[min].myIID4x) : !(rep->arr.node[min]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertion(-500244, (min <= rep->max_free));
|
||||
|
||||
rep->min_free = min;
|
||||
|
||||
if (myIID4x) {
|
||||
rep->arr.ref[IIDpos].myIID4x = myIID4x;
|
||||
rep->arr.ref[IIDpos].referred_by_neigh_timestamp_sec = bmx_time_sec;
|
||||
} else {
|
||||
rep->arr.node[IIDpos] = dhn;
|
||||
dhn->referred_by_me_timestamp = bmx_time;
|
||||
}
|
||||
}
|
||||
|
||||
IID_T iid_new_myIID4x(IID_NODE_T__ *dhn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
IID_T mid;
|
||||
#ifndef NO_ASSERTIONS
|
||||
IDM_T warn = 0;
|
||||
#endif
|
||||
|
||||
assertion(-500216, (my_iid_repos.tot_used <= my_iid_repos.arr_size));
|
||||
|
||||
while (my_iid_repos.arr_size <= my_iid_repos.tot_used * IID_SPREAD_FK)
|
||||
iid_extend_repos(&my_iid_repos);
|
||||
|
||||
if (IID_SPREAD_FK > 1) {
|
||||
|
||||
uint32_t random = rand_num(my_iid_repos.arr_size);
|
||||
|
||||
// Never put random function intro MAX()! It would be called twice
|
||||
mid = XMAX(IID_MIN_USED, random);
|
||||
|
||||
while (my_iid_repos.arr.node[mid]) {
|
||||
|
||||
mid++;
|
||||
if (mid >= my_iid_repos.arr_size) {
|
||||
|
||||
mid = IID_MIN_USED;
|
||||
|
||||
assertion(-500533, (!(warn++)));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
mid = my_iid_repos.min_free;
|
||||
}
|
||||
|
||||
_iid_set(&my_iid_repos, mid, 0, dhn);
|
||||
|
||||
return mid;
|
||||
|
||||
}
|
||||
|
||||
IDM_T iid_set_neighIID4x(struct iid_repos *neigh_rep, IID_T neighIID4x, IID_T myIID4x)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-502332, (ogmIid));
|
||||
assertion(-500326, (neighIID4x > IID_RSVD_MAX));
|
||||
assertion(-500327, (myIID4x > IID_RSVD_MAX));
|
||||
assertion(-500384, (neigh_rep && neigh_rep != &my_iid_repos));
|
||||
assertion(-500245, (my_iid_repos.max_free > myIID4x));
|
||||
|
||||
IID_NODE_T__ *dhn = my_iid_repos.arr.node[myIID4x];
|
||||
|
||||
assertion(-500485, (dhn && dhn->descContent && dhn->descContent->orig));
|
||||
|
||||
dhn->referred_by_me_timestamp = bmx_time;
|
||||
|
||||
if (neigh_rep->max_free > neighIID4x) {
|
||||
|
||||
struct iid_ref *ref = &(neigh_rep->arr.ref[neighIID4x]);
|
||||
|
||||
if (ref->myIID4x > IID_RSVD_MAX) {
|
||||
|
||||
if (ref->myIID4x == myIID4x ||
|
||||
(((uint16_t) (((uint16_t) bmx_time_sec) - ref->referred_by_neigh_timestamp_sec)) >=
|
||||
((MIN_DHASH_TO - (MIN_DHASH_TO / DHASH_TO_TOLERANCE_FK)) / 1000))) {
|
||||
|
||||
ref->myIID4x = myIID4x;
|
||||
ref->referred_by_neigh_timestamp_sec = bmx_time_sec;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
IID_NODE_T__ *dhn_old;
|
||||
dhn_old = my_iid_repos.arr.node[ref->myIID4x]; // avoid -DNO_DEBUG_SYS warnings
|
||||
dbgf_sys(DBGT_ERR, "demanding mapping: neighIID4x=%d to myIID4x=%d "
|
||||
"(global_id=%s updated=%d last_referred_by_me=%d) "
|
||||
"already used for ref->myIID4x=%d (last_referred_by_neigh_sec=%d %s=%s last_referred_by_me=%jd)! Reused faster than allowed!!",
|
||||
neighIID4x, myIID4x, cryptShaAsString(&dhn->key__->orig__->nodeId), dhn->key__->orig__->updated_timestamp,
|
||||
dhn->referred_by_me_timestamp,
|
||||
ref->myIID4x,
|
||||
ref->referred_by_neigh_timestamp_sec,
|
||||
(!dhn_old ? "???" : (dhn_old->key__ && dhn_old->key__->orig__ ? cryptShaAsString(&dhn_old->key__->orig__->nodeId) :
|
||||
(is_zero(&dhn_old->dhash, sizeof(dhn_old->dhash)) ? "FREED" : "INVALIDATED"))),
|
||||
dhn_old ? cryptShaAsString(&dhn_old->dhash) : "???",
|
||||
dhn_old ? (int64_t) dhn_old->referred_by_me_timestamp : -1
|
||||
);
|
||||
|
||||
// EXITERROR(-500701, (0));
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
assertion(-500242, (ref->myIID4x == IID_RSVD_UNUSED));
|
||||
}
|
||||
|
||||
|
||||
while (neigh_rep->arr_size <= neighIID4x) {
|
||||
|
||||
if (
|
||||
neigh_rep->arr_size > IID_REPOS_SIZE_BLOCK &&
|
||||
neigh_rep->arr_size > my_iid_repos.arr_size &&
|
||||
neigh_rep->tot_used < neigh_rep->arr_size / (2 * IID_SPREAD_FK)) {
|
||||
|
||||
dbgf_sys(DBGT_WARN, "IID_REPOS USAGE WARNING neighIID4x %d myIID4x %d arr_size %d used %d",
|
||||
neighIID4x, myIID4x, neigh_rep->arr_size, neigh_rep->tot_used);
|
||||
}
|
||||
|
||||
iid_extend_repos(neigh_rep);
|
||||
}
|
||||
|
||||
assertion(-500243, ((neigh_rep->arr_size > neighIID4x &&
|
||||
(neigh_rep->max_free <= neighIID4x || neigh_rep->arr.ref[neighIID4x].myIID4x == IID_RSVD_UNUSED))));
|
||||
|
||||
_iid_set(neigh_rep, neighIID4x, myIID4x, NULL);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void iid_free_neighIID4x_by_myIID4x(struct iid_repos *rep, IID_T myIID4x)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-500282, (rep != &my_iid_repos));
|
||||
assertion(-500328, (myIID4x > IID_RSVD_MAX));
|
||||
|
||||
IID_T p;
|
||||
uint16_t removed = 0;
|
||||
|
||||
for (p = IID_RSVD_MAX + 1; p < rep->max_free; p++) {
|
||||
|
||||
if (rep->arr.ref[p].myIID4x == myIID4x) {
|
||||
|
||||
if (removed++) {
|
||||
// there could indeed be several (if the neigh has timeouted this node and learned it again later)
|
||||
dbgf(DBGL_TEST, DBGT_INFO, "removed %d. stale rep->arr.sid[%d] = %d", removed, p, myIID4x);
|
||||
}
|
||||
|
||||
iid_free(rep, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iid_purge_dhash(IID_T myIID4orig)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
struct avl_node *an;
|
||||
struct neigh_node *local;
|
||||
|
||||
iid_free(&my_iid_repos, myIID4orig);
|
||||
|
||||
//reset all neigh_node->oid_repos[x]=dhn->mid4o entries
|
||||
for (an = NULL; (local = avl_iterate_item(&local_tree, &an));)
|
||||
iid_free_neighIID4x_by_myIID4x(&local->neighIID4x_repos, myIID4orig);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void iid_init(void)
|
||||
{
|
||||
assertion(-502333, (OGMS_IID_PER_AGGREG_PREF <= OGMS_IID_PER_AGGREG_MAX));
|
||||
}
|
117
iid.h
Normal file
117
iid.h
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
|
||||
|
||||
typedef struct neigh_node IID_NEIGH_T;
|
||||
typedef struct desc_content IID_NODE_T__;
|
||||
|
||||
|
||||
|
||||
#define IID_REPOS_SIZE_BLOCK 32
|
||||
|
||||
#define IID_REPOS_SIZE_MAX ((IID_T)(-1))
|
||||
#define IID_REPOS_SIZE_WARN 1024
|
||||
|
||||
#define IID_RSVD_UNUSED 0
|
||||
#define IID_RSVD_MAX 0
|
||||
#define IID_MIN_USED 1
|
||||
|
||||
#define IID_SPREAD_FK 1 /*default=2 , 1 means no spreading #define IID_REPOS_USAGE_WARNING 10 */
|
||||
|
||||
|
||||
#define OGMS_IID_PER_AGGREG_MAX (SIGNED_FRAMES_SIZE_MAX - (\
|
||||
sizeof(struct tlv_hdr) + \
|
||||
sizeof (struct hdr_ogm_adv) + \
|
||||
(OGM_JUMPS_PER_AGGREGATION * sizeof(struct msg_ogm_iid_adv)))) \
|
||||
/ sizeof(struct msg_ogm_iid_adv)
|
||||
|
||||
#define OGMS_IID_PER_AGGREG_PREF (SIGNED_FRAMES_SIZE_PREF - (\
|
||||
sizeof(struct tlv_hdr) + \
|
||||
sizeof (struct hdr_ogm_adv) + \
|
||||
(OGM_JUMPS_PER_AGGREGATION * sizeof(struct msg_ogm_iid_adv)))) \
|
||||
/ sizeof(struct msg_ogm_iid_adv)
|
||||
|
||||
#define MIN_OGM_IID 0
|
||||
#define MAX_OGM_IID 1
|
||||
#define DEF_OGM_IID 0
|
||||
#define ARG_OGM_IID "iidOgms"
|
||||
extern int32_t ogmIid;
|
||||
struct msg_ogm_iid_adv // 4 bytes
|
||||
{
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int sqn : 16;
|
||||
unsigned int mtcMantissa : 5;
|
||||
unsigned int mtcExponent : 5;
|
||||
unsigned int iidOffset : 6;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int iidOffset : 6;
|
||||
unsigned int mtcExponent : 5;
|
||||
unsigned int mtcMantissa : 5;
|
||||
unsigned int sqn : 16;
|
||||
#else
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
} o;
|
||||
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int iid : 16;
|
||||
unsigned int mtcU10 : 10;
|
||||
unsigned int iidOffset : 6;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int iidOffset : 6;
|
||||
unsigned int mtcU10 : 10;
|
||||
unsigned int iid : 16;
|
||||
#else
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
} j;
|
||||
uint32_t u32;
|
||||
} u;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ogm_aggreg_node {
|
||||
IID_T *iidsArr;
|
||||
uint16_t iidsNum;
|
||||
uint16_t iidJumps;
|
||||
|
||||
AGGREG_SQN_T sqn;
|
||||
uint8_t tx_round;
|
||||
};
|
||||
|
||||
struct iid_ref {
|
||||
IID_T myIID4x;
|
||||
uint16_t referred_by_neigh_timestamp_sec;
|
||||
};
|
||||
|
||||
struct iid_repos {
|
||||
IID_T arr_size; // the number of allocated array fields
|
||||
IID_T min_free; // the first unused array field from the beginning of the array (might be outside of allocated space)
|
||||
IID_T max_free; // the first unused array field after the last used field in the array (might be outside of allocated space)
|
||||
IID_T tot_used; // the total number of used fields in the array
|
||||
|
||||
union {
|
||||
uint8_t *u8;
|
||||
IID_NODE_T__ **node;
|
||||
struct iid_ref *ref;
|
||||
} arr;
|
||||
};
|
||||
|
||||
|
||||
extern struct iid_repos my_iid_repos;
|
||||
|
||||
|
||||
int8_t iid_extend_repos(struct iid_repos *rep);
|
||||
void iid_purge_repos(struct iid_repos *rep);
|
||||
void iid_free(struct iid_repos *rep, IID_T iid);
|
||||
void iid_free_neighIID4x_by_myIID4x(struct iid_repos *rep, IID_T myIID4x);
|
||||
IDM_T iid_set_neighIID4x(struct iid_repos *neigh_rep, IID_T neighIID4x, IID_T myIID4x);
|
||||
IID_T iid_new_myIID4x(IID_NODE_T__ *dhn);
|
||||
|
||||
IID_NODE_T__* iid_get_node_by_neighIID4x(IID_NEIGH_T *nn, IID_T neighIID4x);
|
||||
IID_NODE_T__* iid_get_node_by_myIID4x(IID_T myIID4x);
|
||||
|
||||
void iid_purge_dhash(IID_T myIID4orig);
|
129
ip.h
129
ip.h
@@ -42,9 +42,9 @@
|
||||
|
||||
|
||||
|
||||
#define RTNL_RCV_MAX 66560 // 266240 // 133120 // less causes lost messages !!??
|
||||
|
||||
|
||||
|
||||
extern uint32_t udpRxBytesMean, udpRxPacketsMean, udpTxBytesMean, udpTxPacketsMean;
|
||||
|
||||
|
||||
struct ifname {
|
||||
@@ -53,11 +53,16 @@ struct ifname {
|
||||
|
||||
typedef struct ifname IFNAME_T;
|
||||
|
||||
#define ARG_DEVSTAT_PERIOD "devStatPeriod"
|
||||
#define MIN_DEVSTAT_PERIOD 100
|
||||
#define MAX_DEVSTAT_PERIOD 100000
|
||||
#define DEF_DEVSTAT_PERIOD 5000
|
||||
#define HLP_DEVSTAT_PERIOD "interface traffic-statistics period"
|
||||
#define ARG_DEVSTAT_REGRESSION "devStatRegression"
|
||||
#define MIN_DEVSTAT_REGRESSION 1
|
||||
#define MAX_DEVSTAT_REGRESSION 100
|
||||
#define DEF_DEVSTAT_REGRESSION 10
|
||||
#define HLP_DEVSTAT_REGRESSION "arithmetic-mean regression for interface traffic-statistics"
|
||||
|
||||
extern int32_t devStatRegression;
|
||||
|
||||
#define DEF_DEVSTAT_PERIOD 1000
|
||||
#define DEVSTAT_PRECISION 10000
|
||||
|
||||
#define ARG_LLOCAL_PREFIX "llocalPrefix"
|
||||
#define HLP_LLOCAL_PREFIX "specify link-local prefix for interfaces"
|
||||
@@ -163,11 +168,11 @@ typedef struct ifname IFNAME_T;
|
||||
#define MAX_IP_RULE_TUN U16_MAX //64000
|
||||
#define DEF_IP_RULE_TUN 32766
|
||||
|
||||
#define RT_TABLE_MAX -1
|
||||
//#define RT_TABLE_HOSTS -1
|
||||
#define RT_TABLE_HNA -1
|
||||
#define RT_TABLE_TUN -2
|
||||
#define RT_TABLE_MIN -2
|
||||
#define BMX_TABLE_MAX -1
|
||||
//#define BMX_TABLE_HOSTS -1
|
||||
#define BMX_TABLE_HNA -1
|
||||
#define BMX_TABLE_TUN -2
|
||||
#define BMX_TABLE_MIN -2
|
||||
|
||||
//#define ARG_IP_TABLE_HOST "tableHosts"
|
||||
//#define DEF_IP_TABLE_HOST 60 //avoid conflicts with bmxd and others
|
||||
@@ -199,9 +204,11 @@ typedef struct ifname IFNAME_T;
|
||||
#define MAX_BASE_PORT 60000
|
||||
|
||||
|
||||
|
||||
#define ARG_PEDANTIC_CLEANUP "pedanticCleanup"
|
||||
#define DEF_PEDANTIC_CLEANUP NO
|
||||
#define SYSCTL_IP6_FORWARD 1
|
||||
#define SYSCTL_IP4_RP_FILTER 2
|
||||
#define SYSCTL_IP4_FORWARD 1
|
||||
#define SYSCTL_IP4_SEND_REDIRECT 0
|
||||
#define SYSCTL_IP4_ACCEPT_LOCAL 1
|
||||
|
||||
#define DEF_TUN_OUT_PERSIST 1
|
||||
|
||||
@@ -228,6 +235,7 @@ typedef struct ifname IFNAME_T;
|
||||
|
||||
|
||||
extern struct net_key autoconf_prefix_cfg;
|
||||
extern IPX_T my_primary_ip;
|
||||
|
||||
#define AF_CFG AF_INET6
|
||||
#define ZERO_NETCFG_KEY ZERO_NET6_KEY
|
||||
@@ -269,6 +277,39 @@ extern struct avl_tree dev_name_tree;
|
||||
|
||||
//extern IDM_T dev_soft_conf_changed; // temporary enabled to trigger changed interface configuration
|
||||
|
||||
#define IFCONFIG_PATH_PROCNET_DEV "/proc/net/dev"
|
||||
|
||||
struct user_net_device_stats {
|
||||
unsigned long long rx_packets; /* total packets received */
|
||||
unsigned long long tx_packets; /* total packets transmitted */
|
||||
// unsigned long long rx_bytes; /* total bytes received */
|
||||
// unsigned long long tx_bytes; /* total bytes transmitted */
|
||||
// unsigned long rx_errors; /* bad packets received */
|
||||
// unsigned long tx_errors; /* packet transmit problems */
|
||||
// unsigned long rx_dropped; /* no space in linux buffers */
|
||||
// unsigned long tx_dropped; /* no space available in linux */
|
||||
// unsigned long rx_multicast; /* multicast packets received */
|
||||
// unsigned long rx_compressed;
|
||||
// unsigned long tx_compressed;
|
||||
// unsigned long collisions;
|
||||
|
||||
/* detailed rx_errors: */
|
||||
// unsigned long rx_length_errors;
|
||||
// unsigned long rx_over_errors; /* receiver ring buff overflow */
|
||||
// unsigned long rx_crc_errors; /* recved pkt with crc error */
|
||||
// unsigned long rx_frame_errors; /* recv'd frame alignment error */
|
||||
// unsigned long rx_fifo_errors; /* recv'r fifo overrun */
|
||||
// unsigned long rx_missed_errors; /* receiver missed packet */
|
||||
/* detailed tx_errors */
|
||||
// unsigned long tx_aborted_errors;
|
||||
// unsigned long tx_carrier_errors;
|
||||
// unsigned long tx_fifo_errors;
|
||||
// unsigned long tx_heartbeat_errors;
|
||||
// unsigned long tx_window_errors;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct nlh_req {
|
||||
struct nlmsghdr nlh;
|
||||
};
|
||||
@@ -373,19 +414,13 @@ struct if_addr_node {
|
||||
|
||||
|
||||
|
||||
struct tx_link_node {
|
||||
struct list_head tx_tasks_list[FRAME_TYPE_ARRSZ]; // scheduled frames and messages
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct dev_node {
|
||||
|
||||
struct if_link_node *if_link;
|
||||
struct if_addr_node *if_llocal_addr; // non-zero but might be global for ipv4 or loopback interfaces
|
||||
struct if_addr_node *if_global_addr; // might be zero for non-primary interfaces
|
||||
void (* tx_task) (void *);
|
||||
|
||||
int32_t tx_task_items;
|
||||
|
||||
int8_t hard_conf_changed;
|
||||
int8_t soft_conf_changed;
|
||||
struct net_key autoIP6Configured;
|
||||
@@ -393,36 +428,28 @@ struct dev_node {
|
||||
uint8_t active;
|
||||
uint8_t activate_again;
|
||||
uint8_t activate_cancelled;
|
||||
uint8_t tmp_flag_for_to_be_send_adv;
|
||||
|
||||
uint32_t udpOutCurrPackets;
|
||||
uint32_t udpOutPrevPackets;
|
||||
uint32_t udpInCurrPackets;
|
||||
uint32_t udpInPrevPackets;
|
||||
uint32_t udpOutCurrBytes;
|
||||
uint32_t udpOutPrevBytes;
|
||||
uint32_t udpInCurrBytes;
|
||||
uint32_t udpInPrevBytes;
|
||||
|
||||
// DEVADV_IDX_T dev_adv_idx; //TODO: Remove (use llip_key.idx instead)
|
||||
int16_t dev_adv_msg;
|
||||
uint32_t udpTxPacketsCurr;
|
||||
uint32_t udpTxPacketsMean;
|
||||
uint32_t udpRxPacketsCurr;
|
||||
uint32_t udpRxPacketsMean;
|
||||
uint32_t udpTxBytesCurr;
|
||||
uint32_t udpTxBytesMean;
|
||||
uint32_t udpRxBytesCurr;
|
||||
uint32_t udpRxBytesMean;
|
||||
|
||||
|
||||
IFNAME_T name_phy_cfg; //key for dev_name_tree
|
||||
IFNAME_T label_cfg;
|
||||
|
||||
LinkNode dummyLink;
|
||||
|
||||
struct dev_ip_key llip_key;
|
||||
// IPX_T llocal_ip_key; //TODO: Remove (use llip_key.ip instead)
|
||||
DevKey llipKey;
|
||||
MAC_T mac;
|
||||
|
||||
|
||||
char ip_llocal_str[IPX_STR_LEN];
|
||||
char ip_global_str[IPX_STR_LEN];
|
||||
char ip_brc_str[IPX_STR_LEN];
|
||||
|
||||
int32_t ip4_rp_filter_orig;
|
||||
int32_t ip4_send_redirects_orig;
|
||||
|
||||
struct sockaddr_storage llocal_unicast_addr;
|
||||
struct sockaddr_storage tx_netwbrc_addr;
|
||||
@@ -433,9 +460,6 @@ struct dev_node {
|
||||
|
||||
HELLO_SQN_T link_hello_sqn;
|
||||
|
||||
struct list_head tx_task_lists[FRAME_TYPE_ARRSZ]; // scheduled frames and messages
|
||||
struct avl_tree tx_task_interval_tree;
|
||||
|
||||
int8_t linklayer_conf;
|
||||
int8_t linklayer;
|
||||
|
||||
@@ -492,7 +516,9 @@ struct dev_node {
|
||||
#define BMX6_ROUTE_OLSR 28
|
||||
#define BMX6_ROUTE_BMX6 29
|
||||
#define BMX6_ROUTE_BATMAN 30
|
||||
#define BMX6_ROUTE_MAX 31
|
||||
#define BMX6_ROUTE_MAX_KNOWN 30
|
||||
#define BMX6_ROUTE_MAX_SUPP 63
|
||||
|
||||
|
||||
#define ARG_ROUTE_UNSPEC "unspecified"
|
||||
#define ARG_ROUTE_REDIRECT "redirect"
|
||||
@@ -535,14 +561,14 @@ struct sys_route_dict {
|
||||
};
|
||||
|
||||
#define set_rt_dict( S, T, C, N, B ) do { \
|
||||
S[ T ].sys2Name = N; \
|
||||
S[ T ].sys2Char = C; \
|
||||
S[ T ].sys2Name = N; \
|
||||
S[ T ].sys2bmx = B; \
|
||||
S[ B ].bmx2sys = T; \
|
||||
} while (0)
|
||||
|
||||
|
||||
extern struct sys_route_dict bmx6_rt_dict[BMX6_ROUTE_MAX];
|
||||
extern struct sys_route_dict bmx6_rt_dict[];
|
||||
|
||||
|
||||
//iproute() commands:
|
||||
@@ -572,7 +598,7 @@ extern struct sys_route_dict bmx6_rt_dict[BMX6_ROUTE_MAX];
|
||||
#define IP_ROUTE_HOST 36
|
||||
#define IP_ROUTE_HNA 37
|
||||
#define IP_ROUTE_TUNS 38
|
||||
#define IP_ROUTE_MAX (IP_ROUTE_TUNS + BMX6_ROUTE_MAX)
|
||||
#define IP_ROUTE_MAX (IP_ROUTE_TUNS + BMX6_ROUTE_MAX_SUPP)
|
||||
|
||||
|
||||
|
||||
@@ -620,7 +646,7 @@ struct rtnl_get_node {
|
||||
|
||||
// core:
|
||||
|
||||
IDM_T rtnl_rcv( int fd, uint32_t pid, uint32_t seq, uint8_t cmd, uint8_t quiet, void (*func) (struct nlmsghdr *nh, void *data) ,void *data);
|
||||
int rtnl_rcv(int fd, uint32_t pid, uint32_t seq, uint8_t cmd, uint8_t quiet, void (*func) (struct nlmsghdr *nh, void *data), void *data);
|
||||
|
||||
uint32_t get_if_index(IFNAME_T *name);
|
||||
IDM_T kernel_set_flags(char *name, int fd, int get_req, int set_req, uint16_t up_flags, uint16_t down_flags);
|
||||
@@ -640,6 +666,9 @@ int32_t kernel_get_ifidx( char *name );
|
||||
IDM_T kernel_set_mtu(char *name, uint16_t mtu);
|
||||
IDM_T kernel_get_route(uint8_t quiet, uint8_t family, uint32_t table, void (*func) (struct nlmsghdr *nh, void *data) );
|
||||
|
||||
// from net-tools: ifconfig.c and lib/interface.c
|
||||
IDM_T kernel_get_ifstats(struct user_net_device_stats *stats, char *target);
|
||||
|
||||
struct sockaddr_storage set_sockaddr_storage(uint8_t af, IPX_T *ipx, int32_t port);
|
||||
void set_ipexport( void (*func) (int8_t del, const struct net_key *dst, uint32_t oif_idx, IPX_T *via, uint32_t metric, uint8_t distance) );
|
||||
|
||||
@@ -649,7 +678,7 @@ IDM_T iproute(uint8_t cmd, int8_t del, uint8_t quiet, const struct net_key *dst,
|
||||
void ip_flush_routes(uint8_t family, int32_t table_macro);
|
||||
void ip_flush_rules(uint8_t family, int32_t table_macro);
|
||||
|
||||
IDM_T check_proc_sys_net(char *file, int32_t desired, int32_t *backup);
|
||||
IDM_T check_proc_sys_net(char *file, int32_t desired);
|
||||
|
||||
void sysctl_config(struct dev_node *dev_node);
|
||||
|
||||
|
71
key.h
Normal file
71
key.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define DEF_LINK_PURGE_TO 20000
|
||||
#define MIN_LINK_PURGE_TO (MAX_TX_MIN_INTERVAL*2)
|
||||
#define MAX_LINK_PURGE_TO 864000000 /*10 days*/
|
||||
#define ARG_LINK_PURGE_TO "linkPurgeTimeout"
|
||||
|
||||
#define MIN_OGM_PURGE_TO (MAX_OGM_INTERVAL + MAX_TX_MIN_INTERVAL)
|
||||
#define MAX_OGM_PURGE_TO 864000000 /*10 days*/
|
||||
#define DEF_OGM_PURGE_TO 100000
|
||||
#define ARG_OGM_PURGE_TO "purgeTimeout"
|
||||
|
||||
extern int32_t link_purge_to;
|
||||
extern int32_t tracked_timeout;
|
||||
extern int32_t neigh_qualifying_to;
|
||||
|
||||
|
||||
// Key Weight:
|
||||
enum KColumns {
|
||||
KCListed,
|
||||
KCTracked,
|
||||
KCCertified,
|
||||
KCPromoted,
|
||||
KCNeighbor,
|
||||
KCSize,
|
||||
};
|
||||
|
||||
// Key Credits:
|
||||
enum KRows {
|
||||
KRQualifying,
|
||||
KRFriend,
|
||||
KRRecommended,
|
||||
KRAlien,
|
||||
KRSize,
|
||||
};
|
||||
|
||||
extern struct KeyState keyMatrix[KCSize][KRSize];
|
||||
extern uint32_t key_tree_deletions_chk, key_tree_deletions_cntr;
|
||||
|
||||
void keyNode_schedLowerWeight(struct key_node *kn, int8_t weight);
|
||||
|
||||
struct key_node *keyNode_updCredits(GLOBAL_ID_T *kHash, struct key_node *kn, struct key_credits *kc);
|
||||
|
||||
void keyNode_delCredits(GLOBAL_ID_T *kHash, struct key_node *kn, struct key_credits *kc);
|
||||
#define KEYNODES_BLOCKING_ID 10
|
||||
|
||||
#define keyNodes_block_and_sync( a, b ) keyNodes_block_and_sync_( __FUNCTION__, (a), (b) )
|
||||
uint32_t keyNodes_block_and_sync_(const char *f, uint32_t id, IDM_T force);
|
||||
void keyNode_fixTimeouts();
|
||||
struct key_node *keyNode_get(GLOBAL_ID_T *kHask);
|
||||
void keyNodes_cleanup(int8_t keyStateColumn, struct key_node *except);
|
||||
void init_key(void);
|
@@ -1,6 +1,6 @@
|
||||
|
||||
CFLAGS += $(CORE_CFLAGS) -fpic -I../../
|
||||
LDFLAGS += -shared
|
||||
LDFLAGS +=
|
||||
#-Wl,-soname,bmxd_config
|
||||
|
||||
PLUGIN_NAME = bmx6_json
|
||||
@@ -19,7 +19,7 @@ all: $(PLUGIN_FULLNAME) Makefile
|
||||
|
||||
|
||||
$(PLUGIN_FULLNAME): $(OBJS) Makefile
|
||||
$(CC) $(LDFLAGS) -ljson-c $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) || $(CC) $(LDFLAGS) -ljson $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME)
|
||||
$(CC) -shared $(OBJS) $(LDFLAGS) -ljson-c $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME) || $(CC) -shared $(OBJS) $(LDFLAGS) -ljson $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME)
|
||||
ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME)
|
||||
|
||||
%.o: %.c %.h Makefile
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "link.h"
|
||||
#include "msg.h"
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
@@ -416,7 +417,7 @@ void json_originator_event_hook(int32_t cb_id, struct orig_node *orig)
|
||||
|
||||
if ((on = orig)) {
|
||||
|
||||
sprintf(path_name, "%s/%s", json_orig_dir, cryptShaAsString(&on->nodeId));
|
||||
sprintf(path_name, "%s/%s", json_orig_dir, cryptShaAsString(&on->k.nodeId));
|
||||
|
||||
if ((fd = open(path_name, O_RDONLY)) > 0 && close(fd) == 0) {
|
||||
|
||||
@@ -434,7 +435,7 @@ void json_originator_event_hook(int32_t cb_id, struct orig_node *orig)
|
||||
struct avl_node *it = NULL;
|
||||
while ((on = orig ? orig : avl_iterate_item(&orig_tree, &it))) {
|
||||
|
||||
sprintf(path_name, "%s/%s", json_orig_dir, cryptShaAsString(&on->nodeId));
|
||||
sprintf(path_name, "%s/%s", json_orig_dir, cryptShaAsString(&on->k.nodeId));
|
||||
|
||||
if ((fd = open(path_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
|
||||
|
||||
@@ -450,7 +451,7 @@ void json_originator_event_hook(int32_t cb_id, struct orig_node *orig)
|
||||
char status_name[sizeof (((struct status_handl *) NULL)->status_name)] = ARG_ORIGINATORS;
|
||||
|
||||
if ((handl = avl_find_item(&status_tree, status_name)) &&
|
||||
(data_len = ((*(handl->frame_creator))(handl, on)))) {
|
||||
(data_len = ((*(handl->frame_creator))(handl, on->key)))) {
|
||||
|
||||
json_object *jdesc_fields = NULL;
|
||||
|
||||
@@ -486,7 +487,6 @@ void json_description_event_hook(int32_t cb_id, struct orig_node *on)
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
assertion(-501306, (on));
|
||||
assertion(-501270, IMPLIES(cb_id == PLUGIN_CB_DESCRIPTION_CREATED, (on && on->dhn && on->dhn->desc_frame)));
|
||||
assertion(-501273, (cb_id == PLUGIN_CB_DESCRIPTION_DESTROY || cb_id == PLUGIN_CB_DESCRIPTION_CREATED));
|
||||
assertion(-501274, IMPLIES(initializing, cb_id == PLUGIN_CB_DESCRIPTION_CREATED));
|
||||
assertion(-501275, (json_desc_dir));
|
||||
@@ -495,7 +495,7 @@ void json_description_event_hook(int32_t cb_id, struct orig_node *on)
|
||||
|
||||
int fd;
|
||||
char path_name[MAX_PATH_SIZE];
|
||||
sprintf(path_name, "%s/%s", json_desc_dir, cryptShaAsString(&on->nodeId));
|
||||
sprintf(path_name, "%s/%s", json_desc_dir, cryptShaAsString(&on->k.nodeId));
|
||||
|
||||
if (cb_id == PLUGIN_CB_DESCRIPTION_DESTROY) {
|
||||
|
||||
@@ -517,17 +517,18 @@ void json_description_event_hook(int32_t cb_id, struct orig_node *on)
|
||||
}
|
||||
|
||||
json_object *jorig = json_object_new_object();
|
||||
json_object_object_add(jorig, "descSha", json_object_new_string(cryptShaAsString(&on->dhn->dhash)));
|
||||
json_object_object_add(jorig, "descSha", json_object_new_string(cryptShaAsString(&on->descContent->dhn->dhash)));
|
||||
|
||||
/*
|
||||
json_object *jblocked = json_object_new_int(on->blocked);
|
||||
json_object_object_add(jorig, "blocked", jblocked);
|
||||
|
||||
if (on->dhn && on->dhn->dext && on->dhn->dext->dlen) {
|
||||
if (on->dhn && on->dhn->contents && on->dhn->contents->__dlen) {
|
||||
|
||||
struct rx_frame_iterator it = {
|
||||
.caller = __FUNCTION__, .onOld = on, .dhnNew = on->dhn, .op = TLV_OP_PLUGIN_MIN,
|
||||
.db = description_tlv_db, .process_filter = FRAME_TYPE_PROCESS_ALL,
|
||||
.frame_type = -1, .frames_in = on->dhn->dext->data, .frames_length = on->dhn->dext->dlen,
|
||||
.f_type = -1, .frames_in = on->dhn->contents->__data, .frames_length = on->dhn->contents->__dlen,
|
||||
};
|
||||
|
||||
json_object *jextensions = NULL;
|
||||
@@ -537,11 +538,11 @@ void json_description_event_hook(int32_t cb_id, struct orig_node *on)
|
||||
json_object * jext_fields;
|
||||
|
||||
if ((jext_fields = fields_dbg_json(
|
||||
FIELD_RELEVANCE_MEDI, YES, it.frame_msgs_length, it.msg,
|
||||
it.handl->min_msg_size, it.handl->msg_format))) {
|
||||
FIELD_RELEVANCE_MEDI, YES, it.f_mlen, it.f_msg,
|
||||
it.f_handl->min_msg_size, it.f_handl->msg_format))) {
|
||||
|
||||
json_object *jext = json_object_new_object();
|
||||
json_object_object_add(jext, it.handl->name, jext_fields);
|
||||
json_object_object_add(jext, it.f_handl->name, jext_fields);
|
||||
|
||||
jextensions = jextensions ? jextensions : json_object_new_array();
|
||||
|
||||
@@ -553,7 +554,7 @@ void json_description_event_hook(int32_t cb_id, struct orig_node *on)
|
||||
json_object_object_add(jorig, "extensions", jextensions);
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
dprintf(fd, "%s\n", json_object_to_json_string(jorig));
|
||||
|
||||
dbgf_all(DBGT_INFO, "creating json-description=%s", path_name);
|
||||
|
@@ -5,8 +5,8 @@ LDFLAGS += -shared
|
||||
|
||||
PLUGIN_NAME = bmx6_quagga
|
||||
|
||||
SRC_C = quagga.c
|
||||
SRC_H = quagga.h
|
||||
SRC_C = quagga.c ../../redist.c
|
||||
SRC_H = quagga.h ../../redist.h
|
||||
OBJS= $(SRC_C:.c=.o)
|
||||
|
||||
PLUGIN_FULLNAME = $(PLUGIN_NAME).so
|
||||
|
@@ -48,9 +48,10 @@
|
||||
#include "iptools.h"
|
||||
#include "ip.h"
|
||||
#include "hna.h"
|
||||
#include "redist.h"
|
||||
#include "allocate.h"
|
||||
#include "quagga.h"
|
||||
#include "redist.c"
|
||||
|
||||
|
||||
|
||||
#define CODE_CATEGORY_NAME "quagga"
|
||||
@@ -94,11 +95,11 @@ static AVL_TREE(redist_out_tree, struct redist_out_node, k);
|
||||
|
||||
//static AVL_TREE(export_opt_tree, struct export_opt_node, nameKey);
|
||||
|
||||
static LIST_SIMPEL(tunXin6_net_adv_list, struct tunXin6_net_adv_node, list, list);
|
||||
static LIST_SIMPEL(quagga_net_adv_list, struct tunXin6_net_adv_node, list, list);
|
||||
|
||||
static struct zebra_cfg zcfg;
|
||||
|
||||
static struct sys_route_dict zapi_rt_dict[BMX6_ROUTE_MAX];
|
||||
static struct sys_route_dict zapi_rt_dict[BMX6_ROUTE_MAX_SUPP+1];
|
||||
|
||||
|
||||
STATIC_FUNC void zsock_write(void* zpacket);
|
||||
@@ -205,12 +206,12 @@ void zdata_parse_route(struct zdata *zd)
|
||||
|
||||
if (tmp) {
|
||||
tmp->cnt += (zd->cmd == ZEBRA_IPV4_ROUTE_ADD || zd->cmd == ZEBRA_IPV6_ROUTE_ADD) ? (+1) : (-1);
|
||||
redist_dbg(DBGL_SYS, DBGT_INFO, __FUNCTION__, tmp, zapi_rt_dict, zebraCmd2Str[zd->cmd], "OLD");
|
||||
redist_dbg(DBGL_CHANGES, DBGT_INFO, __FUNCTION__, tmp, zapi_rt_dict, zebraCmd2Str[zd->cmd], "OLD");
|
||||
} else {
|
||||
tmp = debugMallocReset(sizeof (zrn), -300472);
|
||||
*tmp = zrn;
|
||||
tmp->cnt += 1;
|
||||
redist_dbg(DBGL_SYS, DBGT_INFO, __FUNCTION__, tmp, zapi_rt_dict, zebraCmd2Str[zd->cmd], "NEW");
|
||||
redist_dbg(DBGL_CHANGES, DBGT_INFO, __FUNCTION__, tmp, zapi_rt_dict, zebraCmd2Str[zd->cmd], "NEW");
|
||||
assertion(-501406, (zd->cmd == ZEBRA_IPV4_ROUTE_ADD || zd->cmd == ZEBRA_IPV6_ROUTE_ADD));
|
||||
avl_insert(&zroute_tree, tmp, -300473);
|
||||
}
|
||||
@@ -276,7 +277,7 @@ void zdata_parse(void)
|
||||
|
||||
if (changed_routes) {
|
||||
if ( redistribute_routes(&redist_out_tree, &zroute_tree, &redist_opt_tree, zapi_rt_dict) )
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &tunXin6_net_adv_list);
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &quagga_net_adv_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,7 +436,7 @@ void zsock_send_redist_request(void)
|
||||
assertion(-501413, (zcfg.socket > 0));
|
||||
|
||||
int route_type;
|
||||
for (route_type = 0; route_type < BMX6_ROUTE_MAX; route_type++) {
|
||||
for (route_type = 0; route_type <= BMX6_ROUTE_MAX_KNOWN; route_type++) {
|
||||
|
||||
uint8_t new = bit_get((uint8_t*) & zcfg.bmx6_redist_bits_new, (sizeof (zcfg.bmx6_redist_bits_new) * 8), route_type);
|
||||
uint8_t old = bit_get((uint8_t*) & zcfg.bmx6_redist_bits_old, (sizeof (zcfg.bmx6_redist_bits_old) * 8), route_type);
|
||||
@@ -562,8 +563,8 @@ void zsock_disconnect(void)
|
||||
my_description_changed = YES;
|
||||
}
|
||||
|
||||
while (tunXin6_net_adv_list.items) {
|
||||
struct tunXin6_net_adv_node *tn = list_del_head(&tunXin6_net_adv_list);
|
||||
while (quagga_net_adv_list.items) {
|
||||
struct tunXin6_net_adv_node *tn = list_del_head(&quagga_net_adv_list);
|
||||
debugFree(tn, -300515);
|
||||
}
|
||||
|
||||
@@ -815,7 +816,7 @@ int32_t opt_redistribute(uint8_t cmd, uint8_t _save, struct opt_type *opt, struc
|
||||
|
||||
zsock_send_redist_request();
|
||||
if ( redistribute_routes(&redist_out_tree, &zroute_tree, &redist_opt_tree, zapi_rt_dict) )
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &tunXin6_net_adv_list);
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &quagga_net_adv_list);
|
||||
}
|
||||
|
||||
changed = NO;
|
||||
@@ -879,7 +880,7 @@ static void quagga_cleanup( void )
|
||||
if (zcfg.socket)
|
||||
zsock_disconnect();
|
||||
|
||||
set_tunXin6_net_adv_list(DEL, &tunXin6_net_adv_list);
|
||||
set_tunXin6_net_adv_list(DEL, &quagga_net_adv_list);
|
||||
|
||||
}
|
||||
|
||||
@@ -888,7 +889,7 @@ static void quagga_cleanup( void )
|
||||
static int32_t quagga_init( void )
|
||||
{
|
||||
|
||||
assertion(-501424, (ZEBRA_ROUTE_MAX <= BMX6_ROUTE_MAX));
|
||||
assertion(-501424, (ZEBRA_ROUTE_MAX <= BMX6_ROUTE_MAX_KNOWN));
|
||||
memset(&zapi_rt_dict, 0, sizeof(zapi_rt_dict));
|
||||
|
||||
set_rt_dict(zapi_rt_dict, ZEBRA_ROUTE_SYSTEM, 'X', ARG_ROUTE_SYSTEM, BMX6_ROUTE_SYSTEM);
|
||||
@@ -913,7 +914,7 @@ static int32_t quagga_init( void )
|
||||
|
||||
register_options_array(quagga_options, sizeof ( quagga_options), CODE_CATEGORY_NAME);
|
||||
|
||||
set_tunXin6_net_adv_list(ADD, &tunXin6_net_adv_list);
|
||||
set_tunXin6_net_adv_list(ADD, &quagga_net_adv_list);
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
|
@@ -191,8 +191,8 @@ struct zebra_cfg {
|
||||
char *zread_buff;
|
||||
uint16_t zread_buff_len;
|
||||
uint16_t zread_len;
|
||||
uint32_t bmx6_redist_bits_new;
|
||||
uint32_t bmx6_redist_bits_old;
|
||||
uint64_t bmx6_redist_bits_new;
|
||||
uint64_t bmx6_redist_bits_old;
|
||||
|
||||
//...
|
||||
};
|
||||
|
@@ -37,6 +37,8 @@
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "msg.h"
|
||||
#include "content.h"
|
||||
#include "desc.h"
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
@@ -71,7 +73,7 @@ void check_for_changed_sms(void *unused)
|
||||
struct sms_node * sms = NULL;
|
||||
struct avl_node *an = NULL;
|
||||
|
||||
int32_t max_sms_data_len = (use_referencing(&description_tlv_db->handls[BMX_DSC_TLV_SMS])) ? MAX_SMS_DATA_LEN_REF : MAX_SMS_DATA_LEN;
|
||||
int32_t max_sms_data_len = (use_refLevel(&description_tlv_db->handls[BMX_DSC_TLV_SMS])) ? MAX_SMS_DATA_LEN_REF : MAX_SMS_DATA_LEN;
|
||||
|
||||
char name[MAX_SMS_NAME_LEN];
|
||||
char data[max_sms_data_len + 1];
|
||||
@@ -214,7 +216,7 @@ int create_description_sms(struct tx_frame_iterator *it)
|
||||
struct sms_node *sms;
|
||||
|
||||
uint8_t *data = tx_iterator_cache_msg_ptr(it);
|
||||
int32_t max_size = tx_iterator_cache_data_space_pref(it);
|
||||
int32_t max_size = tx_iterator_cache_data_space_pref(it, 0, 100);
|
||||
int pos = 0;
|
||||
|
||||
while ((sms = avl_iterate_item(&sms_tree, &an))) {
|
||||
@@ -245,34 +247,31 @@ int create_description_sms(struct tx_frame_iterator *it)
|
||||
STATIC_FUNC
|
||||
int process_description_sms(struct rx_frame_iterator *it)
|
||||
{
|
||||
struct orig_node *on = it->onOld;
|
||||
uint8_t op = it->op;
|
||||
|
||||
int pos = 0;
|
||||
int mlen;
|
||||
|
||||
if (op == TLV_OP_NEW || op == TLV_OP_DEL)
|
||||
rm_dir_content(smsRx_dir, cryptShaAsString(&on->nodeId));
|
||||
if (it->op == TLV_OP_NEW || it->op == TLV_OP_DEL)
|
||||
rm_dir_content(smsRx_dir, cryptShaAsString(&it->on->k.nodeId));
|
||||
|
||||
do {
|
||||
|
||||
if (pos + (int)sizeof ( struct description_msg_sms) > it->frame_msgs_length)
|
||||
if (pos + (int)sizeof ( struct description_msg_sms) > it->f_msgs_len)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
struct description_msg_sms *sms = (struct description_msg_sms *) (it->frame_data + pos);
|
||||
struct description_msg_sms *sms = (struct description_msg_sms *) (it->f_data + pos);
|
||||
mlen = sizeof ( struct description_msg_sms) +ntohs(sms->text_len);
|
||||
|
||||
if (pos + mlen > it->frame_msgs_length)
|
||||
if (pos + mlen > it->f_msgs_len)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if (validate_name_string(sms->name, sizeof (sms->name), NULL) != SUCCESS)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if (op == TLV_OP_NEW) {
|
||||
if (it->op == TLV_OP_NEW) {
|
||||
|
||||
int fd;
|
||||
char path_name[MAX_PATH_SIZE];
|
||||
sprintf(path_name, "%s/%s:%s", smsRx_dir, cryptShaAsString(&on->nodeId), sms->name);
|
||||
sprintf(path_name, "%s/%s:%s", smsRx_dir, cryptShaAsString(&it->on->k.nodeId), sms->name);
|
||||
|
||||
if ((fd = open(path_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
|
||||
|
||||
@@ -289,9 +288,9 @@ int process_description_sms(struct rx_frame_iterator *it)
|
||||
}
|
||||
}
|
||||
|
||||
} while ((pos = pos + mlen) < it->frame_msgs_length);
|
||||
} while ((pos = pos + mlen) < it->f_msgs_len);
|
||||
|
||||
if (pos != it->frame_msgs_length)
|
||||
if (pos != it->f_msgs_len)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
return pos;
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#define DEF_SMS_FZIP TYP_FZIP_DO
|
||||
|
||||
#define ARG_SMS_FREF "refSms"
|
||||
#define DEF_SMS_FREF TYP_FREF_DO
|
||||
#define DEF_SMS_FREF TYP_FREF_DO1
|
||||
|
||||
|
||||
struct sms_node {
|
||||
|
@@ -5,8 +5,8 @@ LDFLAGS += -shared
|
||||
|
||||
PLUGIN_NAME = bmx6_table
|
||||
|
||||
SRC_C = table.c
|
||||
SRC_H = table.h
|
||||
SRC_C = table.c ../../redist.c
|
||||
SRC_H = table.h ../../redist.h
|
||||
OBJS= $(SRC_C:.c=.o)
|
||||
|
||||
PLUGIN_FULLNAME = $(PLUGIN_NAME).so
|
||||
|
@@ -48,9 +48,9 @@
|
||||
#include "iptools.h"
|
||||
#include "ip.h"
|
||||
#include "hna.h"
|
||||
#include "redist.h"
|
||||
#include "allocate.h"
|
||||
#include "table.h"
|
||||
#include "redist.c"
|
||||
|
||||
|
||||
#define CODE_CATEGORY_NAME "table"
|
||||
@@ -60,58 +60,64 @@ static AVL_TREE(redist_in_tree, struct redist_in_node, k);
|
||||
static AVL_TREE(redist_opt_tree, struct redistr_opt_node, nameKey);
|
||||
static AVL_TREE(redist_out_tree, struct redist_out_node, k);
|
||||
|
||||
static LIST_SIMPEL(tunXin6_net_adv_list, struct tunXin6_net_adv_node, list, list);
|
||||
static LIST_SIMPEL(table_net_adv_list, struct tunXin6_net_adv_node, list, list);
|
||||
|
||||
static struct sys_route_dict rtredist_rt_dict[BMX6_ROUTE_MAX];
|
||||
static struct sys_route_dict rtredist_rt_dict[BMX6_ROUTE_MAX_SUPP+1];
|
||||
|
||||
|
||||
int32_t rtredist_delay = DEF_REDIST_DELAY;
|
||||
|
||||
int rtevent_sk = 0;
|
||||
int32_t rtredist_delay = 200;
|
||||
|
||||
STATIC_FUNC
|
||||
void redist_table_routes(void* laterp)
|
||||
void redist_table_routes(IDM_T forceChanged)
|
||||
{
|
||||
struct redist_in_node *rin;
|
||||
struct redist_in_node rii;
|
||||
struct avl_node *an=NULL;
|
||||
memset(&rii, 0, sizeof (rii));
|
||||
|
||||
while ((rin = avl_next_item(&redist_in_tree, &rii.k))) {
|
||||
rii = *rin;
|
||||
|
||||
ASSERTION(-502300, matching_redist_opt(rin, &redist_opt_tree, rtredist_rt_dict));
|
||||
|
||||
if (!forceChanged && rin->old != (!!rin->cnt))
|
||||
forceChanged = YES;
|
||||
|
||||
if (rin->cnt <= 0)
|
||||
debugFree( avl_remove(&redist_in_tree, &rin->k, -300551), -300554);
|
||||
}
|
||||
|
||||
if ( forceChanged) {
|
||||
if ( redistribute_routes(&redist_out_tree, &redist_in_tree, &redist_opt_tree, rtredist_rt_dict) )
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &table_net_adv_list);
|
||||
}
|
||||
|
||||
while ((rin=avl_iterate_item(&redist_in_tree, &an)))
|
||||
rin->old = 1;
|
||||
|
||||
dbgf(forceChanged ? DBGL_SYS : DBGL_CHANGES, DBGT_INFO, " %sCHANGED out.items=%d in.items=%d opt.items=%d net_advs=%d",
|
||||
forceChanged ? "" : "UN",
|
||||
redist_out_tree.items, redist_in_tree.items, redist_opt_tree.items, table_net_adv_list.items);
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_table_routes(void* laterp)
|
||||
{
|
||||
static IDM_T scheduled = NO;
|
||||
|
||||
if ( laterp && !scheduled) {
|
||||
scheduled = YES;
|
||||
task_register(rtredist_delay, redist_table_routes, NULL, -300550);
|
||||
task_register(rtredist_delay, schedule_table_routes, NULL, -300550);
|
||||
|
||||
} else if ( !laterp ) {
|
||||
|
||||
dbgf_track(DBGT_INFO, " ");
|
||||
scheduled = NO;
|
||||
task_remove(redist_table_routes, NULL);
|
||||
|
||||
IDM_T changed = NO;
|
||||
|
||||
struct redist_in_node *rin;
|
||||
struct redist_in_node rii;
|
||||
struct avl_node *an=NULL;
|
||||
memset(&rii, 0, sizeof (rii));
|
||||
while ((rin = avl_next_item(&redist_in_tree, &rii.k))) {
|
||||
rii = *rin;
|
||||
|
||||
if (rin->old != rin->cnt)
|
||||
changed = YES;
|
||||
|
||||
if (rin->cnt <= 0)
|
||||
debugFree( avl_remove(&redist_in_tree, &rin->k, -300551), -300554);
|
||||
}
|
||||
|
||||
if ( changed) {
|
||||
if ( redistribute_routes(&redist_out_tree, &redist_in_tree, &redist_opt_tree, rtredist_rt_dict) )
|
||||
update_tunXin6_net_adv_list(&redist_out_tree, &tunXin6_net_adv_list);
|
||||
}
|
||||
|
||||
while ((rin=avl_iterate_item(&redist_in_tree, &an)))
|
||||
rin->old = 1;
|
||||
|
||||
dbgf_track(DBGT_INFO, "%sCHANGED out.items=%d in.items=%d opt.items=%d net_advs=%d",
|
||||
changed ? "" : "UN",
|
||||
redist_out_tree.items, redist_in_tree.items, redist_opt_tree.items, tunXin6_net_adv_list.items);
|
||||
task_remove(schedule_table_routes, NULL);
|
||||
|
||||
redist_table_routes(NO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,52 +135,65 @@ void get_route_list_nlhdr(struct nlmsghdr *nh, void *unused )
|
||||
struct net_key net = {.af=rtm->rtm_family, .mask=rtm->rtm_dst_len,
|
||||
.ip=(rtm->rtm_family==AF_INET6) ? *((IPX_T *) RTA_DATA(rtap)) : ip4ToX(*((IP4_T *) RTA_DATA(rtap))) };
|
||||
|
||||
dbgf_sys(DBGT_INFO, "%s route=%s table=%d protocol=%s", nh->nlmsg_type==RTM_NEWROUTE?"ADD":"DEL",
|
||||
netAsStr(&net), rtm->rtm_table, rtredist_rt_dict[rtm->rtm_protocol].sys2Name);
|
||||
dbgf_track(DBGT_INFO, "%s route=%s table=%d protocol=%s", nh->nlmsg_type==RTM_NEWROUTE?"ADD":"DEL",
|
||||
netAsStr(&net), rtm->rtm_table, memAsHexStringSep(&rtm->rtm_protocol, 1, 0, NULL));
|
||||
|
||||
struct redist_in_node new = {.k = {.table = rtm->rtm_table, .inType = rtm->rtm_protocol, .net = net}};
|
||||
struct redist_in_node *rin = avl_find_item(&redist_in_tree, &new.k);
|
||||
assertion(-501527, IMPLIES(nh->nlmsg_type==RTM_DELROUTE, rin && rin->cnt>0));
|
||||
|
||||
if (rin) {
|
||||
|
||||
rin->cnt += (nh->nlmsg_type==RTM_NEWROUTE ? 1 : -1);
|
||||
|
||||
} else {
|
||||
ASSERTION(-502301, (rin->roptn && rin->roptn == matching_redist_opt(&new, &redist_opt_tree, rtredist_rt_dict)));
|
||||
assertion(-501527, IMPLIES(nh->nlmsg_type==RTM_DELROUTE, (rin->cnt>0)));
|
||||
|
||||
rin->cnt += (nh->nlmsg_type==RTM_NEWROUTE ? 1 : -1);
|
||||
schedule_table_routes((void*)1);
|
||||
|
||||
} else if ((new.roptn = matching_redist_opt(&new, &redist_opt_tree, rtredist_rt_dict))) {
|
||||
|
||||
assertion(-502302, (nh->nlmsg_type == RTM_NEWROUTE));
|
||||
|
||||
rin = debugMalloc(sizeof(new), -300552);
|
||||
*rin = new;
|
||||
rin->cnt = 1;
|
||||
avl_insert(&redist_in_tree, rin, -300553);
|
||||
schedule_table_routes((void*)1);
|
||||
}
|
||||
redist_table_routes((void*)1);
|
||||
}
|
||||
rtap = RTA_NEXT(rtap, rtl);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t sync_redist_routes(IDM_T cleanup, IDM_T resync);
|
||||
|
||||
static void recv_rtevent_netlink_sk(int sk)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
char buf[4096]; //test this with a very small value !!
|
||||
struct sockaddr_nl sa;
|
||||
struct iovec iov = {.iov_base = buf, .iov_len = sizeof (buf)};
|
||||
assertion(-501528, (sk==rtevent_sk));
|
||||
// char buf[4096]; //test this with a very small value !!
|
||||
// struct sockaddr_nl sa;
|
||||
// struct iovec iov = {.iov_base = buf, .iov_len = sizeof(buf)};
|
||||
// assertion(-501528, (sk==rtevent_sk));
|
||||
|
||||
dbgf_all(DBGT_INFO, "detected changed routes! Going to check...");
|
||||
|
||||
/*
|
||||
struct msghdr msg; // = {(void *) & sa, sizeof (sa), &iov, 1, NULL, 0, 0};
|
||||
memset( &msg, 0, sizeof( struct msghdr));
|
||||
msg.msg_name = (void *)&sa;
|
||||
msg.msg_namelen = sizeof(sa); /* Length of address data. */
|
||||
msg.msg_iov = &iov; /* Vector of data to send/receive into. */
|
||||
msg.msg_iovlen = 1; /* Number of elements in the vector. */
|
||||
msg.msg_namelen = sizeof(sa); // Length of address data.
|
||||
msg.msg_iov = &iov; // Vector of data to send/receive into.
|
||||
msg.msg_iovlen = 1; // Number of elements in the vector.
|
||||
*/
|
||||
int result = rtnl_rcv( sk, 0, 0, IP_ROUTE_GET, NO, get_route_list_nlhdr, NULL );
|
||||
|
||||
rtnl_rcv( sk, 0, 0, IP_ROUTE_GET, NO, get_route_list_nlhdr, NULL );
|
||||
if (result != SUCCESS)
|
||||
sync_redist_routes(NO, YES);
|
||||
}
|
||||
|
||||
static int open_rtevent_netlink_sk(void)
|
||||
STATIC_FUNC
|
||||
int open_rtevent_netlink_sk(void)
|
||||
{
|
||||
int rtevent_sk = 0;
|
||||
struct sockaddr_nl sa;
|
||||
int32_t unix_opts;
|
||||
memset (&sa, 0, sizeof(sa));
|
||||
@@ -202,19 +221,94 @@ static int open_rtevent_netlink_sk(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int oldBuff=0;
|
||||
socklen_t oldSize = sizeof(oldBuff);
|
||||
int buffsize = 66560; // 532480; // 266240; // 133120 // 66560 // RTNL_RCV_MAX //seems all too small for 2K+ routes and heavy CPU load
|
||||
int newBuff=0;
|
||||
socklen_t newSize = sizeof(newBuff);
|
||||
|
||||
if (
|
||||
getsockopt(rtevent_sk, SOL_SOCKET, SO_RCVBUF, &oldBuff, &oldSize) < 0 ||
|
||||
setsockopt(rtevent_sk, SOL_SOCKET, SO_RCVBUFFORCE, &buffsize, sizeof(buffsize)) < 0 ||
|
||||
getsockopt(rtevent_sk, SOL_SOCKET, SO_RCVBUF, &newBuff, &newSize) < 0 ||
|
||||
newBuff < RTNL_RCV_MAX) {
|
||||
|
||||
dbgf_sys(DBGT_WARN, "can't setsockopts buffsize from=%d to=%d now=%d %s", oldBuff, buffsize, newBuff, strerror(errno));
|
||||
rtevent_sk = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbgf_sys(DBGT_ERR, "setsockopts buffsize from=%d to=%d now=%d", oldBuff, buffsize, newBuff);
|
||||
|
||||
|
||||
set_fd_hook( rtevent_sk, recv_rtevent_netlink_sk, ADD);
|
||||
|
||||
return rtevent_sk;
|
||||
}
|
||||
|
||||
static void close_rtevent_netlink_sk(void)
|
||||
STATIC_FUNC
|
||||
int close_rtevent_netlink_sk(int rtevent_sk)
|
||||
{
|
||||
|
||||
set_fd_hook(rtevent_sk, recv_rtevent_netlink_sk, DEL);
|
||||
|
||||
if ( rtevent_sk > 0 )
|
||||
close( rtevent_sk );
|
||||
|
||||
rtevent_sk = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t sync_redist_routes(IDM_T cleanup, IDM_T resync)
|
||||
{
|
||||
static int rtevent_sk = 0;
|
||||
|
||||
if (cleanup) {
|
||||
|
||||
rtevent_sk = close_rtevent_netlink_sk(rtevent_sk);
|
||||
|
||||
set_tunXin6_net_adv_list(DEL, &table_net_adv_list);
|
||||
|
||||
while (redist_in_tree.items)
|
||||
debugFree(avl_remove_first_item(&redist_in_tree, -300487), -300488);
|
||||
|
||||
while (redist_out_tree.items) {
|
||||
debugFree(avl_remove_first_item(&redist_out_tree, -300513), -300514);
|
||||
my_description_changed = YES;
|
||||
}
|
||||
|
||||
while (table_net_adv_list.items)
|
||||
debugFree(list_del_head(&table_net_adv_list), -300515);
|
||||
|
||||
} else if (resync) {
|
||||
|
||||
dbgf_sys(DBGT_ERR, "rt-events out of sync. Trying to resync...");
|
||||
|
||||
rtevent_sk = close_rtevent_netlink_sk(rtevent_sk);
|
||||
|
||||
while (redist_in_tree.items)
|
||||
debugFree(avl_remove_first_item(&redist_in_tree, -300487), -300488);
|
||||
|
||||
rtevent_sk = open_rtevent_netlink_sk();
|
||||
|
||||
kernel_get_route(NO, AF_INET, 0, get_route_list_nlhdr);
|
||||
kernel_get_route(NO, AF_INET6, 0, get_route_list_nlhdr);
|
||||
|
||||
redist_table_routes(YES);
|
||||
|
||||
} else {
|
||||
|
||||
kernel_get_route(NO, AF_INET, 0, get_route_list_nlhdr);
|
||||
kernel_get_route(NO, AF_INET6, 0, get_route_list_nlhdr);
|
||||
|
||||
set_tunXin6_net_adv_list(ADD, &table_net_adv_list);
|
||||
|
||||
rtevent_sk = open_rtevent_netlink_sk();
|
||||
}
|
||||
|
||||
|
||||
return rtevent_sk;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
@@ -233,30 +327,15 @@ int32_t opt_redistribute(uint8_t cmd, uint8_t _save, struct opt_type *opt, struc
|
||||
|
||||
dbgf_track(DBGT_INFO, "Initializing...");
|
||||
|
||||
kernel_get_route(NO, AF_INET, 0, get_route_list_nlhdr);
|
||||
kernel_get_route(NO, AF_INET6, 0, get_route_list_nlhdr);
|
||||
|
||||
/*
|
||||
struct redist_in_node *rin;
|
||||
struct avl_node *an=NULL;
|
||||
while ((rin=avl_iterate_item(&redist_in_tree, &an))) {
|
||||
dbgf_track(DBGT_INFO, "current routes: net=%s table=%d cnt=%d",
|
||||
netAsStr(&rin->k.net), rin->k.table, rin->cnt);
|
||||
}
|
||||
*/
|
||||
|
||||
set_tunXin6_net_adv_list(ADD, &tunXin6_net_adv_list);
|
||||
|
||||
open_rtevent_netlink_sk();
|
||||
set_fd_hook( rtevent_sk, recv_rtevent_netlink_sk, ADD);
|
||||
|
||||
sync_redist_routes(NO, NO);
|
||||
initialized = YES;
|
||||
}
|
||||
|
||||
if (cmd == OPT_SET_POST && initialized && changed) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "Updating...");
|
||||
redist_table_routes(NULL);
|
||||
// redist_table_routes(YES);
|
||||
sync_redist_routes(NO, YES);
|
||||
|
||||
changed = NO;
|
||||
}
|
||||
@@ -265,21 +344,7 @@ int32_t opt_redistribute(uint8_t cmd, uint8_t _save, struct opt_type *opt, struc
|
||||
|
||||
dbgf_track(DBGT_INFO, "Cleaning up...");
|
||||
|
||||
set_tunXin6_net_adv_list(DEL, &tunXin6_net_adv_list);
|
||||
set_fd_hook(rtevent_sk, recv_rtevent_netlink_sk, DEL);
|
||||
close_rtevent_netlink_sk();
|
||||
|
||||
while (redist_in_tree.items)
|
||||
debugFree(avl_remove_first_item(&redist_in_tree, -300487), -300488);
|
||||
|
||||
while (redist_out_tree.items) {
|
||||
debugFree(avl_remove_first_item(&redist_out_tree, -300513), -300514);
|
||||
my_description_changed = YES;
|
||||
}
|
||||
|
||||
while (tunXin6_net_adv_list.items)
|
||||
debugFree(list_del_head(&tunXin6_net_adv_list), -300515);
|
||||
|
||||
sync_redist_routes(YES, NO);
|
||||
|
||||
initialized = NO;
|
||||
changed = NO;
|
||||
@@ -292,6 +357,9 @@ int32_t opt_redistribute(uint8_t cmd, uint8_t _save, struct opt_type *opt, struc
|
||||
static struct opt_type rtredist_options[]= {
|
||||
// ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help
|
||||
|
||||
{ODI,0,ARG_REDIST_DELAY, 0,9,1, A_PS1, A_ADM, A_DYI, A_CFA, A_ANY, &rtredist_delay,MIN_REDIST_DELAY,MAX_REDIST_DELAY,DEF_REDIST_DELAY,0, 0,
|
||||
ARG_VALUE_FORM, HLP_REDIST_DELAY}
|
||||
,
|
||||
{ODI,0,ARG_REDIST, 0,9,2,A_PM1N,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0,0, opt_redistribute,
|
||||
ARG_NAME_FORM, HLP_REDIST},
|
||||
{ODI,ARG_REDIST,ARG_REDIST_NET, 'n',9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0,0, opt_redistribute,
|
||||
@@ -308,6 +376,10 @@ static struct opt_type rtredist_options[]= {
|
||||
ARG_VALUE_FORM, HLP_REDIST_AGGREGATE},
|
||||
{ODI,ARG_REDIST,ARG_REDIST_BW, 'b',9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0,0, opt_redistribute,
|
||||
ARG_VALUE_FORM, HLP_REDIST_BW},
|
||||
{ODI,ARG_REDIST,ARG_ROUTE_SYS, 0,9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, BMX6_ROUTE_MAX_SUPP,0,0, opt_redistribute,
|
||||
ARG_VALUE_FORM, HLP_ROUTE_SYS},
|
||||
{ODI,ARG_REDIST,ARG_ROUTE_ALL, 0,9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 1, 0,0, opt_redistribute,
|
||||
ARG_VALUE_FORM, HLP_ROUTE_TYPE},
|
||||
{ODI,ARG_REDIST,ARG_ROUTE_KERNEL, 0,9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 1, 0,0, opt_redistribute,
|
||||
ARG_VALUE_FORM, HLP_ROUTE_TYPE},
|
||||
{ODI,ARG_REDIST,ARG_ROUTE_BOOT, 0,9,2,A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 1, 0,0, opt_redistribute,
|
||||
|
@@ -15,6 +15,13 @@
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define ARG_REDIST_DELAY "redistTableDelay"
|
||||
#define HLP_REDIST_DELAY "delay processing (and announcement) of changed table routes in ms to aggregate shortly following changes"
|
||||
#define MIN_REDIST_DELAY 100
|
||||
#define MAX_REDIST_DELAY 3600000
|
||||
#define DEF_REDIST_DELAY 2200
|
||||
|
||||
|
||||
#define ARG_REDIST "redistTable"
|
||||
#define HLP_REDIST "arbitrary but unique name for redistributed table network(s) depending on sub criterias"
|
||||
|
||||
|
@@ -1,15 +1,15 @@
|
||||
2009-08-10 - bmx6_config plugin for openWrt universial configuraton interface (UCI)
|
||||
bmx6_config plugin for openWrt universial configuraton interface (UCI)
|
||||
|
||||
- plugin for dynamic interaction with uci
|
||||
( http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz )
|
||||
|
||||
- to compile first install uci:
|
||||
- To compile first install uci (old version):
|
||||
wget http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz
|
||||
sometimes theres an error: edit cli.c # change line 465 to: char *argv[MAX_ARGS+2];
|
||||
tar xzvf uci-0.7.5.tar.gz; cd uci-0.7.5; make; sudo make install
|
||||
|
||||
- Alternatively check: http://www.wakoond.hu/2013/06/using-uci-on-ubuntu.html
|
||||
|
||||
- default configuration backend is: /etc/config/bmx6
|
||||
- Default configuration backend is: /etc/config/bmx6
|
||||
|
||||
- see lib/bmx6_config/etc_config for a simple (bmx)
|
||||
and an advanced (bmx-advanced) example
|
||||
|
@@ -1,6 +1,6 @@
|
||||
|
||||
CFLAGS += $(CORE_CFLAGS) -fpic -I../../
|
||||
LDFLAGS += -shared -luci
|
||||
CFLAGS += $(CORE_CFLAGS) -fpic -I../../ -I/usr/local/include/uci/
|
||||
LDFLAGS += -luci
|
||||
#-Wl,-soname,bmx6_config
|
||||
|
||||
PLUGIN_NAME = bmx6_config
|
||||
@@ -19,7 +19,7 @@ all: $(PLUGIN_FULLNAME) Makefile
|
||||
|
||||
|
||||
$(PLUGIN_FULLNAME): $(OBJS) Makefile
|
||||
$(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME)
|
||||
$(CC) -shared $(OBJS) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME)
|
||||
ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME)
|
||||
|
||||
%.o: %.c %.h Makefile
|
||||
|
866
link.c
Normal file
866
link.c
Normal file
@@ -0,0 +1,866 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
//#include "math.h"
|
||||
|
||||
|
||||
#include "list.h"
|
||||
#include "control.h"
|
||||
#include "bmx.h"
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "key.h"
|
||||
#include "metrics.h"
|
||||
#include "ogm.h"
|
||||
#include "link.h"
|
||||
#include "msg.h"
|
||||
#include "content.h"
|
||||
#include "ip.h"
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
#include "iptools.h"
|
||||
#include "allocate.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "metric"
|
||||
|
||||
|
||||
|
||||
static int32_t my_link_window = DEF_HELLO_SQN_WINDOW;
|
||||
|
||||
//int32_t link_ignore_min = DEF_LINK_IGNORE_MIN;
|
||||
|
||||
//int32_t link_ignore_max = DEF_LINK_IGNORE_MAX;
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
UMETRIC_T timeaware_rx_probe(LinkNode *link)
|
||||
{
|
||||
if (((TIME_T) (bmx_time - link->rx_probe_record.hello_time_max)) < RP_ADV_DELAY_TOLERANCE)
|
||||
return link->rx_probe_record.hello_umetric;
|
||||
|
||||
if (((TIME_T) (bmx_time - link->rx_probe_record.hello_time_max)) < RP_ADV_DELAY_RANGE) {
|
||||
return (link->rx_probe_record.hello_umetric *
|
||||
((UMETRIC_T) (RP_ADV_DELAY_RANGE - (bmx_time - link->rx_probe_record.hello_time_max)))) /
|
||||
RP_ADV_DELAY_RANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
UMETRIC_T timeaware_tx_probe(LinkNode *link)
|
||||
{
|
||||
if (((TIME_T) (bmx_time - link->rp_time_max)) < TP_ADV_DELAY_TOLERANCE)
|
||||
return link->tx_probe_umetric;
|
||||
|
||||
if (((TIME_T) (bmx_time - link->rp_time_max)) < TP_ADV_DELAY_RANGE) {
|
||||
|
||||
return ((link->tx_probe_umetric * ((UMETRIC_T) (TP_ADV_DELAY_RANGE - (bmx_time - link->rp_time_max)))) / TP_ADV_DELAY_RANGE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void lndev_assign_best(struct neigh_node *onlyLocal, LinkNode *onlyLink )
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
assertion(-501133, (IMPLIES(onlyLink, onlyLocal && onlyLocal == onlyLink->k.linkDev->key.local)));
|
||||
ASSERTION(-500792, (IMPLIES(onlyLink, onlyLink->k.linkDev == avl_find_item(&onlyLocal->linkDev_tree, &onlyLink->k.linkDev->key.devIdx))));
|
||||
|
||||
dbgf_all(DBGT_INFO, "only_local=%s link: nbLlIp=%s nbIdx=%d mydev=%s",
|
||||
onlyLocal ? cryptShaAsString(&onlyLocal->local_id) : 0,
|
||||
onlyLink ? ip6AsStr(&onlyLink->k.linkDev->key.llocal_ip) : DBG_NIL,
|
||||
onlyLink ? onlyLink->k.linkDev->key.devIdx : 0,
|
||||
onlyLink ? onlyLink->k.myDev->label_cfg.str : DBG_NIL);
|
||||
|
||||
struct avl_node *local_an = NULL;
|
||||
struct neigh_node *local;
|
||||
|
||||
while ((local = onlyLocal) || (local = avl_iterate_item(&local_tree, &local_an))) {
|
||||
|
||||
// assertion(-500794, (local->linkDev_tree.items));
|
||||
|
||||
LinkDevNode *linkDev = NULL;
|
||||
struct avl_node *link_an = NULL;
|
||||
|
||||
UMETRIC_T old_timeaware_tx_probe = 0;
|
||||
|
||||
if (local->best_rp_link)
|
||||
local->best_rp_link->timeaware_rx_probe = timeaware_rx_probe(local->best_rp_link);
|
||||
|
||||
if (local->best_tp_link) {
|
||||
old_timeaware_tx_probe = local->best_tp_link->timeaware_tx_probe;
|
||||
local->best_tp_link->timeaware_tx_probe = timeaware_tx_probe(local->best_tp_link);
|
||||
}
|
||||
|
||||
|
||||
dbgf_all(DBGT_INFO, "local_id=%s", cryptShaAsString(&local->local_id));
|
||||
|
||||
while ((onlyLink && (linkDev = onlyLink->k.linkDev)) || (linkDev = avl_iterate_item(&local->linkDev_tree, &link_an))) {
|
||||
|
||||
LinkNode *currLink = NULL;
|
||||
|
||||
dbgf_all(DBGT_INFO, "link=%s", ip6AsStr(&linkDev->key.llocal_ip));
|
||||
|
||||
while ((onlyLink && (currLink = onlyLink)) || (currLink = avl_next_item(&linkDev->link_tree, (currLink ? &currLink->k : NULL)))) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "lndev=%s items=%d",
|
||||
currLink->k.myDev->label_cfg.str, linkDev->link_tree.items);
|
||||
|
||||
currLink->timeaware_rx_probe = timeaware_rx_probe(currLink);
|
||||
currLink->timeaware_tx_probe = timeaware_tx_probe(currLink);
|
||||
|
||||
|
||||
if (!local->best_rp_link || local->best_rp_link->timeaware_rx_probe < currLink->timeaware_rx_probe)
|
||||
local->best_rp_link = currLink;
|
||||
|
||||
if (!local->best_tp_link || local->best_tp_link->timeaware_tx_probe < currLink->timeaware_tx_probe)
|
||||
local->best_tp_link = currLink;
|
||||
|
||||
if (onlyLink)
|
||||
break;
|
||||
}
|
||||
|
||||
if (onlyLink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// assertion(-500406, (local->best_rp_link));
|
||||
// assertion(-501086, (local->best_tp_link));
|
||||
|
||||
if (!local->best_tp_link || local->best_tp_link->timeaware_tx_probe == 0)
|
||||
local->best_tp_link = local->best_rp_link;
|
||||
|
||||
if (sendLinkRevisedOgms && local->best_tp_link && local->best_tp_link->timeaware_tx_probe > old_timeaware_tx_probe) {
|
||||
|
||||
struct reference_node *ref = NULL;
|
||||
while ((ref = avl_next_item(&local->refsByKhash_tree, ref ? &ref->claimedKey : NULL))) {
|
||||
assertion(-502422, (ref->dhn));
|
||||
if (ref->dhn->descContent && ref->dhn->descContent->orig)
|
||||
process_ogm_metric(ref);
|
||||
}
|
||||
}
|
||||
|
||||
if(onlyLocal)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void purge_linkDevs(LinkDevKey *onlyLinkDev, struct dev_node *only_dev, IDM_T purgeLocal)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
LinkDevNode *linkDev;
|
||||
LinkDevKey linkDevKey;
|
||||
memset(&linkDevKey, 0, sizeof(linkDevKey));
|
||||
|
||||
dbgf_all(DBGT_INFO, "only_link_key=%s llip=%s only_dev=%s purgeLocal=%d",
|
||||
onlyLinkDev ? cryptShaAsString(&onlyLinkDev->local->local_id) : "---", ip6AsStr(onlyLinkDev ? &onlyLinkDev->llocal_ip : NULL),
|
||||
only_dev ? only_dev->label_cfg.str : DBG_NIL, purgeLocal);
|
||||
|
||||
while ((linkDev = (onlyLinkDev ? avl_find_item(&link_dev_tree, onlyLinkDev) : avl_next_item(&link_dev_tree, &linkDevKey)))) {
|
||||
|
||||
struct neigh_node *local = linkDev->key.local;
|
||||
LinkKey linkKey = {NULL,NULL};
|
||||
LinkNode *link;
|
||||
|
||||
assertion(-500940, local);
|
||||
assertion(-500941, local == avl_find_item(&local_tree, &linkDev->key.local->local_id));
|
||||
assertion(-500942, linkDev == avl_find_item(&local->linkDev_tree, &linkDev->key.devIdx));
|
||||
|
||||
linkDevKey = linkDev->key;
|
||||
|
||||
while ((link = avl_next_item(&linkDev->link_tree, &linkKey))) {
|
||||
linkKey = link->k;
|
||||
|
||||
if ((!only_dev || only_dev == link->k.myDev)
|
||||
//&& (!only_expired || (((TIME_T) (bmx_time - link->pkt_time_max)) > (TIME_T) link_purge_to))
|
||||
) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "purging nbLlIp=%s nbIdx=%d dev=%s",
|
||||
ip6AsStr(&linkDev->key.llocal_ip), linkDev->key.devIdx, link->k.myDev->label_cfg.str);
|
||||
|
||||
purge_orig_router(NULL, NULL, link, NO);
|
||||
|
||||
if (link == local->best_rp_link)
|
||||
local->best_rp_link = NULL;
|
||||
|
||||
if (link == local->best_tp_link)
|
||||
local->best_tp_link = NULL;
|
||||
|
||||
avl_remove(&link_tree, &link->k, -300221);
|
||||
avl_remove(&linkDev->link_tree, &link->k, -300749);
|
||||
debugFree(link, -300044);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assertion(-500323, (only_dev || !linkDev->link_tree.items));
|
||||
|
||||
if (!linkDev->link_tree.items) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "purging: linkDev local_id=%s link_ip=%s only_dev=%s, local->linkDevs=%d",
|
||||
cryptShaAsString(&linkDev->key.local->local_id), ip6AsStr(&linkDev->key.llocal_ip),
|
||||
only_dev ? only_dev->label_cfg.str : "???", local->linkDev_tree.items);
|
||||
|
||||
avl_remove(&link_dev_tree, &linkDev->key, -300193);
|
||||
avl_remove(&local->linkDev_tree, &linkDev->key.devIdx, -300330);
|
||||
|
||||
assertion(-502423, IMPLIES(!local->linkDev_tree.items, !local->best_rp_link));
|
||||
assertion(-502424, IMPLIES(!local->linkDev_tree.items, !local->best_tp_link));
|
||||
|
||||
debugFree(linkDev, -300045);
|
||||
|
||||
if (purgeLocal && !local->linkDev_tree.items)
|
||||
keyNode_schedLowerWeight(local->on->key, KCPromoted);
|
||||
|
||||
}
|
||||
|
||||
if (onlyLinkDev)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
lndev_assign_best(NULL, NULL);
|
||||
cb_plugin_hooks(PLUGIN_CB_LINKS_EVENT, NULL);
|
||||
|
||||
assertion(-502425, IMPLIES(!only_dev && !onlyLinkDev, !link_tree.items));
|
||||
assertion(-502426, IMPLIES(!only_dev && !onlyLinkDev, !link_dev_tree.items));
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
IDM_T updateNeighDevId(struct neigh_node *nn, struct desc_content *contents)
|
||||
{
|
||||
struct dsc_msg_llip* msg = (struct dsc_msg_llip*) contents_data(contents, BMX_DSC_TLV_LLIP);
|
||||
uint16_t m, msgs = 0;
|
||||
LinkDevNode *ldn;
|
||||
DEVIDX_T idx = 0;
|
||||
struct avl_node *an = NULL;
|
||||
|
||||
if (!contents || (msgs = contents_dlen(contents, BMX_DSC_TLV_LLIP) / sizeof(struct dsc_msg_llip))) {
|
||||
|
||||
for (an = NULL; (ldn = avl_iterate_item(&nn->linkDev_tree, &an));)
|
||||
ldn->purge = YES;
|
||||
|
||||
for (m = 0; m < msgs; m++) {
|
||||
|
||||
for (an = NULL; (ldn = avl_iterate_item(&nn->linkDev_tree, &an));) {
|
||||
|
||||
if (is_ip_equal(&ldn->key.llocal_ip, &msg[m].ip6))
|
||||
ldn->purge = NO;
|
||||
}
|
||||
}
|
||||
|
||||
while ((ldn = avl_next_item(&nn->linkDev_tree, &idx))) {
|
||||
idx = ldn->key.devIdx;
|
||||
|
||||
if (ldn->purge)
|
||||
purge_linkDevs(&ldn->key, NULL, YES);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
LinkNode *getLinkNode(struct dev_node *dev, IPX_T *llip, DEVIDX_T idx, struct neigh_node *verifiedNeigh)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
LinkNode *link = NULL;
|
||||
LinkDevNode *linkDev = NULL;
|
||||
|
||||
dbgf_all(DBGT_INFO, "llip=%s local_id=%s local=%s",
|
||||
ip6AsStr(llip), cryptShaAsString(&verifiedNeigh->local_id), verifiedNeigh ? "yes" : "no");
|
||||
|
||||
if (!(linkDev = avl_find_item(&verifiedNeigh->linkDev_tree, &idx))) {
|
||||
|
||||
linkDev = debugMallocReset(sizeof(LinkDevNode), -300024);
|
||||
|
||||
AVL_INIT_TREE(linkDev->link_tree, LinkNode, k);
|
||||
|
||||
linkDev->key.llocal_ip = *llip;
|
||||
linkDev->key.devIdx = idx;
|
||||
linkDev->key.local = verifiedNeigh;
|
||||
|
||||
avl_insert(&link_dev_tree, linkDev, -300147);
|
||||
avl_insert(&verifiedNeigh->linkDev_tree, linkDev, -300334);
|
||||
|
||||
dbgf_track(DBGT_INFO, "creating new link=%s (total %d)", ip6AsStr(llip), link_dev_tree.items);
|
||||
|
||||
updateNeighDevId(verifiedNeigh, verifiedNeigh->on->descContent);
|
||||
|
||||
} else if (!is_ip_equal(&linkDev->key.llocal_ip, llip)) {
|
||||
|
||||
dbgf_mute(25 , DBGL_SYS, DBGT_ERR, "changed NB=%s devIdx=%d llIp: %s->%s",
|
||||
cryptShaAsString(&verifiedNeigh->local_id), idx, ip6AsStr(&linkDev->key.llocal_ip), ip6AsStr(llip));
|
||||
purge_linkDevs(&linkDev->key, NULL, NO);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linkDev->pkt_time_max = bmx_time;
|
||||
|
||||
LinkKey linkKey = {.linkDev = linkDev, .myDev = dev};
|
||||
|
||||
if (!(link = avl_find_item(&linkDev->link_tree, &linkKey))) {
|
||||
|
||||
link = debugMallocReset(sizeof(LinkNode), -300023);
|
||||
|
||||
link->k = linkKey;
|
||||
|
||||
dbgf_track(DBGT_INFO, "creating new lndev %16s %s", ip6AsStr(&linkDev->key.llocal_ip), dev->name_phy_cfg.str);
|
||||
|
||||
avl_insert(&linkDev->link_tree, link, -300750);
|
||||
|
||||
ASSERTION(-500489, !avl_find(&link_tree, &link->k));
|
||||
|
||||
avl_insert(&link_tree, link, -300220);
|
||||
|
||||
lndev_assign_best(linkDev->key.local, link);
|
||||
cb_plugin_hooks(PLUGIN_CB_LINKS_EVENT, NULL);
|
||||
}
|
||||
|
||||
assertion(-502196, (link->k.linkDev == linkDev));
|
||||
|
||||
lndev_assign_best(NULL, NULL);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
void update_link_probe_record(LinkNode *link, HELLO_SQN_T sqn, uint8_t probe)
|
||||
{
|
||||
|
||||
TRACE_FUNCTION_CALL;
|
||||
LinkDevNode *linkDev = link->k.linkDev;
|
||||
struct lndev_probe_record *lpr = &link->rx_probe_record;
|
||||
|
||||
ASSERTION(-501049, ((sizeof (((struct lndev_probe_record*) NULL)->hello_array)) * 8 == MAX_HELLO_SQN_WINDOW));
|
||||
assertion(-501050, (probe <= 1));
|
||||
ASSERTION(-501055, (bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK) == lpr->hello_sum));
|
||||
|
||||
if ((linkDev->hello_time_max || linkDev->hello_sqn_max) && linkDev->hello_sqn_max != sqn &&
|
||||
((HELLO_SQN_MASK)&(linkDev->hello_sqn_max - sqn)) < HELLO_SQN_TOLERANCE)
|
||||
return;
|
||||
|
||||
|
||||
if (((HELLO_SQN_MASK)&(sqn - lpr->hello_sqn_max)) >= my_link_window) {
|
||||
|
||||
memset(lpr->hello_array, 0, MAX_HELLO_SQN_WINDOW/8);
|
||||
|
||||
ASSERTION(-500159, is_zero(lpr->hello_array, MAX_HELLO_SQN_WINDOW / 8));
|
||||
|
||||
if (probe)
|
||||
bit_set(lpr->hello_array, MAX_HELLO_SQN_WINDOW, sqn, 1);
|
||||
|
||||
lpr->hello_sum = probe;
|
||||
dbgf_all(DBGT_INFO, "probe=%d probe_sum=%d %d",
|
||||
probe, lpr->hello_sum, bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK));
|
||||
|
||||
ASSERTION(-501058, (bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK) == lpr->hello_sum));
|
||||
|
||||
} else {
|
||||
if (sqn != lpr->hello_sqn_max) {
|
||||
HELLO_SQN_T prev_sqn_min = (HELLO_SQN_MASK)&(lpr->hello_sqn_max + 1 - ((HELLO_SQN_T) my_link_window));
|
||||
HELLO_SQN_T new_sqn_min_minus_one = (HELLO_SQN_MASK)&(sqn - ((HELLO_SQN_T) my_link_window));
|
||||
|
||||
dbgf_all(DBGT_INFO, "prev_min=%5d prev_max=%d new_min=%5d sqn=%5d sum=%3d bits=%3d %s",
|
||||
prev_sqn_min,lpr->hello_sqn_max, new_sqn_min_minus_one+1, sqn, lpr->hello_sum,
|
||||
bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK),
|
||||
bits_print(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK));
|
||||
|
||||
lpr->hello_sum -= bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, prev_sqn_min, new_sqn_min_minus_one, HELLO_SQN_MASK);
|
||||
|
||||
dbgf_all(DBGT_INFO, "prev_min=%5d prev_max=%d new_min=%5d sqn=%5d sum=%3d bits=%3d %s",
|
||||
prev_sqn_min,lpr->hello_sqn_max, new_sqn_min_minus_one+1, sqn, lpr->hello_sum,
|
||||
bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK),
|
||||
bits_print(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK));
|
||||
|
||||
bits_clear(lpr->hello_array, MAX_HELLO_SQN_WINDOW, prev_sqn_min, new_sqn_min_minus_one, HELLO_SQN_MASK);
|
||||
|
||||
dbgf_all(DBGT_INFO, "prev_min=%5d prev_max=%d new_min=%5d sqn=%5d sum=%3d bits=%3d %s\n",
|
||||
prev_sqn_min,lpr->hello_sqn_max, new_sqn_min_minus_one+1, sqn, lpr->hello_sum,
|
||||
bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK),
|
||||
bits_print(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK));
|
||||
|
||||
}
|
||||
|
||||
ASSERTION(-501057, (bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK) == lpr->hello_sum));
|
||||
|
||||
if (!bit_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, sqn) && probe) {
|
||||
bit_set(lpr->hello_array, MAX_HELLO_SQN_WINDOW, sqn, 1);
|
||||
lpr->hello_sum++;
|
||||
}
|
||||
|
||||
ASSERTION(-501056, (bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK) == lpr->hello_sum));
|
||||
}
|
||||
|
||||
lpr->hello_sqn_max = sqn;
|
||||
lpr->hello_umetric = (UMETRIC_MAX / my_link_window) * lpr->hello_sum;
|
||||
lpr->hello_time_max = bmx_time;
|
||||
|
||||
linkDev->hello_sqn_max = sqn;
|
||||
linkDev->hello_time_max = bmx_time;
|
||||
|
||||
lndev_assign_best(linkDev->key.local, link);
|
||||
|
||||
dbgf_all(DBGT_INFO, "%s metric %ju", ip6AsStr(&linkDev->key.llocal_ip), link->timeaware_rx_probe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t opt_link_metric(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
static int32_t my_link_window_prev = DEF_HELLO_SQN_WINDOW;
|
||||
|
||||
if (cmd == OPT_APPLY && !strcmp(opt->name, ARG_HELLO_SQN_WINDOW)) {
|
||||
|
||||
LinkNode *link;
|
||||
struct avl_node *an;
|
||||
|
||||
for (an = NULL; (link = avl_iterate_item(&link_tree, &an));) {
|
||||
|
||||
struct lndev_probe_record *lpr = &link->rx_probe_record;
|
||||
|
||||
if (my_link_window < my_link_window_prev) {
|
||||
|
||||
HELLO_SQN_T prev_sqn_min = (HELLO_SQN_MASK)&(lpr->hello_sqn_max + 1 - my_link_window_prev);
|
||||
HELLO_SQN_T new_sqn_min_minus_one = (HELLO_SQN_MASK)&(lpr->hello_sqn_max - my_link_window);
|
||||
|
||||
lpr->hello_sum -= bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, prev_sqn_min, new_sqn_min_minus_one, HELLO_SQN_MASK);
|
||||
bits_clear(lpr->hello_array, MAX_HELLO_SQN_WINDOW, prev_sqn_min, new_sqn_min_minus_one, HELLO_SQN_MASK);
|
||||
}
|
||||
|
||||
assertion(-501053, (bits_get(lpr->hello_array, MAX_HELLO_SQN_WINDOW, 0, MAX_HELLO_SQN_WINDOW - 1, HELLO_SQN_MASK) == lpr->hello_sum));
|
||||
assertion(-501061, (lpr->hello_sum <= ((uint32_t)my_link_window)));
|
||||
|
||||
lpr->hello_umetric = (UMETRIC_MAX / my_link_window) * lpr->hello_sum;
|
||||
}
|
||||
|
||||
|
||||
lndev_assign_best(NULL, NULL);
|
||||
cb_plugin_hooks(PLUGIN_CB_LINKS_EVENT, NULL);
|
||||
|
||||
my_link_window_prev = my_link_window;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int process_dsc_tlv_llip(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
uint8_t op = it->op;
|
||||
|
||||
if (op == TLV_OP_TEST) {
|
||||
|
||||
uint16_t m = 0;
|
||||
struct dsc_msg_llip *msg = (struct dsc_msg_llip *)it->f_data;
|
||||
|
||||
if (it->f_msgs_fixed > DEVIDX_MAX)
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
for (m = 0; m < it->f_msgs_fixed; m++) {
|
||||
|
||||
if (!is_ip_valid(&(msg[m].ip6), AF_INET6))
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
if( !is_ip_net_equal(&(msg[m].ip6), &IP6_LINKLOCAL_UC_PREF, IP6_LINKLOCAL_UC_PLEN, AF_INET6))
|
||||
return TLV_RX_DATA_FAILURE;
|
||||
|
||||
IDM_T TODO_check_for_each_becoming_neighbor_if_llip_is_unused_then_add_linkDev_and_update_neighDevId_otherwise_ignore;
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == TLV_OP_NEW || op == TLV_OP_DEL) && it->on->neigh)
|
||||
updateNeighDevId(it->on->neigh, (op == TLV_OP_NEW ? it->dcNew : NULL));
|
||||
|
||||
|
||||
|
||||
return it->f_msgs_len;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int create_dsc_tlv_llip(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct dsc_msg_llip *msg = (struct dsc_msg_llip *)tx_iterator_cache_msg_ptr(it);
|
||||
int m = 0;
|
||||
struct avl_node *an = NULL;
|
||||
struct dev_node *dev;
|
||||
|
||||
if ((int)(dev_ip_tree.items * sizeof(struct dsc_msg_llip)) > tx_iterator_cache_data_space_pref(it, 0, 0))
|
||||
return TLV_TX_DATA_FULL;
|
||||
|
||||
while ((dev = avl_iterate_item(&dev_ip_tree, &an))) {
|
||||
if (!dev->active || dev->linklayer == TYP_DEV_LL_LO)
|
||||
continue;
|
||||
if (m > 0 && is_ip_equal(&msg[m-1].ip6, &dev->llipKey.llip))
|
||||
continue;
|
||||
msg[m++].ip6 = dev->llipKey.llip;
|
||||
}
|
||||
|
||||
return m * (sizeof(struct dsc_msg_llip));
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_hello_adv(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-500771, (tx_iterator_cache_data_space_pref(it, 0, 0) >= ((int) sizeof(struct msg_hello_adv))));
|
||||
|
||||
struct tx_task_node *ttn = it->ttn;
|
||||
struct msg_hello_adv *adv = (struct msg_hello_adv *) (tx_iterator_cache_msg_ptr(it));
|
||||
|
||||
HELLO_SQN_T sqn_in = ttn->key.f.p.dev->link_hello_sqn = ((HELLO_SQN_MASK)&(ttn->key.f.p.dev->link_hello_sqn + 1));
|
||||
|
||||
adv->hello_sqn = htons(sqn_in);
|
||||
|
||||
dbgf_all(DBGT_INFO, "%s %s SQN %d", ttn->key.f.p.dev->label_cfg.str, ttn->key.f.p.dev->ip_llocal_str, sqn_in);
|
||||
|
||||
return sizeof(struct msg_hello_adv);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_hello_adv(void)
|
||||
{
|
||||
static TIME_T next = 0;
|
||||
|
||||
if (doNowOrLater(&next, txCasualInterval, 0))
|
||||
schedule_tx_task(FRAME_TYPE_HELLO_ADV, NULL, NULL, NULL, SCHEDULE_MIN_MSG_SIZE, 0, 0);
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_msg_hello_adv(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
struct packet_buff *pb = it->pb;
|
||||
assertion(-502427, (pb->i.verifiedLink));
|
||||
LinkNode *link = pb->i.verifiedLink;
|
||||
struct msg_hello_adv *msg = (struct msg_hello_adv*) (it->f_msg);
|
||||
HELLO_SQN_T hello_sqn = ntohs(msg->hello_sqn);
|
||||
DEVIDX_T devIdx = link->k.linkDev->key.devIdx;
|
||||
char *goto_error_code = NULL;
|
||||
int goto_error_ret = TLV_RX_DATA_PROCESSED;
|
||||
|
||||
if (devIdx < DEVIDX_MIN || devIdx > DEVIDX_MAX) {
|
||||
goto_error_return( finish, "Invalid LinkDevIdx!", TLV_RX_DATA_FAILURE);
|
||||
}
|
||||
|
||||
update_link_probe_record(link, hello_sqn, 1);
|
||||
|
||||
finish:
|
||||
dbgf_mute(10, goto_error_code ? DBGL_SYS : DBGL_ALL, goto_error_code ? DBGT_ERR : DBGT_INFO,
|
||||
"NB=%s via llip=%s dev=%s SQN=%d linkDevIdx=%d problem=%s",
|
||||
cryptShaAsShortStr(&pb->p.hdr.keyHash), pb->i.llip_str, pb->i.iif->label_cfg.str, hello_sqn, devIdx, goto_error_code);
|
||||
|
||||
return goto_error_ret;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_hello_reply(void)
|
||||
{
|
||||
LinkNode *link;
|
||||
struct avl_node *an = NULL;
|
||||
|
||||
while ((link = avl_iterate_item(&link_tree, &an))) {
|
||||
|
||||
schedule_tx_task(ogmIid ? FRAME_TYPE_HELLO_REPLY_IID : FRAME_TYPE_HELLO_REPLY_DHASH, &link->k.linkDev->key.local->local_id,
|
||||
link->k.linkDev->key.local, link->k.myDev, SCHEDULE_MIN_MSG_SIZE, &link->k.linkDev->key.devIdx, sizeof(DEVIDX_T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_hello_reply(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
DEVIDX_T *nbDevIdx = ((DEVIDX_T*) it->ttn->key.data);
|
||||
struct neigh_node *neigh = it->ttn->neigh;
|
||||
LinkDevNode *ldn = avl_find_item(&neigh->linkDev_tree, nbDevIdx);
|
||||
LinkKey lk = {.linkDev = ldn, .myDev = it->ttn->key.f.p.dev};
|
||||
LinkNode *link = ldn ? avl_find_item(&link_tree, &lk) : NULL;
|
||||
|
||||
if (!link || !ldn || ldn->key.devIdx < DEVIDX_MIN) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "yet unestablished devIdx=%d link=%p ldn=%p dev=%p neigh=%p for neigh=%s llip=%s dev=%s",
|
||||
(ldn ? ldn->key.devIdx : 0), link, ldn, lk.myDev, neigh, cryptShaAsString(&neigh->local_id),
|
||||
ip6AsStr(&ldn->key.llocal_ip), (lk.myDev ? lk.myDev->label_cfg.str : NULL));
|
||||
|
||||
return TLV_TX_DATA_DONE;
|
||||
}
|
||||
|
||||
if (ogmIid && it->frame_type == FRAME_TYPE_HELLO_REPLY_IID) {
|
||||
/*
|
||||
struct msg_hello_reply_iid* msg = ((struct msg_hello_reply_iid*) tx_iterator_cache_msg_ptr(it));
|
||||
msg->dest_transmitterIid4x = neigh->on->dhn->myIID4orig;
|
||||
msg->u.d.receiverDevId = ldn->neighDevId;
|
||||
msg->u.d.rxLq_63range = (link->timeaware_rx_probe * 63) / UMETRIC_MAX;
|
||||
msg->u.u16 = htons(msg->u.u16);
|
||||
return sizeof(struct msg_hello_reply_iid);
|
||||
*/
|
||||
} else if (!ogmIid && it->frame_type == FRAME_TYPE_HELLO_REPLY_DHASH) {
|
||||
|
||||
struct msg_hello_reply_dhash* msg = ((struct msg_hello_reply_dhash*) tx_iterator_cache_msg_ptr(it));
|
||||
msg->dest_dhash = neigh->on->descContent->dhn->dhash;
|
||||
msg->u.d.receiverDevIdx = ldn->key.devIdx;
|
||||
msg->u.d.rxLq_63range = (link->timeaware_rx_probe * 63) / UMETRIC_MAX;
|
||||
msg->u.u16 = htons(msg->u.u16);
|
||||
|
||||
neigh->on->descContent->dhn->referred_by_me_timestamp = bmx_time;
|
||||
|
||||
return sizeof(struct msg_hello_reply_dhash);
|
||||
}
|
||||
|
||||
return TLV_TX_DATA_DONE;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_msg_hello_reply(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
struct packet_buff *pb = it->pb;
|
||||
assertion(-502431, (pb->i.verifiedLink));
|
||||
|
||||
struct msg_hello_reply_dhash msg;
|
||||
|
||||
if (!ogmIid && it->f_type == FRAME_TYPE_HELLO_REPLY_DHASH) {
|
||||
if (!cryptShasEqual(&(((struct msg_hello_reply_dhash *) it->f_msg)->dest_dhash), &myKey->currOrig->descContent->dhn->dhash))
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
msg.u.u16 = ntohs(((struct msg_hello_reply_dhash *) it->f_msg)->u.u16);
|
||||
} else if (ogmIid && it->f_type == FRAME_TYPE_HELLO_REPLY_IID) {
|
||||
/*
|
||||
if (self->dhn != iid_get_node_by_neighIID4x(neigh, ((struct msg_hello_reply_iid *) it->f_msg)->dest_transmitterIid4x))
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
msg.u.u16 = ntohs(((struct msg_hello_reply_iid *) it->f_msg)->u.u16);
|
||||
*/
|
||||
} else {
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
LinkNode *link = pb->i.verifiedLink;
|
||||
struct neigh_node *neigh = link->k.linkDev->key.local;
|
||||
|
||||
if (msg.u.d.receiverDevIdx != link->k.myDev->llipKey.devIdx)
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
|
||||
link->rp_time_max = bmx_time;
|
||||
link->tx_probe_umetric = (UMETRIC_MAX * ((UMETRIC_T) (msg.u.d.rxLq_63range))) / 63;
|
||||
lndev_assign_best(neigh, link);
|
||||
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct link_status {
|
||||
GLOBAL_ID_T *shortId;
|
||||
GLOBAL_ID_T *globalId;
|
||||
char* name;
|
||||
IPX_T neighLocalIp;
|
||||
uint16_t neighIdx;
|
||||
IPX_T localIp;
|
||||
IFNAME_T dev;
|
||||
uint16_t idx;
|
||||
uint8_t rxRate;
|
||||
uint8_t bestRxLink;
|
||||
uint8_t txRate;
|
||||
uint8_t bestTxLink;
|
||||
uint8_t routes;
|
||||
AGGREG_SQN_T aggSqnSize;
|
||||
AGGREG_SQN_T aggSqnMax;
|
||||
uint8_t aggSqnRcvd;
|
||||
HELLO_SQN_T lastHelloSqn;
|
||||
TIME_T lastHelloAdv;
|
||||
};
|
||||
|
||||
static const struct field_format link_status_format[] = {
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_SHORT_ID, link_status, shortId, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_GLOBAL_ID, link_status, globalId, 1, FIELD_RELEVANCE_LOW),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_CHAR, link_status, name, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_IPX, link_status, neighLocalIp, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, neighIdx, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_IPX, link_status, localIp, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_STRING_CHAR, link_status, dev, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, idx, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, rxRate, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, bestRxLink, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, txRate, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, bestTxLink, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, routes, 1, FIELD_RELEVANCE_HIGH),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, aggSqnSize, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, aggSqnMax, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, aggSqnRcvd, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, lastHelloSqn, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_INIT(FIELD_TYPE_UINT, link_status, lastHelloAdv, 1, FIELD_RELEVANCE_MEDI),
|
||||
FIELD_FORMAT_END
|
||||
};
|
||||
|
||||
static int32_t link_status_creator(struct status_handl *handl, void *data)
|
||||
{
|
||||
struct avl_node *linkDev_it, *local_it;
|
||||
LinkDevNode *linkDev;
|
||||
struct neigh_node *local;
|
||||
uint32_t max_size = link_tree.items * sizeof (struct link_status);
|
||||
uint32_t i = 0;
|
||||
|
||||
struct link_status *status = ((struct link_status*) (handl->data = debugRealloc(handl->data, max_size, -300358)));
|
||||
memset(status, 0, max_size);
|
||||
|
||||
for (local_it = NULL; (local = avl_iterate_item(&local_tree, &local_it));) {
|
||||
|
||||
struct orig_node *on = local->on;
|
||||
assertion(-502210, (on));
|
||||
for (linkDev_it = NULL; (linkDev = avl_iterate_item(&local->linkDev_tree, &linkDev_it));) {
|
||||
|
||||
LinkNode *link = NULL;
|
||||
while ((link = avl_next_item(&linkDev->link_tree, (link ? &link->k : NULL)))) {
|
||||
|
||||
status[i].globalId = &on->k.nodeId;
|
||||
status[i].shortId = &on->k.nodeId;
|
||||
status[i].name = on->k.hostname;
|
||||
status[i].neighLocalIp = linkDev->key.llocal_ip;
|
||||
status[i].neighIdx = linkDev->key.devIdx;
|
||||
status[i].dev = link->k.myDev->label_cfg;
|
||||
status[i].idx = link->k.myDev->llipKey.devIdx;
|
||||
status[i].localIp = link->k.myDev->llipKey.llip;
|
||||
status[i].rxRate = ((link->timeaware_rx_probe * 100) / UMETRIC_MAX);
|
||||
status[i].bestRxLink = (link == local->best_rp_link);
|
||||
status[i].txRate = ((link->timeaware_tx_probe * 100) / UMETRIC_MAX);
|
||||
status[i].bestTxLink = (link == local->best_tp_link);
|
||||
status[i].routes = link->orig_routes;
|
||||
status[i].aggSqnSize = local->ogm_aggreg_size;
|
||||
status[i].aggSqnMax = local->ogm_aggreg_max;
|
||||
status[i].aggSqnRcvd = bit_get(local->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE, local->ogm_aggreg_max);
|
||||
status[i].lastHelloSqn = linkDev->hello_sqn_max;
|
||||
status[i].lastHelloAdv = ((TIME_T) (bmx_time - linkDev->hello_time_max)) / 1000;
|
||||
|
||||
i++;
|
||||
assertion(-501225, (max_size >= i * sizeof (struct link_status)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i * sizeof (struct link_status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
struct opt_type link_options[]=
|
||||
{
|
||||
{ODI,0,ARG_LINKS, 0, 9,1,A_PS0N,A_USR,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0,0, opt_status,
|
||||
0, "show links\n"},
|
||||
{ODI,0,ARG_HELLO_SQN_WINDOW, 0, 9,1,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_link_window, MIN_HELLO_SQN_WINDOW, MAX_HELLO_SQN_WINDOW,DEF_HELLO_SQN_WINDOW,0, opt_link_metric,
|
||||
ARG_VALUE_FORM, "set link window size (LWS) for link-quality calculation (link metric)"}
|
||||
};
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t init_link( void )
|
||||
{
|
||||
register_options_array(link_options, sizeof (link_options), CODE_CATEGORY_NAME);
|
||||
register_status_handl(sizeof(struct link_status), 1, link_status_format, ARG_LINKS, link_status_creator);
|
||||
|
||||
struct frame_handl handl;
|
||||
memset(&handl, 0, sizeof( handl));
|
||||
|
||||
static const struct field_format llip_format[] = DESCRIPTION_MSG_LLIP_FORMAT;
|
||||
handl.name = "DSC_LLIP";
|
||||
handl.min_msg_size = sizeof(struct dsc_msg_llip);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.positionMandatory = 0;
|
||||
handl.dextCompression = (int32_t*) & dflt_fzip;
|
||||
handl.dextReferencing = (int32_t*) & fref_dflt;
|
||||
handl.tx_frame_handler = create_dsc_tlv_llip;
|
||||
handl.rx_frame_handler = process_dsc_tlv_llip;
|
||||
handl.msg_format = llip_format;
|
||||
register_frame_handler(description_tlv_db, BMX_DSC_TLV_LLIP, &handl);
|
||||
|
||||
handl.name = "HELLO_ADV";
|
||||
handl.min_msg_size = sizeof(struct msg_hello_adv);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_packet_prepare_casuals = schedule_hello_adv;
|
||||
handl.tx_msg_handler = tx_msg_hello_adv;
|
||||
handl.rx_msg_handler = rx_msg_hello_adv;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_HELLO_ADV, &handl);
|
||||
|
||||
handl.name = "HELLO_REPLY";
|
||||
handl.min_msg_size = sizeof (struct msg_hello_reply_dhash);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_packet_prepare_casuals = schedule_hello_reply;
|
||||
handl.tx_msg_handler = tx_msg_hello_reply;
|
||||
handl.rx_msg_handler = rx_msg_hello_reply;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_HELLO_REPLY_DHASH, &handl);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void cleanup_link( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct plugin *link_get_plugin( void ) {
|
||||
|
||||
static struct plugin link_plugin;
|
||||
memset( &link_plugin, 0, sizeof ( struct plugin ) );
|
||||
|
||||
link_plugin.plugin_name = CODE_CATEGORY_NAME;
|
||||
link_plugin.plugin_size = sizeof ( struct plugin );
|
||||
link_plugin.cb_init = init_link;
|
||||
link_plugin.cb_cleanup = cleanup_link;
|
||||
|
||||
return &link_plugin;
|
||||
}
|
||||
|
48
link.h
Normal file
48
link.h
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
#define DEF_LINK_METRIC_FLAGS (0x0)
|
||||
#define ARG_LINK_METRIC_FLAGS "linkMetricFlags"
|
||||
|
||||
#define ARG_LINKS "links"
|
||||
|
||||
|
||||
|
||||
struct dsc_msg_llip {
|
||||
IP6_T ip6;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DESCRIPTION_MSG_LLIP_FORMAT { \
|
||||
{FIELD_TYPE_IPX6, -1, 128, 1, FIELD_RELEVANCE_HIGH, "address" }, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct msg_hello_adv { // 2 bytes
|
||||
HELLO_SQN_T hello_sqn;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct msg_hello_reply_data {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int rxLq_63range : 6;
|
||||
unsigned int receiverDevIdx : DEVIDX_BITS;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int receiverDevIdx : DEVIDX_BITS;
|
||||
unsigned int rxLq_63range : 6;
|
||||
#else
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
|
||||
struct msg_hello_reply_dhash {
|
||||
DHASH_T dest_dhash;
|
||||
|
||||
union {
|
||||
struct msg_hello_reply_data d;
|
||||
uint16_t u16;
|
||||
} u;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
//IDM_T updateNeighDevId(struct neigh_node *nn, struct desc_content *contents);
|
||||
LinkNode *getLinkNode(struct dev_node *dev, IPX_T *llip, DEVIDX_T idx, struct neigh_node *verifiedNeigh);
|
||||
void purge_linkDevs(LinkDevKey *onlyLinkDev, struct dev_node *only_dev, IDM_T purgeLocal);
|
||||
|
||||
struct plugin *link_get_plugin(void);
|
118
metrics.h
118
metrics.h
@@ -22,8 +22,6 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define MIN_DESC_METRICALGO 0
|
||||
#define MAX_DESC_METRICALGO 1
|
||||
#define DEF_DESC_METRICALGO 1
|
||||
@@ -76,64 +74,46 @@
|
||||
#define ARG_PATH_TP_EXP_DIVISOR "txExpDivisor"
|
||||
#define CHR_PATH_TP_EXP_DIVISOR 't'
|
||||
|
||||
#define MAX_PATH_WINDOW 250 /* 250 TBD: should not be larger until ogm->ws and neigh_node.packet_count (and related variables) is only 8 bit */
|
||||
#define MIN_PATH_WINDOW 1
|
||||
#define DEF_PATH_WINDOW 5 /* NBRF: NeighBor Ranking sequence Frame) sliding packet range of received orginator messages in squence numbers (should be a multiple of our word size) */
|
||||
#define ARG_PATH_WINDOW "pathWindow"
|
||||
//extern int32_t my_path_window; // my path window size used to quantify the end to end path quality between me and other nodes
|
||||
#define MIN_PATH_LQ_TX_R255 0
|
||||
#define MAX_PATH_LQ_TX_R255 254
|
||||
#define DEF_PATH_LQ_TX_R255 ((255*2)/3)
|
||||
#define ARG_PATH_LQ_TX_R255 "pathLqXThreshold"
|
||||
|
||||
#define MIN_PATH_LOUNGE 0
|
||||
#define MAX_PATH_LOUNGE 10
|
||||
#define DEF_PATH_LOUNGE 1
|
||||
#define ARG_PATH_LOUNGE "pathLounge"
|
||||
//extern int32_t my_path_lounge;
|
||||
#define MIN_PATH_LQ_TY_R255 0
|
||||
#define MAX_PATH_LQ_TY_R255 254
|
||||
#define DEF_PATH_LQ_TY_R255 ((255*1)/3)
|
||||
#define ARG_PATH_LQ_TY_R255 "pathLqYThreshold"
|
||||
|
||||
|
||||
#define DEF_PATH_REGRESSION_SLOW 1
|
||||
#define MIN_PATH_REGRESSION_SLOW 1
|
||||
#define MAX_PATH_REGRESSION_SLOW 255
|
||||
#define ARG_PATH_REGRESSION_SLOW "pathRegression"
|
||||
#define MIN_PATH_LQ_T1_R255 1
|
||||
#define MAX_PATH_LQ_T1_R255 255
|
||||
#define DEF_PATH_LQ_T1_R255 ((255*9)/10)
|
||||
#define ARG_PATH_LQ_T1_R255 "pathLq1Threshold"
|
||||
|
||||
|
||||
|
||||
//#define RP_LINK_LOUNGE 0 /* may also be rtq_link_lounge */
|
||||
|
||||
/*
|
||||
// this deactivates OGM-Acks on the link:
|
||||
#define MIN_LINK_IGNORE_MIN 0
|
||||
#define MAX_LINK_IGNORE_MIN 100
|
||||
#define DEF_LINK_IGNORE_MIN 50
|
||||
#define ARG_LINK_IGNORE_MIN "link_ignore_min"
|
||||
//extern int32_t link_ignore_min;
|
||||
|
||||
// this activates OGM-Acks on the link:
|
||||
#define MIN_LINK_IGNORE_MAX 0
|
||||
#define MAX_LINK_IGNORE_MAX 255
|
||||
#define DEF_LINK_IGNORE_MAX 100
|
||||
#define ARG_LINK_IGNORE_MAX "link_ignore_max"
|
||||
//extern int32_t link_ignore_max;
|
||||
*/
|
||||
|
||||
|
||||
#define MIN_PATH_HYST 0
|
||||
#define MAX_PATH_HYST 255
|
||||
#define DEF_PATH_HYST 0
|
||||
#define ARG_PATH_HYST "pathHysteresis"
|
||||
#define MIN_OGM_METRIC_HYST 0
|
||||
#define MAX_OGM_METRIC_HYST 64000
|
||||
#define DEF_OGM_METRIC_HYST 10
|
||||
#define ARG_OGM_METRIC_HYST "pathMetricHysteresis"
|
||||
//extern int32_t my_path_hystere;
|
||||
|
||||
#define MIN_OGM_SQN_LATE_HYST 0
|
||||
#define MAX_OGM_SQN_LATE_HYST 64000
|
||||
#define DEF_OGM_SQN_LATE_HYST 2500
|
||||
#define ARG_OGM_SQN_LATE_HYST "pathLateHysteresis"
|
||||
|
||||
#define MIN_LATE_PENAL 0
|
||||
#define MAX_LATE_PENAL 100
|
||||
#define DEF_LATE_PENAL 1
|
||||
#define ARG_LATE_PENAL "latenessPenalty"
|
||||
//extern int32_t my_late_penalty;
|
||||
#define MIN_OGM_SQN_BEST_HYST 0
|
||||
#define MAX_OGM_SQN_BEST_HYST 255
|
||||
#define DEF_OGM_SQN_BEST_HYST 5
|
||||
#define ARG_OGM_SQN_BEST_HYST "pathSqnBestHysteresis"
|
||||
|
||||
|
||||
#define DEF_HOP_PENALTY 0 //(U8_MAX/20) <=> 5% penalty on metric per hop
|
||||
#define MIN_HOP_PENALTY 0 // smaller values than 4 do not show effect
|
||||
#define MAX_HOP_PENALTY U8_MAX
|
||||
#define ARG_HOP_PENALTY "hopPenalty"
|
||||
#define MAX_HOP_PENALTY_PRECISION_EXP 8
|
||||
|
||||
#define DEF_OGM_HOP_PENALTY 0 //(U8_MAX/20) <=> 5% penalty on metric per hop
|
||||
#define MIN_OGM_HOP_PENALTY 0 // smaller values than 4 do not show effect
|
||||
#define MAX_OGM_HOP_PENALTY U8_MAX
|
||||
#define ARG_OGM_HOP_PENALTY "pathHopPenalty"
|
||||
#define MAX_OGM_HOP_PENALTY_PRECISION_EXP 8
|
||||
//extern int32_t my_hop_penalty;
|
||||
|
||||
|
||||
@@ -162,9 +142,6 @@
|
||||
#define DEF_PATH_METRIC_FLAGS (0x0)
|
||||
#define ARG_PATH_METRIC_FLAGS "pathMetricFlags"
|
||||
|
||||
#define DEF_LINK_METRIC_FLAGS (0x0)
|
||||
#define ARG_LINK_METRIC_FLAGS "linkMetricFlags"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -189,16 +166,17 @@ struct mandatory_tlv_metricalgo { // 16 bytes
|
||||
unsigned int tp_exp_numerator : 2;
|
||||
unsigned int tp_exp_divisor : 2;
|
||||
#else
|
||||
# error "Please fix <bits/endian.h>"
|
||||
#error "Please fix <bits/endian.h>"
|
||||
#endif
|
||||
|
||||
uint8_t reserved2; // 1 byte
|
||||
uint8_t path_window_size; // 1 byte
|
||||
uint8_t path_lounge_size; // 1 byte
|
||||
uint8_t regression; // 1 byte
|
||||
uint8_t hystere; // 1 byte
|
||||
uint8_t hop_penalty; // 1 byte
|
||||
uint8_t late_penalty; // 1 byte
|
||||
uint8_t lq_tx_point_r255;
|
||||
uint8_t lq_ty_point_r255;
|
||||
uint8_t lq_t1_point_r255;
|
||||
|
||||
uint8_t hop_penalty; // 1 byte
|
||||
uint8_t ogm_sqn_best_hystere;
|
||||
uint16_t ogm_sqn_late_hystere;
|
||||
uint16_t ogm_metric_hystere; // 2 byte
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -217,13 +195,13 @@ struct description_tlv_metricalgo {
|
||||
{FIELD_TYPE_UINT, -1, 2, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_RP_EXP_DIVISOR }, \
|
||||
{FIELD_TYPE_UINT, -1, 2, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_TP_EXP_NUMERATOR }, \
|
||||
{FIELD_TYPE_UINT, -1, 2, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_TP_EXP_DIVISOR }, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_LOW, "reserved2"}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_WINDOW}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_LOUNGE}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_REGRESSION_SLOW}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_LOW , ARG_PATH_HYST}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_HOP_PENALTY}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_LOW , ARG_LATE_PENAL}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_LQ_TX_R255}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_LQ_TY_R255}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_PATH_LQ_T1_R255}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_OGM_HOP_PENALTY}, \
|
||||
{FIELD_TYPE_UINT, -1, 8, 1, FIELD_RELEVANCE_HIGH, ARG_OGM_SQN_BEST_HYST}, \
|
||||
{FIELD_TYPE_UINT, -1, 16, 1, FIELD_RELEVANCE_HIGH, ARG_OGM_SQN_LATE_HYST}, \
|
||||
{FIELD_TYPE_UINT, -1, 16, 1, FIELD_RELEVANCE_HIGH, ARG_OGM_METRIC_HYST}, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
|
||||
@@ -231,7 +209,6 @@ extern struct host_metricalgo link_rp_metric_algo;
|
||||
|
||||
|
||||
extern UMETRIC_T UMETRIC_NBDISCOVERY_MIN;
|
||||
extern UMETRIC_T TX_UMETRIC_OGM_ACK_MIN;
|
||||
|
||||
|
||||
|
||||
@@ -258,9 +235,8 @@ IDM_T fmetric_cmp(FMETRIC_U16_T a, unsigned char cmp, FMETRIC_U16_T b);
|
||||
//void apply_metric_algo(UMETRIC_T *out, struct link_dev_node *link, const UMETRIC_T *path, struct host_metricalgo *algo);
|
||||
|
||||
UMETRIC_T apply_metric_algo(UMETRIC_T *tr, UMETRIC_T *umetric_max, const UMETRIC_T *path, struct host_metricalgo *algo);
|
||||
UMETRIC_T apply_lndev_metric_algo(LinkNode *link, const UMETRIC_T *path, struct host_metricalgo *algo);
|
||||
|
||||
void lndev_assign_best(struct neigh_node *onlyLocal, LinkNode *onlyLink );
|
||||
void update_link_probe_record(LinkNode *link, HELLO_SQN_T sqn, uint8_t probe);
|
||||
|
||||
IDM_T update_path_metrics(struct packet_buff *pb, struct orig_node *on, OGM_SQN_T in_sqn, UMETRIC_T *in_umetric);
|
||||
|
||||
|
460
node.h
460
node.h
@@ -23,43 +23,18 @@
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* from iid.h:
|
||||
*/
|
||||
typedef uint16_t IID_T;
|
||||
typedef struct neigh_node IID_NEIGH_T;
|
||||
typedef struct dhash_node IID_NODE_T;
|
||||
|
||||
|
||||
#define IID_REPOS_SIZE_BLOCK 32
|
||||
|
||||
#define IID_REPOS_SIZE_MAX ((IID_T)(-1))
|
||||
#define IID_REPOS_SIZE_WARN 1024
|
||||
|
||||
#define IID_RSVD_UNUSED 0
|
||||
#define IID_RSVD_MAX 0
|
||||
#define IID_MIN_USED 1
|
||||
|
||||
#define IID_SPREAD_FK 1 /*default=2 , 1 means no spreading #define IID_REPOS_USAGE_WARNING 10 */
|
||||
|
||||
|
||||
struct iid_ref {
|
||||
IID_T myIID4x;
|
||||
uint16_t referred_by_neigh_timestamp_sec;
|
||||
};
|
||||
|
||||
struct iid_repos {
|
||||
IID_T arr_size; // the number of allocated array fields
|
||||
IID_T min_free; // the first unused array field from the beginning of the array (might be outside of allocated space)
|
||||
IID_T max_free; // the first unused array field after the last used field in the array (might be outside of allocated space)
|
||||
IID_T tot_used; // the total number of used fields in the array
|
||||
union {
|
||||
uint8_t *u8;
|
||||
IID_NODE_T **node;
|
||||
struct iid_ref *ref;
|
||||
} arr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -113,6 +88,7 @@ typedef uint64_t UMETRIC_T;
|
||||
struct float_u16 {
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
uint8_t mantissa_fm16;
|
||||
@@ -128,15 +104,14 @@ struct float_u16 {
|
||||
uint8_t u8[2];
|
||||
|
||||
uint16_t u16;
|
||||
}val;
|
||||
} val;
|
||||
};
|
||||
|
||||
|
||||
typedef struct float_u16 FMETRIC_U16_T;
|
||||
|
||||
|
||||
|
||||
struct float_u8 {
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
@@ -158,9 +133,7 @@ typedef struct float_u8 FMETRIC_U8_T;
|
||||
|
||||
typedef uint16_t ALGO_T;
|
||||
|
||||
|
||||
struct host_metricalgo {
|
||||
|
||||
FMETRIC_U16_T fmetric_u16_min;
|
||||
|
||||
UMETRIC_T umetric_min;
|
||||
@@ -171,37 +144,35 @@ struct host_metricalgo {
|
||||
uint8_t algo_tp_exp_numerator;
|
||||
uint8_t algo_tp_exp_divisor;
|
||||
|
||||
uint8_t lq_tx_point_r255;
|
||||
uint8_t lq_ty_point_r255;
|
||||
uint8_t lq_t1_point_r255;
|
||||
|
||||
uint8_t window_size; // MUST be given as multiple of sqn_steps
|
||||
uint8_t lounge_size; // MUST be given as multiple of sqn_steps e.g. 6
|
||||
uint8_t regression; // e.g. 16
|
||||
// uint8_t fast_regression; // e.g. 2
|
||||
// uint8_t fast_regression_impact; // e.g. 8
|
||||
uint8_t hystere;
|
||||
uint8_t hop_penalty;
|
||||
uint8_t late_penalty;
|
||||
uint8_t ogm_hop_penalty;
|
||||
uint8_t ogm_sqn_best_hystere;
|
||||
uint16_t ogm_sqn_late_hystere;
|
||||
uint16_t ogm_metric_hystere;
|
||||
};
|
||||
|
||||
struct lndev_probe_record {
|
||||
HELLO_SQN_T hello_sqn_max; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NOT be set again!
|
||||
|
||||
uint8_t hello_array[MAX_HELLO_SQN_WINDOW/8];
|
||||
uint8_t hello_array[MAX_HELLO_SQN_WINDOW / 8];
|
||||
uint32_t hello_sum;
|
||||
UMETRIC_T hello_umetric;
|
||||
TIME_T hello_time_max;
|
||||
};
|
||||
|
||||
|
||||
struct metric_record {
|
||||
SQN_T sqn_bit_mask;
|
||||
|
||||
SQN_T clr; // SQN upto which waightedAverageVal has been purged
|
||||
SQN_T clr; // SQN upto which waightedAverageVal has been purged
|
||||
SQN_T set; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NOT be set again!
|
||||
|
||||
// UMETRIC_T umetric;
|
||||
// UMETRIC_T umetric_fast;
|
||||
// UMETRIC_T umetric;
|
||||
// UMETRIC_T umetric_fast;
|
||||
UMETRIC_T umetric;
|
||||
// UMETRIC_T umetric_prev;
|
||||
// UMETRIC_T umetric_prev;
|
||||
};
|
||||
|
||||
#define ZERO_METRIC_RECORD {0, 0, 0, 0,0,0}
|
||||
@@ -210,7 +181,6 @@ struct metric_record {
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* from node.h:
|
||||
*/
|
||||
@@ -220,43 +190,42 @@ typedef CRYPTSHA1_T DHASH_T;
|
||||
typedef CRYPTSHA1_T RHASH_T;
|
||||
|
||||
|
||||
#define DEF_LINK_PURGE_TO 100000
|
||||
#define MIN_LINK_PURGE_TO (MAX_TX_INTERVAL*2)
|
||||
#define MAX_LINK_PURGE_TO 864000000 /*10 days*/
|
||||
#define ARG_LINK_PURGE_TO "linkPurgeTimeout"
|
||||
|
||||
#define MIN_OGM_PURGE_TO (MAX_OGM_INTERVAL + MAX_TX_INTERVAL)
|
||||
#define MAX_OGM_PURGE_TO 864000000 /*10 days*/
|
||||
#define DEF_OGM_PURGE_TO 100000
|
||||
#define ARG_OGM_PURGE_TO "purgeTimeout"
|
||||
|
||||
|
||||
typedef CRYPTSHA1_T GLOBAL_ID_T;
|
||||
|
||||
typedef CRYPTSHA1_T LOCAL_ID_T;
|
||||
|
||||
typedef uint16_t DEVIDX_T;
|
||||
#define DEVIDX_INVALID 0
|
||||
#define DEVIDX_MIN 1
|
||||
#define DEVIDX_BITS 10
|
||||
#define DEVIDX_MASK ((1<<DEVIDX_BITS)-1)
|
||||
#define DEVIDX_MAX DEVIDX_MASK
|
||||
|
||||
typedef struct {
|
||||
DEVADV_IDX_T dev_idx;
|
||||
LOCAL_ID_T local_id;
|
||||
LOCAL_IP_T llip;
|
||||
DEVIDX_T devIdx;
|
||||
} __attribute__((packed)) DevKey;
|
||||
|
||||
typedef struct {
|
||||
LOCAL_IP_T llocal_ip;
|
||||
DEVIDX_T devIdx;
|
||||
struct neigh_node *local; // set immediately
|
||||
} __attribute__((packed)) LinkDevKey;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
LinkDevKey key;
|
||||
|
||||
IPX_T link_ip;
|
||||
uint8_t purge;
|
||||
|
||||
TIME_T pkt_time_max;
|
||||
TIME_T hello_time_max;
|
||||
|
||||
HELLO_SQN_T hello_sqn_max;
|
||||
|
||||
struct neigh_node *local; // set immediately
|
||||
|
||||
struct list_head link_list; // list with one link_node_dev element per link
|
||||
struct avl_tree link_tree;
|
||||
} LinkDevNode;
|
||||
|
||||
|
||||
typedef struct {
|
||||
LinkDevNode *linkDev;
|
||||
struct dev_node *myDev;
|
||||
@@ -270,176 +239,134 @@ typedef struct {
|
||||
UMETRIC_T timeaware_tx_probe;
|
||||
struct lndev_probe_record rx_probe_record;
|
||||
UMETRIC_T timeaware_rx_probe;
|
||||
int32_t orig_routes;
|
||||
|
||||
struct list_head tx_task_lists[FRAME_TYPE_ARRSZ]; // scheduled frames and messages
|
||||
int16_t myLinkId;
|
||||
TIME_T pkt_time_max;
|
||||
|
||||
TIME_T rp_time_max;
|
||||
} LinkNode;
|
||||
|
||||
|
||||
struct neigh_node {
|
||||
|
||||
LOCAL_ID_T local_id;
|
||||
struct avl_tree linkDev_tree;
|
||||
LinkNode *best_rp_link;
|
||||
LinkNode *best_tp_link;
|
||||
LinkNode *best_link;
|
||||
|
||||
TIME_T packet_time;
|
||||
LINKADV_SQN_T packet_link_sqn_ref; //indicating the maximum existing link_adv_sqn
|
||||
BURST_SQN_T burstSqn;
|
||||
|
||||
// the latest received link_adv:
|
||||
LINKADV_SQN_T link_adv_sqn;
|
||||
TIME_T link_adv_time;
|
||||
uint16_t link_adv_msgs;
|
||||
int16_t neighLinkId;
|
||||
int16_t myLinkId;
|
||||
OGM_DEST_T internalNeighId;
|
||||
|
||||
struct msg_link_adv *link_adv;
|
||||
DEVADV_SQN_T link_adv_dev_sqn_ref;
|
||||
INT_NEIGH_ID_T internalNeighId;
|
||||
|
||||
// the latest received dev_adv:
|
||||
DEVADV_SQN_T dev_adv_sqn;
|
||||
uint16_t dev_adv_msgs;
|
||||
struct msg_dev_adv *dev_adv;
|
||||
|
||||
// the latest received rp_adv:
|
||||
TIME_T rp_adv_time;
|
||||
IDM_T rp_ogm_request_rcvd;
|
||||
int32_t orig_routes;
|
||||
|
||||
|
||||
struct orig_node *on;
|
||||
// the old neigh_node:
|
||||
struct dhash_node *dhn; //TODO remove and use on;
|
||||
CRYPTKEY_T *pktKey;
|
||||
|
||||
IID_T neighIID4me;
|
||||
struct orig_node *on;
|
||||
CRYPTKEY_T *pktKey;
|
||||
|
||||
struct iid_repos neighIID4x_repos;
|
||||
|
||||
TIME_T ogm_new_aggregation_rcvd;
|
||||
AGGREG_SQN_T ogm_aggregation_cleard_max;
|
||||
uint8_t ogm_aggregations_not_acked[AGGREG_ARRAY_BYTE_SIZE];
|
||||
uint8_t ogm_aggregations_rcvd[AGGREG_ARRAY_BYTE_SIZE];
|
||||
|
||||
struct avl_tree refsByDhash_tree;
|
||||
struct avl_tree refsByKhash_tree;
|
||||
|
||||
TIME_T ogm_aggreg_time;
|
||||
AGGREG_SQN_T ogm_aggreg_max;
|
||||
AGGREG_SQN_T ogm_aggreg_size;
|
||||
uint8_t ogm_aggreg_sqns[(AGGREG_SQN_CACHE_RANGE / 8)];
|
||||
};
|
||||
|
||||
struct content_usage_node {
|
||||
|
||||
struct {
|
||||
uint32_t expanded_type;
|
||||
struct content_node *content;
|
||||
struct desc_content *descContent;
|
||||
} __attribute__((packed)) k;
|
||||
|
||||
|
||||
struct router_node {
|
||||
|
||||
// struct link_dev_key key_2BRemoved;
|
||||
|
||||
struct neigh_node *local_key;
|
||||
|
||||
struct metric_record mr;
|
||||
OGM_SQN_T ogm_sqn_last;
|
||||
UMETRIC_T ogm_umetric_last;
|
||||
|
||||
UMETRIC_T best_path_metric; //TODO removed
|
||||
LinkNode *best_path_link;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct dext_tree_key {
|
||||
struct desc_extension *dext;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dext_tree_node {
|
||||
struct dext_tree_key dext_key;
|
||||
uint8_t rf_types[(BMX_DSC_TLV_ARRSZ/8) + (BMX_DSC_TLV_ARRSZ%8)];
|
||||
uint8_t maxUsedLevel;
|
||||
uint8_t maxAllowedLevel;
|
||||
uint16_t dup;
|
||||
};
|
||||
|
||||
#define MAX_DESC_LEN (INT32_MAX-1)
|
||||
#define MAX_REF_NESTING 2
|
||||
|
||||
struct ref_node {
|
||||
SHA1_T rhash;
|
||||
//struct frame_header_long *frame_hdr;
|
||||
struct content_node {
|
||||
SHA1_T chash;
|
||||
struct key_node *key;
|
||||
uint8_t *f_body;
|
||||
uint32_t f_body_len;
|
||||
uint8_t nested;
|
||||
uint8_t compression;
|
||||
uint8_t gzip;
|
||||
uint8_t reserved;
|
||||
uint32_t last_usage;
|
||||
uint32_t usage_counter;
|
||||
struct avl_tree dext_tree;
|
||||
|
||||
struct avl_tree usage_tree;
|
||||
};
|
||||
|
||||
struct desc_tlv_body {
|
||||
|
||||
|
||||
struct refnl_node {
|
||||
struct list_node list;
|
||||
struct ref_node *refn;
|
||||
union {
|
||||
struct content_usage_node *cun;
|
||||
uint8_t *desc_tlv_body;
|
||||
} u;
|
||||
uint16_t desc_tlv_body_len;
|
||||
};
|
||||
|
||||
struct dext_type_data {
|
||||
uint32_t len;
|
||||
uint32_t pos;
|
||||
};
|
||||
struct desc_content {
|
||||
IDM_T cntr;
|
||||
struct key_node *key;
|
||||
struct orig_node *orig;
|
||||
uint8_t *desc_frame;
|
||||
uint16_t desc_frame_len;
|
||||
int32_t ref_content_len;
|
||||
DESC_SQN_T descSqn;
|
||||
|
||||
struct desc_extension {
|
||||
struct list_head refnl_list;
|
||||
struct dhash_node *dhn;
|
||||
uint8_t max_nesting;
|
||||
uint8_t *data;
|
||||
uint32_t dlen;
|
||||
struct dext_type_data dtd[BMX_DSC_TLV_ARRSZ];
|
||||
struct avl_tree contentRefs_tree;
|
||||
uint32_t unresolvedContentCounter;
|
||||
uint8_t max_nesting;
|
||||
struct desc_tlv_body final[BMX_DSC_TLV_ARRSZ];
|
||||
};
|
||||
|
||||
void *dext_dptr( struct desc_extension *dext, uint8_t type);
|
||||
struct dhash_node {
|
||||
DHASH_T dhash;
|
||||
|
||||
TIME_T referred_by_me_timestamp; // last time this node was referred
|
||||
TIME_T referred_by_others_timestamp;
|
||||
|
||||
struct desc_content *descContent;
|
||||
uint8_t rejected;
|
||||
struct avl_tree neighRefs_tree;
|
||||
};
|
||||
|
||||
|
||||
struct orig_node {
|
||||
// filled in by validate_new_link_desc0():
|
||||
|
||||
GLOBAL_ID_T nodeId;
|
||||
struct {
|
||||
char hostname[MAX_HOSTNAME_LEN];
|
||||
|
||||
struct dhash_node *dhn;
|
||||
GLOBAL_ID_T nodeId;
|
||||
} __attribute__((packed)) k;
|
||||
|
||||
// struct dhash_node *dhn; //TODO: remove
|
||||
// int32_t currKeySupportsPerOrig;
|
||||
struct desc_content *descContent;
|
||||
struct key_node *key;
|
||||
struct neigh_node *neigh;
|
||||
TIME_T updated_timestamp; // last time this on's desc was succesfully updated
|
||||
|
||||
OGM_SQN_T ogmSqn_rangeMin;
|
||||
OGM_SQN_T ogmSqn_rangeSize;
|
||||
|
||||
|
||||
|
||||
// filled in by process_desc0_tlvs()->
|
||||
IPX_T primary_ip;
|
||||
char primary_ip_str[IPX_STR_LEN];
|
||||
uint8_t blocked; // blocked description
|
||||
uint8_t added; // added description
|
||||
|
||||
// uint8_t blocked; // blocked description
|
||||
// uint8_t added; // added description
|
||||
|
||||
struct host_metricalgo *path_metricalgo;
|
||||
|
||||
char *hostname;
|
||||
|
||||
uint32_t *trustedNeighsBitArray;
|
||||
|
||||
// calculated by update_path_metric()
|
||||
uint32_t *trustedNeighsBitArray;
|
||||
|
||||
OGM_SQN_T ogmSqn_maxRcvd;
|
||||
IDM_T ogmAggregActive;
|
||||
AGGREG_SQN_T ogmAggregSqn;
|
||||
|
||||
OGM_SQN_T ogmSqn_next;
|
||||
UMETRIC_T ogmMetric_next;
|
||||
|
||||
OGM_SQN_T ogmSqn_send;
|
||||
// UMETRIC_T ogmMetric_send;
|
||||
|
||||
UMETRIC_T *metricSqnMaxArr; // TODO: remove
|
||||
|
||||
struct avl_tree rt_tree;
|
||||
|
||||
struct router_node *curr_rt_local; // the currently used local neighbor for routing
|
||||
TIME_T ogmSqnTime;
|
||||
OGM_SQN_T ogmSqn;
|
||||
UMETRIC_T ogmMetric;
|
||||
LinkNode *curr_rt_link; // the configured route in the kernel!
|
||||
|
||||
//size of plugin data is defined during intialization and depends on registered PLUGIN_DATA_ORIG hooks
|
||||
@@ -447,42 +374,81 @@ struct orig_node {
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct dhash_node {
|
||||
|
||||
DHASH_T dhash;
|
||||
|
||||
TIME_T referred_by_me_timestamp; // last time this dhn was referred
|
||||
|
||||
struct neigh_node *local; //TODO: remove and use on!
|
||||
IID_T myIID4orig;
|
||||
|
||||
|
||||
struct orig_node *on;
|
||||
|
||||
uint8_t *desc_frame;
|
||||
uint16_t desc_frame_len;
|
||||
struct desc_extension *dext;
|
||||
|
||||
struct deprecated_globalId_node *deprecated_globalId;
|
||||
struct reference_node {
|
||||
struct dhash_node *dhn;
|
||||
struct neigh_node *neigh;
|
||||
struct key_node *claimedKey;
|
||||
TIME_T mentionedRefTime;
|
||||
DESC_SQN_T claimedDescSqn;
|
||||
OGM_SQN_T ogmSqnMax;
|
||||
TIME_T ogmSqnTime;
|
||||
TIME_T ogmBestSinceSqn;
|
||||
AGGREG_SQN_T aggSqn;
|
||||
FMETRIC_U16_T ogmMetricMax;
|
||||
uint8_t scheduled_ogm_processing;
|
||||
uint8_t shown;
|
||||
};
|
||||
|
||||
struct deprecated_globalId_node {
|
||||
GLOBAL_ID_T globalId;
|
||||
struct avl_tree deprecated_dhash_tree;
|
||||
struct key_credits {
|
||||
uint8_t nQualifying;
|
||||
uint8_t friend;
|
||||
uint8_t pktId;
|
||||
uint8_t pktSign;
|
||||
struct orig_node *recom;
|
||||
struct reference_node *ref;
|
||||
};
|
||||
|
||||
struct key_node {
|
||||
GLOBAL_ID_T kHash;
|
||||
struct KeyState *bookedState;
|
||||
struct KeyState *decreasedEffectiveState;
|
||||
struct content_node *content;
|
||||
uint8_t dirFriend; //[0,1,2=supportHisDirSupKeys]
|
||||
TIME_T pktIdTime;
|
||||
TIME_T pktSignTime;
|
||||
TIME_T nQTime;
|
||||
TIME_T TAPTime;
|
||||
struct avl_tree neighRefs_tree;
|
||||
struct orig_node *currOrig;
|
||||
struct desc_content *nextDesc;
|
||||
struct avl_tree recommendations_tree; //ofMyDirect2SupportedKeys
|
||||
};
|
||||
|
||||
struct schedDecreasedEffectiveState_node {
|
||||
struct key_node *kn;
|
||||
};
|
||||
|
||||
struct packet_header
|
||||
{
|
||||
uint8_t comp_version;
|
||||
uint8_t reserved;
|
||||
|
||||
} __attribute__((packed,__may_alias__));
|
||||
struct KeyState {
|
||||
|
||||
struct {
|
||||
int16_t numSet;
|
||||
int16_t numSec;
|
||||
uint16_t flags;
|
||||
uint8_t c;
|
||||
uint8_t r;
|
||||
struct KeyState *up;
|
||||
struct KeyState *down;
|
||||
struct KeyState *left;
|
||||
struct KeyState *right;
|
||||
} i;
|
||||
char *setName;
|
||||
char *rowName;
|
||||
char *secName;
|
||||
int16_t prefBase;
|
||||
int16_t(* prefGet) (struct key_node *kn);
|
||||
int16_t maxSet;
|
||||
void (*setInAction) (GLOBAL_ID_T *kHash, struct key_node **kn, struct KeyState *next);
|
||||
void (*setOutAction) (struct key_node **kn, struct KeyState *next);
|
||||
int8_t(* colMaintain) (struct key_node *kn);
|
||||
int8_t(* colCond) (uint8_t asRow, struct key_node *kn);
|
||||
int8_t(* rowCond) (struct key_node *kn, struct key_credits *kc);
|
||||
};
|
||||
|
||||
struct packet_header {
|
||||
uint8_t comp_version;
|
||||
uint8_t reserved;
|
||||
CRYPTSHA1_T keyHash;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
|
||||
struct packet_buff {
|
||||
|
||||
@@ -500,13 +466,9 @@ struct packet_buff {
|
||||
//filled in by rx_packet():
|
||||
IPX_T llip;
|
||||
char llip_str[INET6_ADDRSTRLEN];
|
||||
|
||||
struct dhash_node *verifiedLinkDhn;
|
||||
LinkNode *verifiedLink;
|
||||
// LinkDevNode *linkDev;
|
||||
// IID_T transmittersIID;
|
||||
// uint32_t rx_counter;
|
||||
|
||||
|
||||
struct key_node *claimedKey;
|
||||
LinkNode *verifiedLink;
|
||||
} i;
|
||||
|
||||
union {
|
||||
@@ -517,66 +479,40 @@ struct packet_buff {
|
||||
};
|
||||
|
||||
|
||||
extern struct packet_buff *curr_rx_packet;
|
||||
|
||||
extern struct key_node *myKey;
|
||||
|
||||
|
||||
extern struct orig_node *self;
|
||||
|
||||
extern struct iid_repos my_iid_repos;
|
||||
|
||||
|
||||
//extern struct avl_tree dhash_tree;
|
||||
extern struct avl_tree deprecated_dhash_tree;
|
||||
extern struct avl_tree deprecated_globalId_tree;
|
||||
extern struct avl_tree local_tree;
|
||||
extern struct avl_tree link_dev_tree;
|
||||
extern struct avl_tree link_tree;
|
||||
extern struct avl_tree orig_tree;
|
||||
extern struct avl_tree key_tree;
|
||||
extern struct avl_tree dhash_tree;
|
||||
|
||||
extern uint32_t content_tree_unresolveds;
|
||||
|
||||
|
||||
/***********************************************************
|
||||
Data Infrastructure
|
||||
************************************************************/
|
||||
|
||||
void iid_purge_repos( struct iid_repos *rep );
|
||||
void iid_free(struct iid_repos *rep, IID_T iid);
|
||||
void iid_free_neighIID4x_by_myIID4x( struct iid_repos *rep, IID_T myIID4x);
|
||||
IDM_T iid_set_neighIID4x(struct iid_repos *neigh_rep, IID_T neighIID4x, IID_T myIID4x);
|
||||
IID_T iid_new_myIID4x( IID_NODE_T *dhn );
|
||||
IID_NODE_T* iid_get_node_by_neighIID4x(IID_NEIGH_T *nn, IID_T neighIID4x, IDM_T verbose);
|
||||
IID_NODE_T* iid_get_node_by_myIID4x( IID_T myIID4x );
|
||||
void refNode_destroy(struct reference_node *ref, IDM_T reAssessState);
|
||||
struct reference_node *refNode_update(struct neigh_node *neigh, AGGREG_SQN_T aggSqn, DHASH_T *descHash, struct CRYPTSHA1_T *claimedKey, DESC_SQN_T claimedSqn);
|
||||
|
||||
struct dhash_node* dhash_node_create(DHASH_T *dhash, struct neigh_node *neigh);
|
||||
void dhash_node_reject(struct dhash_node *dhn);
|
||||
void dhash_clean_data(struct dhash_node *dhn);
|
||||
|
||||
LinkNode *getLinkNode(struct dev_node *dev, IPX_T *llip, LINKADV_SQN_T link_sqn, struct dhash_node *verifiedLinkDhn, DEVADV_IDX_T dev_idx);
|
||||
int purge_orig_router(struct orig_node *onlyOrig, struct neigh_node *onlyNeigh, LinkNode *onlyLink, IDM_T onlyUseless);
|
||||
void neigh_destroy(struct neigh_node *local);
|
||||
struct neigh_node *neigh_create(struct orig_node *on);
|
||||
|
||||
void badlist_neighbor_if_verified(struct packet_buff *pb);
|
||||
|
||||
IDM_T badlist_neighbor(struct packet_buff *pb, DHASH_T *dhash);
|
||||
|
||||
|
||||
void purge_deprecated_globalId_tree( GLOBAL_ID_T *globalId );
|
||||
//void purge_deprecated_dhash_tree( struct dhash_node *onlyDhn, IDM_T onlyExpired );
|
||||
void deprecate_dhash_iid( struct dhash_node *dhn, DHASH_T *dhash, GLOBAL_ID_T *globalId );
|
||||
void purge_orig_router(struct orig_node *onlyOrig, struct neigh_node *onlyNeigh, LinkNode *onlyLink, IDM_T only_useless);
|
||||
void purge_link_route_orig_nodes(struct dev_node *only_dev, IDM_T only_expired, struct orig_node *except_on);
|
||||
void block_orig_node(IDM_T block, struct orig_node *on);
|
||||
void free_orig_node(struct orig_node *on);
|
||||
struct orig_node *init_orig_node(GLOBAL_ID_T *id);
|
||||
void destroy_orig_node(struct orig_node *on);
|
||||
void init_self(void);
|
||||
|
||||
SHA1_T *nodeIdFromDescAdv( uint8_t *desc_adv );
|
||||
char *nodeIdAsStringFromDescAdv( uint8_t *desc_adv );
|
||||
|
||||
void purge_local_node(struct neigh_node *local);
|
||||
void purge_linkDevs(LinkDevKey *onlyLinkDev, struct dev_node *only_dev, IDM_T only_expired);
|
||||
|
||||
struct dhash_node *get_dhash_tree_node(DHASH_T *dhash);
|
||||
void update_orig_dhash(struct orig_node *on, struct dhash_node *dhn);
|
||||
struct dhash_node* create_dext_dhash(uint8_t *desc_frame, uint32_t desc_frame_len, struct desc_extension* dext, DHASH_T *dhash);
|
||||
|
||||
LOCAL_ID_T new_local_id(struct dev_node *dev);
|
||||
|
||||
|
||||
void node_tasks(void);
|
||||
|
||||
void cleanup_node(void);
|
||||
void init_node(void);
|
603
ogm.c
Normal file
603
ogm.c
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
//#include "math.h"
|
||||
|
||||
|
||||
#include "list.h"
|
||||
#include "control.h"
|
||||
#include "bmx.h"
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "sec.h"
|
||||
#include "metrics.h"
|
||||
#include "ogm.h"
|
||||
#include "msg.h"
|
||||
#include "desc.h"
|
||||
#include "ip.h"
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
#include "tools.h"
|
||||
#include "iptools.h"
|
||||
#include "allocate.h"
|
||||
#include "prof.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "ogm"
|
||||
|
||||
int32_t ogmIid = NO;
|
||||
|
||||
|
||||
static int32_t ogmSqnRange = DEF_OGM_SQN_RANGE;
|
||||
|
||||
static int32_t minMyOgmInterval = DEF_OGM_INTERVAL; /* orginator message interval in miliseconds */
|
||||
static int32_t maxMyOgmIFactor = DEF_OGM_IFACTOR;
|
||||
|
||||
AGGREG_SQN_T ogm_aggreg_sqn_max = 0;
|
||||
AGGREG_SQN_T ogm_aggreg_sqn_max_window_size = 0;
|
||||
AGGREG_SQN_T ogm_aggreg_sqn_send = 0;
|
||||
|
||||
int32_t sendLinkRevisedOgms = DEF_SEND_LINK_REVISED_OGMS;
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
struct avl_tree **ogm_aggreg_origs(AGGREG_SQN_T aggSqn)
|
||||
{
|
||||
static struct avl_tree *ogm_aggreg_orig_trees[AGGREG_SQN_CACHE_RANGE] = {NULL};
|
||||
|
||||
return &ogm_aggreg_orig_trees[(AGGREG_SQN_CACHE_MASK & aggSqn)];
|
||||
}
|
||||
|
||||
|
||||
void remove_ogm( struct orig_node *on )
|
||||
{
|
||||
|
||||
if (on->ogmAggregActive) {
|
||||
AGGREG_SQN_T aggregSqn = on->ogmAggregSqn;
|
||||
struct avl_tree *aggregSqnOrigs = *ogm_aggreg_origs(aggregSqn);
|
||||
ASSERTION(-502280, (aggregSqnOrigs && aggregSqnOrigs->items && avl_find(aggregSqnOrigs, &on->k.nodeId)));
|
||||
|
||||
on->ogmAggregActive = 0;
|
||||
avl_remove(aggregSqnOrigs, &on->k.nodeId, -300760);
|
||||
|
||||
if (!aggregSqnOrigs->items) {
|
||||
debugFree(aggregSqnOrigs, -300761);
|
||||
*ogm_aggreg_origs(aggregSqn) = (struct avl_tree*) NULL;
|
||||
}
|
||||
|
||||
while (ogm_aggreg_sqn_max_window_size && (ogm_aggreg_sqn_max - (ogm_aggreg_sqn_max_window_size - 1)) == aggregSqn && !(*ogm_aggreg_origs(aggregSqn))) {
|
||||
|
||||
ogm_aggreg_sqn_max_window_size--;
|
||||
aggregSqn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_ogm_aggregations(void)
|
||||
{
|
||||
assertion(-502276, ((ogm_aggreg_sqn_max - ogm_aggreg_sqn_send) <= 1));
|
||||
assertion(-502471, ((*ogm_aggreg_origs(ogm_aggreg_sqn_max))));
|
||||
assertion(-502275, ((*ogm_aggreg_origs(ogm_aggreg_sqn_max))->items));
|
||||
|
||||
if (ogm_aggreg_sqn_max > ogm_aggreg_sqn_send) {
|
||||
|
||||
ogm_aggreg_sqn_send = ogm_aggreg_sqn_max;
|
||||
uint16_t sz = (*ogm_aggreg_origs(ogm_aggreg_sqn_max))->items * sizeof(struct msg_ogm_dhash_adv);
|
||||
schedule_tx_task(FRAME_TYPE_OGM_DHASH_ADV, NULL, NULL, NULL, sz, &ogm_aggreg_sqn_max, sizeof(ogm_aggreg_sqn_max));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_ogm( struct orig_node *on, OGM_SQN_T ogmSqn, UMETRIC_T um )
|
||||
{
|
||||
assertion(-502281, (on && ogmSqn && um));
|
||||
|
||||
if ((ogmSqn > on->ogmSqn) || (ogmSqn == on->ogmSqn && um > on->ogmMetric)) {
|
||||
|
||||
if (on->ogmAggregActive && on->ogmAggregSqn == ogm_aggreg_sqn_max && ogm_aggreg_sqn_max > ogm_aggreg_sqn_send) {
|
||||
|
||||
ASSERTION(-502282, (avl_find((*ogm_aggreg_origs(ogm_aggreg_sqn_max)), &on->k.nodeId)));
|
||||
|
||||
} else {
|
||||
remove_ogm(on);
|
||||
|
||||
assertion(-502283, ((ogm_aggreg_sqn_max - ogm_aggreg_sqn_send) <= 1));
|
||||
|
||||
if (ogm_aggreg_sqn_max == ogm_aggreg_sqn_send) {
|
||||
|
||||
if (ogm_aggreg_sqn_max_window_size >= AGGREG_SQN_CACHE_RANGE) {
|
||||
struct avl_tree *origs;
|
||||
while ((origs = *ogm_aggreg_origs(ogm_aggreg_sqn_max + 1))) {
|
||||
struct orig_node *o = avl_first_item(origs);
|
||||
dbgf_sys(DBGT_WARN, "Removing scheduled ogmSqn=%d hostname=%s ogmAggActive=%d ogmAggSqn=%d ogmAggSqnMax=%d",
|
||||
o->ogmSqn, o->k.hostname, o->ogmAggregActive, o->ogmAggregSqn, ogm_aggreg_sqn_max);
|
||||
assertion(-502472, (o->ogmAggregActive && o->ogmAggregSqn == ((AGGREG_SQN_T)(ogm_aggreg_sqn_max+1-AGGREG_SQN_CACHE_RANGE))));
|
||||
remove_ogm(o);
|
||||
}
|
||||
assertion(-502473, (ogm_aggreg_sqn_max_window_size < AGGREG_SQN_CACHE_RANGE));
|
||||
}
|
||||
|
||||
ogm_aggreg_sqn_max++;
|
||||
ogm_aggreg_sqn_max_window_size++;
|
||||
}
|
||||
|
||||
if (!(*ogm_aggreg_origs(ogm_aggreg_sqn_max))) {
|
||||
(*ogm_aggreg_origs(ogm_aggreg_sqn_max)) = debugMallocReset(sizeof(struct avl_tree), -300762);
|
||||
AVL_INIT_TREE((*(*ogm_aggreg_origs(ogm_aggreg_sqn_max))), struct orig_node, k.nodeId );
|
||||
}
|
||||
|
||||
avl_insert((*ogm_aggreg_origs(ogm_aggreg_sqn_max)), on, -300763);
|
||||
|
||||
on->ogmAggregActive = 1;
|
||||
on->ogmAggregSqn = ogm_aggreg_sqn_max;
|
||||
}
|
||||
|
||||
assertion(-502284, ((ogm_aggreg_sqn_max - ogm_aggreg_sqn_send) == 1));
|
||||
|
||||
on->ogmSqn = ogmSqn;
|
||||
on->ogmMetric = um;
|
||||
|
||||
if ((*ogm_aggreg_origs(ogm_aggreg_sqn_max))->items >= OGMS_DHASH_PER_AGGREG_PREF)
|
||||
schedule_ogm_aggregations();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_my_originator_message(void)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
struct orig_node *on = myKey->currOrig;
|
||||
|
||||
if ((on->ogmSqn + 1) > ogmSqnRange) {
|
||||
|
||||
my_description_changed = YES;
|
||||
|
||||
} else {
|
||||
|
||||
schedule_ogm(on, on->ogmSqn + 1, UMETRIC_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void revise_ogm_aggregations(void)
|
||||
{
|
||||
assertion(-502276, ((ogm_aggreg_sqn_max - ogm_aggreg_sqn_send) <= 1));
|
||||
|
||||
|
||||
static TIME_T myNextHitchhike = 0;
|
||||
static TIME_T myNextGuarantee = 0;
|
||||
|
||||
TIME_T myGuaranteedInterval = ((minMyOgmInterval * maxMyOgmIFactor) / 100);
|
||||
IDM_T myNextNow = doNowOrLater(&myNextGuarantee, myGuaranteedInterval, (myKey->currOrig->ogmSqn == 0));
|
||||
|
||||
if (myNextNow ||
|
||||
(ogm_aggreg_sqn_max > ogm_aggreg_sqn_send && *ogm_aggreg_origs(ogm_aggreg_sqn_max) && (*ogm_aggreg_origs(ogm_aggreg_sqn_max))->items)) {
|
||||
|
||||
if (doNowOrLater(&myNextHitchhike, minMyOgmInterval, myNextNow)) {
|
||||
doNowOrLater(&myNextGuarantee, myGuaranteedInterval, YES); //sync the two timeouts!
|
||||
schedule_my_originator_message();
|
||||
}
|
||||
|
||||
|
||||
dbgf(myNextNow ? DBGL_CHANGES : DBGL_ALL, DBGT_INFO, "myNextNow=%d myGuaranteedInterval=%d sqnMax=%d sqnSend=%d size=%d max=%d",
|
||||
myNextNow, myGuaranteedInterval, ogm_aggreg_sqn_max, ogm_aggreg_sqn_send,
|
||||
(*ogm_aggreg_origs(ogm_aggreg_sqn_max)) ? (*ogm_aggreg_origs(ogm_aggreg_sqn_max))->items : 0,
|
||||
OGMS_DHASH_PER_AGGREG_PREF);
|
||||
|
||||
schedule_ogm_aggregations();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_frame_ogm_aggreg_sqn(struct tx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
assertion(-500771, (tx_iterator_cache_data_space_pref(it, 0, 0) >= ((int) sizeof(struct msg_ogm_aggreg_sqn_adv))));
|
||||
|
||||
dbgf_all(DBGT_INFO, "max=%d size=%d", ogm_aggreg_sqn_max, ogm_aggreg_sqn_max_window_size);
|
||||
|
||||
struct msg_ogm_aggreg_sqn_adv *adv = (struct msg_ogm_aggreg_sqn_adv *) (tx_iterator_cache_msg_ptr(it));
|
||||
|
||||
adv->max = htons(ogm_aggreg_sqn_max);
|
||||
adv->size = htons(ogm_aggreg_sqn_max_window_size);
|
||||
|
||||
return sizeof(struct msg_ogm_aggreg_sqn_adv);
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_frame_ogm_aggreg_sqn(struct rx_frame_iterator *it)
|
||||
{
|
||||
|
||||
assertion(-502285, (it && it->f_type == FRAME_TYPE_OGM_AGG_SQN_ADV));
|
||||
assertion(-502286, (it->pb->i.verifiedLink && it->pb->i.verifiedLink->k.linkDev->key.local));
|
||||
|
||||
AGGREG_SQN_T max = ntohs(((struct msg_ogm_aggreg_sqn_adv *) it->f_msg)->max);
|
||||
AGGREG_SQN_T sz = ntohs(((struct msg_ogm_aggreg_sqn_adv *) it->f_msg)->size);
|
||||
struct neigh_node *nn = it->pb->i.verifiedLink->k.linkDev->key.local;
|
||||
|
||||
dbgf_all(DBGT_INFO, "from neigh=%s max=%d/%d sz=%d/%d time=%d",
|
||||
nn->on->k.hostname, max, nn->ogm_aggreg_max, sz, nn->ogm_aggreg_size, nn->ogm_aggreg_time);
|
||||
|
||||
|
||||
if ((AGGREG_SQN_MASK & (nn->ogm_aggreg_max - (max + 1))) >= AGGREG_SQN_CACHE_RANGE) {
|
||||
|
||||
sz = XMIN(sz, AGGREG_SQN_CACHE_RANGE);
|
||||
|
||||
if (nn->ogm_aggreg_time && ((AGGREG_SQN_MASK & (max - nn->ogm_aggreg_max)) < AGGREG_SQN_CACHE_RANGE))
|
||||
sz = XMIN(sz, (nn->ogm_aggreg_size + (max - nn->ogm_aggreg_max)));
|
||||
else
|
||||
sz = XMIN(sz, 1);
|
||||
|
||||
nn->ogm_aggreg_size = sz;
|
||||
|
||||
if (max != nn->ogm_aggreg_max) {
|
||||
|
||||
if ((AGGREG_SQN_MASK & (max - nn->ogm_aggreg_max)) >= sz) {
|
||||
|
||||
memset(nn->ogm_aggreg_sqns, 0, sizeof(nn->ogm_aggreg_sqns));
|
||||
|
||||
} else {
|
||||
bits_clear(nn->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE,
|
||||
((AGGREG_SQN_MASK)& (nn->ogm_aggreg_max + 1)), max, AGGREG_SQN_MASK);
|
||||
}
|
||||
|
||||
nn->ogm_aggreg_max = max;
|
||||
nn->ogm_aggreg_time = bmx_time;
|
||||
}
|
||||
}
|
||||
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
void schedule_ogm_req(void)
|
||||
{
|
||||
struct neigh_node *nn = NULL;
|
||||
|
||||
while ((nn = avl_next_item(&local_tree, nn ? &nn->local_id : NULL))) {
|
||||
|
||||
if (nn->orig_routes && nn->best_tp_link && (nn->ogm_aggreg_time || nn->ogm_aggreg_max)) { //ever updated:
|
||||
|
||||
AGGREG_SQN_T cnt = 0;
|
||||
|
||||
for (cnt = 0; cnt < nn->ogm_aggreg_size; cnt++) {
|
||||
|
||||
AGGREG_SQN_T sqn = (nn->ogm_aggreg_max - cnt);
|
||||
|
||||
if (!bit_get(nn->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE, sqn)) {
|
||||
struct dev_node *dev = nn->best_tp_link->k.myDev;
|
||||
schedule_tx_task(FRAME_TYPE_OGM_REQ, &nn->local_id, nn, dev, SCHEDULE_MIN_MSG_SIZE, &sqn, sizeof(sqn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_msg_ogm_aggreg_request(struct tx_frame_iterator *it)
|
||||
{
|
||||
AGGREG_SQN_T *sqn = (AGGREG_SQN_T *)it->ttn->key.data;
|
||||
struct hdr_ogm_aggreg_req *hdr = (struct hdr_ogm_aggreg_req *) tx_iterator_cache_hdr_ptr(it);
|
||||
struct msg_ogm_aggreg_req *msg = (struct msg_ogm_aggreg_req *) tx_iterator_cache_msg_ptr(it);
|
||||
|
||||
IDM_T known = bit_get(it->ttn->neigh->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE, *sqn);
|
||||
|
||||
dbgf_track(DBGT_INFO, "sqn=%d known=%d to neigh=%s", *sqn, known, it->ttn->neigh->on->k.hostname);
|
||||
|
||||
if (known) {
|
||||
|
||||
return TLV_TX_DATA_DONE;
|
||||
|
||||
} else {
|
||||
|
||||
if (hdr->msg == msg) {
|
||||
assertion(-502287, (is_zero(hdr, sizeof (*hdr))));
|
||||
hdr->dest_nodeId = it->ttn->key.f.groupId;
|
||||
} else {
|
||||
assertion(-502288, (cryptShasEqual(&hdr->dest_nodeId, &it->ttn->key.f.groupId)));
|
||||
}
|
||||
|
||||
msg->sqn = htons(*sqn);
|
||||
|
||||
return sizeof(struct msg_ogm_aggreg_req);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_msg_ogm_aggreg_request(struct rx_frame_iterator *it)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
|
||||
struct hdr_ogm_aggreg_req *hdr = (struct hdr_ogm_aggreg_req*) (it->f_data);
|
||||
struct msg_ogm_aggreg_req *msg = (struct msg_ogm_aggreg_req*) (it->f_msg);
|
||||
AGGREG_SQN_T sqn = ntohs(msg->sqn);
|
||||
|
||||
if (cryptShasEqual(&hdr->dest_nodeId, &myKey->kHash) && (((AGGREG_SQN_T)(ogm_aggreg_sqn_max - sqn)) < ogm_aggreg_sqn_max_window_size) ) {
|
||||
|
||||
struct neigh_node *nn = it->pb->i.verifiedLink->k.linkDev->key.local;
|
||||
uint16_t ogms = (*ogm_aggreg_origs(sqn)) ? (*ogm_aggreg_origs(sqn))->items : 0;
|
||||
|
||||
schedule_tx_task(FRAME_TYPE_OGM_DHASH_ADV, NULL, NULL, nn->best_tp_link->k.myDev, (ogms * sizeof(struct msg_ogm_dhash_adv)), &sqn, sizeof(sqn));
|
||||
|
||||
dbgf_track(DBGT_INFO, "sqn=%d ogms=%d", sqn, ogms);
|
||||
}
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t tx_frame_ogm_dhash_aggreg_advs(struct tx_frame_iterator *it)
|
||||
{
|
||||
struct hdr_ogm_adv *hdr = ((struct hdr_ogm_adv*) tx_iterator_cache_hdr_ptr(it));
|
||||
AGGREG_SQN_T *sqn = ((AGGREG_SQN_T *)it->ttn->key.data);
|
||||
struct avl_tree *origs = (*ogm_aggreg_origs(*sqn));
|
||||
uint16_t ogms = origs ? origs->items : 0;
|
||||
struct avl_node *an = NULL;
|
||||
struct orig_node *on;
|
||||
struct msg_ogm_dhash_adv *msg;
|
||||
|
||||
assertion(-500771, (tx_iterator_cache_data_space_pref(it, 0, 0) >= (int)(ogms * sizeof(struct msg_ogm_dhash_adv))));
|
||||
|
||||
hdr->aggregation_sqn = htons(*sqn);
|
||||
|
||||
for (msg = hdr->msg; (origs && (on = avl_iterate_item(origs, &an))); msg++) {
|
||||
msg->dhash = on->descContent->dhn->dhash;
|
||||
msg->sqn = htons(on->ogmSqn);
|
||||
msg->metric.val.u16 = htons(umetric_to_fmetric(on->ogmMetric).val.u16);
|
||||
|
||||
on->descContent->dhn->referred_by_me_timestamp = bmx_time;
|
||||
}
|
||||
|
||||
dbgf_all(DBGT_INFO, "aggSqn=%d aggSqnMax=%d ogms=%d", *sqn, ogm_aggreg_sqn_max, ogms);
|
||||
|
||||
return (ogms * sizeof(struct msg_ogm_dhash_adv));
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
UMETRIC_T lndev_best_via_router(struct neigh_node *local, struct orig_node *on, UMETRIC_T *ogm_metric, LinkNode **bestPathLink)
|
||||
{
|
||||
assertion(-502474, (local->linkDev_tree.items));
|
||||
UMETRIC_T metric_best = 0;
|
||||
|
||||
struct avl_node *linkDev_an = NULL;
|
||||
LinkDevNode *linkDev;
|
||||
|
||||
while ((linkDev = avl_iterate_item(&local->linkDev_tree, &linkDev_an))) {
|
||||
|
||||
LinkNode *link = NULL;
|
||||
|
||||
while ((link = avl_next_item(&linkDev->link_tree, (link ? &link->k : NULL)))) {
|
||||
|
||||
UMETRIC_T um = apply_lndev_metric_algo(link, ogm_metric, on->path_metricalgo);
|
||||
|
||||
if (metric_best <= um) {
|
||||
metric_best = um;
|
||||
*bestPathLink = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertion(-501088, (*bestPathLink));
|
||||
return metric_best;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void process_ogm_metric(void *voidRef)
|
||||
{
|
||||
struct reference_node *ref = voidRef;
|
||||
assertion(-502475, (ref));
|
||||
assertion(-502476, (ref->dhn));
|
||||
|
||||
if (ref->scheduled_ogm_processing) {
|
||||
ref->scheduled_ogm_processing = 0;
|
||||
task_remove(process_ogm_metric, (void*)ref);
|
||||
}
|
||||
|
||||
if (!ref->dhn->descContent || !ref->dhn->descContent->orig)
|
||||
return;
|
||||
|
||||
struct orig_node *on = ref->dhn->descContent->orig;
|
||||
IDM_T neighTrust = verify_neighTrust(on, ref->neigh);
|
||||
IDM_T valid_metric = is_fmetric_valid(ref->ogmMetricMax);
|
||||
UMETRIC_T ogmMetric = valid_metric ? fmetric_to_umetric(ref->ogmMetricMax) : 0;
|
||||
|
||||
|
||||
dbgf_all(DBGT_INFO, "orig=%s via neigh=%s ogmMtc=%ju, ogmSqn=%d knownSqn=%d",
|
||||
cryptShaAsShortStr(&on->k.nodeId), cryptShaAsShortStr(&ref->neigh->local_id), ogmMetric, ref->ogmSqnMax, on->ogmSqn);
|
||||
|
||||
if (!neighTrust || !valid_metric || ogmMetric < on->path_metricalgo->umetric_min)
|
||||
return;
|
||||
|
||||
static int count = 0;
|
||||
assertion(-502477, (count <= 2)); //this one calls itself via schedule_ogm()->schedule_ogm_aggregations()->process_ogm()
|
||||
|
||||
if (ref->ogmSqnMax >= on->ogmSqn) {
|
||||
|
||||
LinkNode *best_rt_link = NULL;
|
||||
UMETRIC_T best_rt_metric = lndev_best_via_router(ref->neigh, on, &ogmMetric, &best_rt_link);
|
||||
assertion(-502478, (best_rt_metric && best_rt_link));
|
||||
|
||||
if (
|
||||
((ref->ogmSqnMax >= (on->ogmSqn + 2))) ||
|
||||
((ref->ogmSqnMax >= (on->ogmSqn + 1)) && (((TIME_T)(bmx_time - ref->ogmSqnTime)) >= on->path_metricalgo->ogm_sqn_late_hystere)) ||
|
||||
((ref->ogmSqnMax >= (on->ogmSqn + 0)) && (best_rt_link == on->curr_rt_link)) ||
|
||||
((ref->ogmSqnMax >= (on->ogmSqn + 0)) && (best_rt_metric > on->ogmMetric) && ref->ogmBestSinceSqn && (((OGM_SQN_T) (ref->ogmSqnMax - ref->ogmBestSinceSqn)) >= on->path_metricalgo->ogm_sqn_best_hystere)) ||
|
||||
((ref->ogmSqnMax >= (on->ogmSqn + 0)) && (best_rt_metric > ((on->ogmMetric * (100 + on->path_metricalgo->ogm_metric_hystere))/100)))
|
||||
) {
|
||||
|
||||
if (best_rt_link != on->curr_rt_link) {
|
||||
|
||||
if (on->curr_rt_link)
|
||||
cb_route_change_hooks(DEL, on);
|
||||
|
||||
on->curr_rt_link = best_rt_link;
|
||||
|
||||
cb_route_change_hooks(ADD, on);
|
||||
}
|
||||
|
||||
schedule_ogm(on, ref->ogmSqnMax, best_rt_metric);
|
||||
|
||||
ref->ogmBestSinceSqn = 0;
|
||||
|
||||
} else {
|
||||
if ((ref->ogmSqnMax >= (on->ogmSqn + 1)) && (((TIME_T)(bmx_time - ref->ogmSqnTime)) < on->path_metricalgo->ogm_sqn_late_hystere)) {
|
||||
ref->scheduled_ogm_processing++;
|
||||
task_register((on->path_metricalgo->ogm_sqn_late_hystere - ((TIME_T) (bmx_time - ref->ogmSqnTime))), process_ogm_metric, ref, -300764);
|
||||
}
|
||||
|
||||
if ((best_rt_metric > on->ogmMetric) && !ref->ogmBestSinceSqn)
|
||||
ref->ogmBestSinceSqn = ref->ogmSqnMax;
|
||||
else if (best_rt_metric <= on->ogmMetric)
|
||||
ref->ogmBestSinceSqn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_FUNC
|
||||
int32_t rx_frame_ogm_dhash_aggreg_advs(struct rx_frame_iterator *it)
|
||||
{
|
||||
struct hdr_ogm_adv *hdr = ((struct hdr_ogm_adv*) it->f_data);
|
||||
struct msg_ogm_dhash_adv *msg = hdr->msg;
|
||||
AGGREG_SQN_T aggSqn = ntohs(hdr->aggregation_sqn);
|
||||
struct neigh_node *nn = it->pb->i.verifiedLink->k.linkDev->key.local;
|
||||
IDM_T new = ((AGGREG_SQN_T) (nn->ogm_aggreg_max - aggSqn)) < nn->ogm_aggreg_size && !bit_get(nn->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE, aggSqn);
|
||||
|
||||
dbgf_all(DBGT_INFO, "new=%d neigh=%s aggSqn=%d/%d/%d msgs=%d", new, nn->on->k.hostname, aggSqn, nn->ogm_aggreg_max, nn->ogm_aggreg_size, it->f_msgs_fixed);
|
||||
|
||||
if (new) {
|
||||
|
||||
bit_set(nn->ogm_aggreg_sqns, AGGREG_SQN_CACHE_RANGE, aggSqn, 1);
|
||||
|
||||
for (; msg < &(hdr->msg[it->f_msgs_fixed]); msg++) {
|
||||
|
||||
struct reference_node *ref;
|
||||
|
||||
if ((ref = refNode_update(nn, aggSqn, &msg->dhash, NULL, 0))) {
|
||||
|
||||
OGM_SQN_T ogmSqn = ntohs(msg->sqn);
|
||||
FMETRIC_U16_T ogmMtc = {.val = {.u16 = ntohs(msg->metric.val.u16)}};
|
||||
struct orig_node *on = ref->dhn->descContent ? ref->dhn->descContent->orig : NULL;
|
||||
|
||||
dbgf_all(DBGT_INFO, "dhash=%s hostname=%s ogmSqn=%d ogmMtc=%d",
|
||||
cryptShaAsShortStr(&msg->dhash), on ? on->k.hostname : NULL, ogmSqn, ogmMtc.val.u16);
|
||||
|
||||
if (ogmSqn > ref->ogmSqnMax || (ogmSqn == ref->ogmSqnMax && ogmMtc.val.u16 > ref->ogmMetricMax.val.u16 )) {
|
||||
|
||||
if (ogmSqn > ref->ogmSqnMax) {
|
||||
ref->ogmSqnMax = ogmSqn;
|
||||
ref->ogmSqnTime = bmx_time;
|
||||
}
|
||||
|
||||
ref->ogmMetricMax = ogmMtc;
|
||||
|
||||
if (on)
|
||||
process_ogm_metric(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TLV_RX_DATA_PROCESSED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
STATIC_FUNC
|
||||
struct opt_type ogm_options[]=
|
||||
{
|
||||
{ODI, 0, ARG_OGM_SQN_RANGE, 0, 9,0, A_PS1, A_ADM, A_DYI, A_CFA, A_ANY,&ogmSqnRange, MIN_OGM_SQN_RANGE, MAX_OGM_SQN_RANGE, DEF_OGM_SQN_RANGE,0, 0,
|
||||
ARG_VALUE_FORM, "set average OGM sequence number range (affects frequency of bmx6 description updates)"},
|
||||
{ODI,0,ARG_SEND_LINK_REVISED_OGMS, 0, 9,1,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &sendLinkRevisedOgms,MIN_SEND_REVISED_OGMS, 1, DEF_SEND_LINK_REVISED_OGMS,0, NULL,
|
||||
ARG_VALUE_FORM, "send revised ogms with better metric (but unchanged sqn)"},
|
||||
{ODI,0,ARG_OGM_INTERVAL, 'o',9,1, A_PS1, A_ADM, A_DYI, A_CFA, A_ANY, &minMyOgmInterval, MIN_OGM_INTERVAL, MAX_OGM_INTERVAL, DEF_OGM_INTERVAL,0, 0,
|
||||
ARG_VALUE_FORM, "set interval in ms with which new originator message (OGM) are send"},
|
||||
{ODI,0,ARG_OGM_IFACTOR, 0,9,1, A_PS1, A_ADM, A_DYI, A_CFA, A_ANY, &maxMyOgmIFactor, MIN_OGM_IFACTOR, MAX_OGM_IFACTOR, DEF_OGM_IFACTOR, 0, 0,
|
||||
ARG_VALUE_FORM, "set factor (relative to ogmInterval) for max delay of own ogms"},
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
int32_t init_ogm( void )
|
||||
{
|
||||
register_options_array(ogm_options, sizeof(ogm_options), CODE_CATEGORY_NAME);
|
||||
|
||||
struct frame_handl handl;
|
||||
memset(&handl, 0, sizeof ( handl));
|
||||
|
||||
handl.name = "AGGREG_SQN_ADV";
|
||||
handl.min_msg_size = sizeof(struct msg_ogm_aggreg_sqn_adv);
|
||||
handl.fixed_msg_size = 1;
|
||||
|
||||
// this might schedule a new tx_packet because schedule_tx_packet() believes
|
||||
// the stuff we are about to send now is still waiting to be send.
|
||||
handl.tx_packet_prepare_casuals = revise_ogm_aggregations;
|
||||
handl.tx_frame_handler = tx_frame_ogm_aggreg_sqn;
|
||||
handl.rx_frame_handler = rx_frame_ogm_aggreg_sqn;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_OGM_AGG_SQN_ADV, &handl);
|
||||
|
||||
handl.name = "OGM_AGGREG_REQ";
|
||||
handl.data_header_size = sizeof(struct hdr_ogm_aggreg_req);
|
||||
handl.min_msg_size = sizeof(struct msg_ogm_aggreg_req);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_packet_prepare_casuals = schedule_ogm_req;
|
||||
handl.tx_msg_handler = tx_msg_ogm_aggreg_request;
|
||||
handl.rx_msg_handler = rx_msg_ogm_aggreg_request;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_OGM_REQ, &handl);
|
||||
|
||||
handl.name = "OGM_DHASH_ADV";
|
||||
handl.data_header_size = sizeof(struct hdr_ogm_adv);
|
||||
handl.min_msg_size = sizeof(struct msg_ogm_dhash_adv);
|
||||
handl.fixed_msg_size = 1;
|
||||
handl.tx_frame_handler = tx_frame_ogm_dhash_aggreg_advs;
|
||||
handl.rx_frame_handler = rx_frame_ogm_dhash_aggreg_advs;
|
||||
register_frame_handler(packet_frame_db, FRAME_TYPE_OGM_DHASH_ADV, &handl);
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
99
ogm.h
Normal file
99
ogm.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Axel Neumann
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
extern int32_t ogmIid;
|
||||
extern uint32_t ogms_pending;
|
||||
|
||||
#define ARG_OGM_IFACTOR "ogmIntervalFactor"
|
||||
#define DEF_OGM_IFACTOR 120
|
||||
#define MIN_OGM_IFACTOR 100
|
||||
#define MAX_OGM_IFACTOR 10000
|
||||
|
||||
|
||||
#define ARG_OGM_INTERVAL "ogmInterval"
|
||||
#define DEF_OGM_INTERVAL 6000
|
||||
#define MIN_OGM_INTERVAL 200
|
||||
#define MAX_OGM_INTERVAL 60000 // 60000 = 1 minutes
|
||||
|
||||
#define _DEF_OGM_SQN_DIV 5
|
||||
#define _MIN_OGM_SQN_RANGE 32
|
||||
#define _MAX_OGM_SQN_RANGE 8192 // changing this will cause compatibility trouble
|
||||
|
||||
#define MIN_OGM_SQN_RANGE _MIN_OGM_SQN_RANGE + (_MIN_OGM_SQN_RANGE/(2*_DEF_OGM_SQN_DIV))
|
||||
#define MAX_OGM_SQN_RANGE _MAX_OGM_SQN_RANGE - (_MAX_OGM_SQN_RANGE/(2*_DEF_OGM_SQN_DIV))
|
||||
#define DEF_OGM_SQN_RANGE MAX_OGM_SQN_RANGE
|
||||
#define ARG_OGM_SQN_RANGE "ogmSqnRange"
|
||||
|
||||
#define MIN_OGM_AGGREG_HISTORY 2
|
||||
#define MAX_OGM_AGGREG_HISTORY AGGREG_SQN_CACHE_RANGE
|
||||
#define DEF_OGM_AGGREG_HISTORY 20
|
||||
#define ARG_OGM_AGGREG_HISTORY "ogmAggregHistory"
|
||||
|
||||
|
||||
#define MIN_SEND_REVISED_OGMS 0
|
||||
#define DEF_SEND_LINK_REVISED_OGMS 0
|
||||
#define ARG_SEND_LINK_REVISED_OGMS "sendRevisedOgms"
|
||||
extern int32_t sendLinkRevisedOgms;
|
||||
|
||||
#define OGM_JUMPS_PER_AGGREGATION 10
|
||||
|
||||
|
||||
#define OGMS_DHASH_PER_AGGREG_PREF (SIGNED_FRAMES_SIZE_PREF - (\
|
||||
sizeof(struct tlv_hdr) + \
|
||||
sizeof (struct hdr_ogm_adv))) \
|
||||
/ sizeof(struct msg_ogm_dhash_adv)
|
||||
|
||||
|
||||
|
||||
#define OGM_IID_RSVD_JUMP (OGM_IIDOFFST_MASK) // 63 //255 // resulting from ((2^transmitterIIDoffset_bit_range)-1)
|
||||
|
||||
struct msg_ogm_aggreg_sqn_adv {
|
||||
AGGREG_SQN_T max;
|
||||
uint16_t size;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct msg_ogm_aggreg_req {
|
||||
AGGREG_SQN_T sqn;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hdr_ogm_aggreg_req {
|
||||
GLOBAL_ID_T dest_nodeId;
|
||||
struct msg_ogm_aggreg_req msg[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
struct msg_ogm_dhash_adv {
|
||||
DHASH_T dhash;
|
||||
FMETRIC_U16_T metric;
|
||||
uint16_t sqn;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hdr_ogm_adv {
|
||||
AGGREG_SQN_T aggregation_sqn;
|
||||
struct msg_ogm_dhash_adv msg[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
void remove_ogm(struct orig_node *on);
|
||||
void process_ogm_metric(void *voidRef);
|
||||
|
||||
int32_t init_ogm(void);
|
7
plugin.c
7
plugin.c
@@ -123,11 +123,10 @@ void cb_route_change_hooks(uint8_t del, struct orig_node *dest)
|
||||
TRACE_FUNCTION_CALL;
|
||||
struct list_node *list_pos;
|
||||
struct cb_route_change_node *con, *prev_con = NULL;
|
||||
struct neigh_node *local_router = dest->curr_rt_local->local_key;
|
||||
struct neigh_node *local_router = dest->curr_rt_link->k.linkDev->key.local;
|
||||
|
||||
assertion(-500674, (dest && dest->dhn && dest->dhn->desc_frame_len));
|
||||
|
||||
local_router->orig_routes = local_router->orig_routes + (del ? -1 : +1);
|
||||
local_router->orig_routes += (del ? -1 : +1);
|
||||
dest->curr_rt_link->orig_routes += (del ? -1 : +1);
|
||||
|
||||
assertion(-501320, (local_router->orig_routes >= 0 && local_router->orig_routes < (int) orig_tree.items));
|
||||
|
||||
|
31
prof.c
31
prof.c
@@ -37,6 +37,8 @@
|
||||
#include "prof.h"
|
||||
#include "schedule.h"
|
||||
|
||||
#define CODE_CATEGORY_NAME "profiling"
|
||||
|
||||
static AVL_TREE(prof_tree, struct prof_ctx, k);
|
||||
|
||||
void prof_init( struct prof_ctx *sp)
|
||||
@@ -89,13 +91,13 @@ int prof_check(struct prof_ctx *p, int childs)
|
||||
!p || (p->active_prof && !!p->active_childs == childs && prof_check(p->parent, 1) == SUCCESS))
|
||||
return SUCCESS;
|
||||
|
||||
dbgf_sys(DBGT_ERR, "func=%p name=%s parent_func=%p neigh=%p orig=%p parent_active_childs=%d childs=%d",
|
||||
p->k.func, p->name, p->parent_func, (void*)p->k.neigh, (void*)p->k.orig, p->active_childs, childs);
|
||||
dbgf_sys(DBGT_ERR, "func=%d name=%s parent_func=%d neigh=%p orig=%p parent_active_childs=%d childs=%d",
|
||||
!!p->k.func, p->name, !!p->parent_func, (void*)p->k.neigh, (void*)p->k.orig, p->active_childs, childs);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
void prof_start( struct prof_ctx *p)
|
||||
void prof_start_( struct prof_ctx *p)
|
||||
{
|
||||
assertion(-502122, (!p->active_prof));
|
||||
assertion(-502123, (!p->clockBeforePStart));
|
||||
@@ -113,7 +115,9 @@ void prof_start( struct prof_ctx *p)
|
||||
ASSERTION(-502125, (prof_check(p, 0) == SUCCESS));
|
||||
}
|
||||
|
||||
void prof_stop( struct prof_ctx *p)
|
||||
|
||||
|
||||
void prof_stop_( struct prof_ctx *p)
|
||||
{
|
||||
assertion(-502126, (p->active_prof));
|
||||
ASSERTION(-502127, (prof_check(p, 0) == SUCCESS));
|
||||
@@ -158,7 +162,7 @@ void prof_update_all( void *unused) {
|
||||
dbgf_all(DBGT_INFO, "updating %s active=%d", pn->name, active);
|
||||
|
||||
if (active)
|
||||
prof_stop(pn);
|
||||
prof_stop_(pn);
|
||||
|
||||
pn->clockPrevPeriod = pn->clockRunningPeriod;
|
||||
pn->clockPrevTotal += pn->clockRunningPeriod;
|
||||
@@ -166,7 +170,7 @@ void prof_update_all( void *unused) {
|
||||
pn->clockRunningPeriod = 0;
|
||||
|
||||
if (active)
|
||||
prof_start(pn);
|
||||
prof_start_(pn);
|
||||
}
|
||||
|
||||
prof_check_disabled = NO;
|
||||
@@ -208,8 +212,8 @@ struct prof_status *prof_status_iterate(struct prof_ctx *pn, struct prof_status
|
||||
{
|
||||
dbgf_all(DBGT_INFO, "dbg pn=%s status=%p", pn->name, (void*)status);
|
||||
|
||||
status->neighId = pn->k.neigh ? &pn->k.neigh->dhn->on->nodeId : NULL;
|
||||
status->origId = &pn->k.orig ? &pn->k.orig->nodeId : NULL;
|
||||
status->neighId = pn->k.neigh ? &pn->k.neigh->local_id: NULL;
|
||||
status->origId = pn->k.orig ? &pn->k.orig->k.nodeId : NULL;
|
||||
status->parent = pn->parent ? pn->parent->name : NULL;
|
||||
status->name = pn->name;
|
||||
sprintf(status->sysCurrCpu, DBG_NIL);
|
||||
@@ -286,11 +290,20 @@ int32_t prof_status_creator(struct status_handl *handl, void *data)
|
||||
return status_size;
|
||||
}
|
||||
|
||||
#define ARG_CPU_PROFILING "cpu"
|
||||
|
||||
static struct opt_type prof_options[]=
|
||||
{
|
||||
// ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help
|
||||
{ODI,0,ARG_CPU_PROFILING, 0, 9,1,A_PS0N,A_USR,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0,0, opt_status,
|
||||
0, "show cpu usage of relevant functions\n"}
|
||||
};
|
||||
|
||||
|
||||
void init_prof( void )
|
||||
{
|
||||
register_status_handl(sizeof (struct prof_status), 1, prof_status_format, "cpu", prof_status_creator);
|
||||
register_status_handl(sizeof (struct prof_status), 1, prof_status_format, ARG_CPU_PROFILING, prof_status_creator);
|
||||
register_options_array(prof_options, sizeof( prof_options), CODE_CATEGORY_NAME);
|
||||
|
||||
task_register(5000, prof_update_all, NULL, -300649);
|
||||
|
||||
|
13
prof.h
13
prof.h
@@ -46,8 +46,17 @@ struct prof_ctx {
|
||||
|
||||
void prof_free( struct prof_ctx *p);
|
||||
|
||||
void prof_start( struct prof_ctx *p);
|
||||
void prof_stop( struct prof_ctx *p);
|
||||
void prof_start_(struct prof_ctx *p);
|
||||
void prof_stop_(struct prof_ctx *p);
|
||||
|
||||
#define prof_start( thisFunc, parentFunc ) \
|
||||
extern int main(int argc, char *argv[]); \
|
||||
static struct prof_ctx prof_ctx_ = {.k = { .func = (void(*)(void))thisFunc}, .name = __FUNCTION__, .parent_func = (void (*) (void))parentFunc}; \
|
||||
prof_start_(&prof_ctx_)
|
||||
|
||||
#define prof_stop() prof_stop_( &prof_ctx_ )
|
||||
|
||||
|
||||
|
||||
|
||||
void init_prof( void );
|
||||
|
162
redist.c
162
redist.c
@@ -16,6 +16,37 @@
|
||||
*/
|
||||
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/un.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "control.h"
|
||||
#include "bmx.h"
|
||||
#include "crypt.h"
|
||||
#include "avl.h"
|
||||
#include "node.h"
|
||||
#include "metrics.h"
|
||||
#include "msg.h"
|
||||
#include "ip.h"
|
||||
#include "hna.h"
|
||||
#include "schedule.h"
|
||||
#include "plugin.h"
|
||||
#include "tools.h"
|
||||
#include "iptools.h"
|
||||
#include "allocate.h"
|
||||
#include "redist.h"
|
||||
|
||||
|
||||
@@ -23,9 +54,9 @@ void redist_dbg(int8_t dbgl, int8_t dbgt, const char *func, struct redist_in_nod
|
||||
{
|
||||
dbgf(dbgl, dbgt, "%s %s %s old=%d cnt=%d %s route=%s via=%s type=%s table=%d ifidx=%d metric=%d distance=%d flags=%X message=%X",
|
||||
func, misc1, misc2, zrn->old, zrn->cnt,
|
||||
(zrn->cnt > 1 || zrn->cnt < 0) ? "INVALID" : (zrn->old != zrn->cnt) ? "CHANGED" : "UNCHANGED",
|
||||
(zrn->cnt < 0) ? "INVALID" : (zrn->old != (!!zrn->cnt)) ? "CHANGED" : "UNCHANGED",
|
||||
netAsStr(&zrn->k.net), ipXAsStr(zrn->k.net.af, &zrn->k.via),
|
||||
zrn->k.inType < BMX6_ROUTE_MAX ? zapi_rt_dict[zrn->k.inType].sys2Name : memAsHexStringSep(&zrn->k.inType, 1, 0, NULL),
|
||||
zrn->k.inType < BMX6_ROUTE_MAX_KNOWN ? zapi_rt_dict[zrn->k.inType].sys2Name : memAsHexStringSep(&zrn->k.inType, 1, 0, NULL),
|
||||
zrn->k.table, zrn->k.ifindex, zrn->metric, zrn->distance, zrn->flags, zrn->message);
|
||||
}
|
||||
|
||||
@@ -97,7 +128,7 @@ void redist_rm_overlapping(struct avl_tree *redist_out_tree)
|
||||
if (is_ip_net_equal(&ovlp->k.net.ip, &routn->k.net.ip, ovlp->k.net.mask, routn->k.net.af)) {
|
||||
routn->new = 0;
|
||||
ovlp->minAggregatePrefixLen = XMAX(ovlp->minAggregatePrefixLen, routn->minAggregatePrefixLen);
|
||||
dbgf_track(DBGT_INFO, "disable overlapping net=%s in favor of net=%s",
|
||||
dbgf_all(DBGT_INFO, "disable overlapping net=%s in favor of net=%s",
|
||||
netAsStr(&routn->k.net), netAsStr(&ovlp->k.net));
|
||||
break;
|
||||
}
|
||||
@@ -174,8 +205,67 @@ void redist_rm_aggregatable(struct avl_tree *redist_out_tree)
|
||||
}
|
||||
}
|
||||
|
||||
struct redistr_opt_node *matching_redist_opt(struct redist_in_node *rin, struct avl_tree *redist_opt_tree, struct sys_route_dict *rt_dict)
|
||||
{
|
||||
struct redistr_opt_node *roptn;
|
||||
struct avl_node *ropti;
|
||||
|
||||
|
||||
for (ropti = NULL; (roptn = avl_iterate_item(redist_opt_tree, &ropti));) {
|
||||
|
||||
if (roptn->net.af && roptn->net.af != rin->k.net.af) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s AF", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (roptn->table != rin->k.table) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s table", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (roptn->bandwidth.val.u8 == 0) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s bandwidth", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rin->k.inType > BMX6_ROUTE_MAX_SUPP) {
|
||||
dbgf_all(DBGT_INFO, "skipping unsupported routeType=%d", rin->k.inType);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/*roptn->bmx6_redist_bits &&*/
|
||||
!roptn->bmx6_redist_all &&
|
||||
!bit_get(((uint8_t*) & roptn->bmx6_redist_bits),
|
||||
sizeof (roptn->bmx6_redist_bits)*8, rt_dict[rin->k.inType].sys2bmx)) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "skipping %s redist bits", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (roptn->bmx6_redist_sys && roptn->bmx6_redist_sys != rin->k.inType) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s redist sys=%d != %d", roptn->nameKey, roptn->bmx6_redist_sys, rin->k.inType);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((roptn->net.mask != MIN_REDIST_PREFIX ||
|
||||
roptn->netPrefixMin != DEF_REDIST_PREFIX_MIN ||
|
||||
roptn->netPrefixMax != DEF_REDIST_PREFIX_MAX)
|
||||
&& !(
|
||||
(roptn->netPrefixMax == TYP_REDIST_PREFIX_NET ?
|
||||
roptn->net.mask >= rin->k.net.mask : roptn->netPrefixMax >= rin->k.net.mask) &&
|
||||
(roptn->netPrefixMin == TYP_REDIST_PREFIX_NET ?
|
||||
roptn->net.mask <= rin->k.net.mask : roptn->netPrefixMin <= rin->k.net.mask) &&
|
||||
is_ip_net_equal(&roptn->net.ip, &rin->k.net.ip, XMIN(roptn->net.mask, rin->k.net.mask), roptn->net.af))) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "skipping %s prefix", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
return roptn;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *redist_in_tree, struct avl_tree *redist_opt_tree, struct sys_route_dict *rt_dict)
|
||||
{
|
||||
|
||||
@@ -187,12 +277,11 @@ IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *red
|
||||
struct avl_node *rii;
|
||||
|
||||
struct redistr_opt_node *roptn;
|
||||
struct avl_node *ropti;
|
||||
|
||||
struct redist_out_node *routn;
|
||||
struct avl_node *routi;
|
||||
|
||||
struct redist_out_node routf;
|
||||
struct redist_out_node routf;
|
||||
|
||||
for (routi = NULL; (routn = avl_iterate_item(redist_out_tree, &routi));) {
|
||||
routn->new = 0;
|
||||
@@ -201,54 +290,19 @@ IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *red
|
||||
|
||||
for (rii = NULL; (rin = avl_iterate_item(redist_in_tree, &rii));) {
|
||||
|
||||
for (ropti = NULL; (roptn = avl_iterate_item(redist_opt_tree, &ropti));) {
|
||||
ASSERTION(-502479, IMPLIES(rin->roptn, rin->roptn == matching_redist_opt(rin, redist_opt_tree, rt_dict)));
|
||||
|
||||
if (roptn->net.af && roptn->net.af != rin->k.net.af) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s AF", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
if ((roptn = rin->roptn ? rin->roptn : matching_redist_opt(rin, redist_opt_tree, rt_dict))) {
|
||||
|
||||
if (roptn->table != rin->k.table) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s table", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
memset(&routf, 0, sizeof (routf));
|
||||
|
||||
if (roptn->bandwidth.val.u8 == 0) {
|
||||
dbgf_all(DBGT_INFO, "skipping %s bandwidth", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/*roptn->bmx6_redist_bits &&*/
|
||||
!bit_get(((uint8_t*) & roptn->bmx6_redist_bits),
|
||||
sizeof (roptn->bmx6_redist_bits)*8, rt_dict[rin->k.inType].sys2bmx)) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "skipping %s redist bits", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((roptn->net.mask != MIN_REDIST_PREFIX ||
|
||||
roptn->netPrefixMin != DEF_REDIST_PREFIX_MIN ||
|
||||
roptn->netPrefixMax != DEF_REDIST_PREFIX_MAX)
|
||||
&& !(
|
||||
(roptn->netPrefixMax == TYP_REDIST_PREFIX_NET ?
|
||||
roptn->net.mask >= rin->k.net.mask : roptn->netPrefixMax >= rin->k.net.mask) &&
|
||||
(roptn->netPrefixMin == TYP_REDIST_PREFIX_NET ?
|
||||
roptn->net.mask <= rin->k.net.mask : roptn->netPrefixMin <= rin->k.net.mask) &&
|
||||
is_ip_net_equal(&roptn->net.ip, &rin->k.net.ip, XMIN(roptn->net.mask, rin->k.net.mask), roptn->net.af))) {
|
||||
|
||||
dbgf_all(DBGT_INFO, "skipping %s prefix", roptn->nameKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&routf, 0, sizeof (routf));
|
||||
|
||||
routf.k.bmx6_route_type = rt_dict[rin->k.inType].sys2bmx;
|
||||
routf.k.net = roptn->net.mask >= rin->k.net.mask ? roptn->net : rin->k.net;
|
||||
routf.k.bandwidth = roptn->bandwidth;
|
||||
routf.k.bmx6_route_type = rt_dict[rin->k.inType].sys2bmx;
|
||||
routf.k.net = roptn->net.mask >= rin->k.net.mask ? roptn->net : rin->k.net;
|
||||
routf.k.bandwidth = roptn->bandwidth;
|
||||
if ( roptn->tunInDev )
|
||||
strcpy(routf.k.tunInDev.str, roptn->tunInDev);
|
||||
routf.k.must_be_one = 1; // to let alv_next_item find the first one
|
||||
routf.minAggregatePrefixLen = roptn->minAggregatePrefixLen;
|
||||
routf.k.must_be_one = 1; // to let alv_next_item find the first one
|
||||
routf.minAggregatePrefixLen = roptn->minAggregatePrefixLen;
|
||||
|
||||
if (!(routn = avl_find_item(redist_out_tree, &routf.k))) {
|
||||
*(routn = debugMalloc(sizeof (routf), -300505)) = routf;
|
||||
@@ -264,8 +318,6 @@ IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *red
|
||||
|
||||
routn->new = 1;
|
||||
routn->minAggregatePrefixLen = XMAX(routn->minAggregatePrefixLen, roptn->minAggregatePrefixLen);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,9 +481,17 @@ int32_t opt_redist(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_
|
||||
} else if (!strcmp(c->opt->name, ARG_REDIST_HYSTERESIS)) {
|
||||
ron->hysteresis = c->val ? strtol(c->val, NULL, 10) : DEF_REDIST_HYSTERESIS;
|
||||
|
||||
} else if (!strcmp(c->opt->name, ARG_ROUTE_ALL)) {
|
||||
|
||||
ron->bmx6_redist_all = (c->val && strtol(c->val, NULL, 10) == 1 ) ? 1 : 0;
|
||||
|
||||
} else if (!strcmp(c->opt->name, ARG_ROUTE_SYS)) {
|
||||
|
||||
ron->bmx6_redist_sys = c->val ? strtol(c->val, NULL, 10) : 0;
|
||||
|
||||
} else {
|
||||
uint8_t t;
|
||||
for (t = 0; t < BMX6_ROUTE_MAX; t++) {
|
||||
for (t = 0; t <= BMX6_ROUTE_MAX_KNOWN; t++) {
|
||||
if (bmx6_rt_dict[t].sys2Name && !strcmp(c->opt->name, bmx6_rt_dict[t].sys2Name)) {
|
||||
bit_set((uint8_t*) &ron->bmx6_redist_bits,
|
||||
sizeof (ron->bmx6_redist_bits) * 8,
|
||||
|
18
redist.h
18
redist.h
@@ -86,7 +86,11 @@
|
||||
|
||||
#define NETWORK_NAME_LEN 32
|
||||
|
||||
#define HLP_ROUTE_TYPE "redistribute route type (mandatory to enable at least one type)"
|
||||
#define ARG_ROUTE_ALL "all"
|
||||
#define ARG_ROUTE_SYS "sys"
|
||||
|
||||
#define HLP_ROUTE_TYPE "redistribute bmx route type (mandatory to enable at least one type)"
|
||||
#define HLP_ROUTE_SYS "filter redistributed routes based on system id (ignored if unset, recommends: /all=1)"
|
||||
|
||||
|
||||
|
||||
@@ -122,16 +126,19 @@ struct redist_in_node {
|
||||
int8_t cnt;
|
||||
uint8_t old;
|
||||
uint32_t metric;
|
||||
uint8_t distance;
|
||||
uint8_t distance;
|
||||
struct redistr_opt_node *roptn;
|
||||
};
|
||||
|
||||
struct redistr_opt_node {
|
||||
char nameKey[NETWORK_NAME_LEN];
|
||||
struct net_key net;
|
||||
uint32_t bmx6_redist_bits;
|
||||
uint64_t bmx6_redist_bits;
|
||||
uint32_t hysteresis;
|
||||
uint32_t table;
|
||||
uint8_t netPrefixMin;
|
||||
uint8_t bmx6_redist_all;
|
||||
uint8_t bmx6_redist_sys;
|
||||
uint8_t netPrefixMin;
|
||||
uint8_t netPrefixMax;
|
||||
uint8_t minAggregatePrefixLen;
|
||||
FMETRIC_U8_T bandwidth;
|
||||
@@ -142,4 +149,5 @@ void redist_dbg(int8_t dbgl, int8_t dbgt, const char *func, struct redist_in_nod
|
||||
void update_tunXin6_net_adv_list(struct avl_tree *redist_out_tree, struct list_head *tunXin6_net_adv_list );
|
||||
IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *zroute_tree, struct avl_tree *redist_opt_tree, struct sys_route_dict *zapi_rt_dict);
|
||||
|
||||
int32_t opt_redist(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn, struct avl_tree *redist_opt_tree, uint8_t *changed);
|
||||
int32_t opt_redist(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn, struct avl_tree *redist_opt_tree, uint8_t *changed);
|
||||
struct redistr_opt_node *matching_redist_opt(struct redist_in_node *rin, struct avl_tree *redist_opt_tree, struct sys_route_dict *rt_dict);
|
100
schedule.c
100
schedule.c
@@ -39,6 +39,7 @@
|
||||
#include "plugin.h"
|
||||
#include "schedule.h"
|
||||
#include "allocate.h"
|
||||
#include "key.h"
|
||||
|
||||
|
||||
|
||||
@@ -65,29 +66,21 @@ void upd_time(struct timeval *precise_tv)
|
||||
|
||||
gettimeofday( &curr_tv, NULL );
|
||||
|
||||
IDM_T larger;
|
||||
if ( (larger=timercmp( &curr_tv, &acceptable_max_tv, > )) || timercmp( &curr_tv, &acceptable_min_tv, < ) ) {
|
||||
|
||||
if ( timercmp( &curr_tv, &acceptable_max_tv, > ) ) {
|
||||
if (larger)
|
||||
timersub( &curr_tv, &acceptable_max_tv, &diff_tv );
|
||||
else
|
||||
timersub( &acceptable_min_tv, &curr_tv, &diff_tv );
|
||||
|
||||
timersub( &curr_tv, &acceptable_max_tv, &diff_tv );
|
||||
timeradd( &start_time_tv, &diff_tv, &start_time_tv );
|
||||
|
||||
dbg_sys(DBGT_WARN, "critical system time drift detected: ++ca %ld s, %ld us! Correcting reference!",
|
||||
diff_tv.tv_sec, diff_tv.tv_usec );
|
||||
dbg_sys(DBGT_WARN, "critical system time drift detected: %s approx %ld s, %ld us! Correcting reference!",
|
||||
larger ? "++" : "--", diff_tv.tv_sec, diff_tv.tv_usec );
|
||||
|
||||
if ( diff_tv.tv_sec > CRITICAL_PURGE_TIME_DRIFT )
|
||||
purge_link_route_orig_nodes(NULL, NO, self);
|
||||
|
||||
} else if ( timercmp( &curr_tv, &acceptable_min_tv, < ) ) {
|
||||
|
||||
timersub( &acceptable_min_tv, &curr_tv, &diff_tv );
|
||||
timersub( &start_time_tv, &diff_tv, &start_time_tv );
|
||||
|
||||
dbg_sys(DBGT_WARN, "critical system time drift detected: --ca %ld s, %ld us! Correcting reference!",
|
||||
diff_tv.tv_sec, diff_tv.tv_usec );
|
||||
|
||||
if ( diff_tv.tv_sec > CRITICAL_PURGE_TIME_DRIFT )
|
||||
purge_link_route_orig_nodes(NULL, NO, self);
|
||||
|
||||
keyNodes_cleanup(KCPromoted, myKey);
|
||||
}
|
||||
|
||||
timersub( &curr_tv, &start_time_tv, &bmx_tv );
|
||||
@@ -104,10 +97,20 @@ void upd_bmx_time(struct timeval *tv)
|
||||
{
|
||||
static struct timeval tmp;
|
||||
|
||||
upd_time((tv = tv ? tv : &tmp));
|
||||
while (1) {
|
||||
upd_time((tv = tv ? tv : &tmp));
|
||||
|
||||
bmx_time = ( (tv->tv_sec * 1000) + (tv->tv_usec / 1000) );
|
||||
bmx_time_sec = tv->tv_sec;
|
||||
bmx_time = ( (tv->tv_sec * 1000) + (tv->tv_usec / 1000) );
|
||||
bmx_time_sec = tv->tv_sec;
|
||||
|
||||
if (bmx_time)
|
||||
break;
|
||||
else //Never return zero bmx_time. To Simplifying timeout processing.
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
|
||||
keyNode_fixTimeouts();
|
||||
}
|
||||
|
||||
|
||||
@@ -301,8 +304,6 @@ void wait4Event(TIME_T timeout)
|
||||
{
|
||||
TRACE_FUNCTION_CALL;
|
||||
static struct packet_buff pb;
|
||||
|
||||
TIME_T last_get_time_result = 0;
|
||||
|
||||
static uint32_t addr_len = sizeof (pb.i.addr);
|
||||
|
||||
@@ -335,15 +336,6 @@ loop4Event:
|
||||
//which should be removed before debugging
|
||||
//dbgf_all( DBGT_INFO, "timeout %d", timeout );
|
||||
|
||||
if ( bmx_time < last_get_time_result ) {
|
||||
|
||||
last_get_time_result = bmx_time;
|
||||
dbg_sys(DBGT_WARN, "detected Timeoverlap..." );
|
||||
|
||||
goto wait4Event_end;
|
||||
}
|
||||
|
||||
last_get_time_result = bmx_time;
|
||||
|
||||
if ( selected < 0 ) {
|
||||
static TIME_T last_interrupted_syscall = 0;
|
||||
@@ -378,28 +370,9 @@ loop4Event:
|
||||
|
||||
goto loop4Event;
|
||||
}
|
||||
|
||||
/*
|
||||
// check for changed interface status...
|
||||
if ( FD_ISSET( ifevent_sk, &tmp_wait_set ) ) {
|
||||
|
||||
dbgf_track(DBGT_INFO, "detected changed interface status! Going to check interfaces!");
|
||||
|
||||
recv_ifevent_netlink_sk( );
|
||||
keyNodes_block_and_sync(0, YES);
|
||||
|
||||
dev_check2();
|
||||
|
||||
|
||||
//do NOT delay checking of interfaces to not miss ifdown/up of interfaces !!
|
||||
if (kernel_if_config() ) //just call if changed!
|
||||
dev_check(YES);
|
||||
|
||||
|
||||
goto wait4Event_end;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// check for received packets...
|
||||
struct avl_node *it = NULL;
|
||||
while ((pb.i.iif = avl_iterate_item(&dev_ip_tree, &it))) {
|
||||
@@ -414,7 +387,7 @@ loop4Event:
|
||||
errno=0;
|
||||
pb.i.length = recvfrom( pb.i.iif->rx_mcast_sock, pb.p.data,
|
||||
sizeof(pb.p.data) - 1, 0,
|
||||
(struct sockaddr *)&pb.i.addr, &addr_len );
|
||||
(struct sockaddr *)&pb.i.addr, (socklen_t*)&addr_len );
|
||||
|
||||
if ( pb.i.length < 0 && ( errno == EWOULDBLOCK || errno == EAGAIN ) ) {
|
||||
|
||||
@@ -440,7 +413,7 @@ loop4Event:
|
||||
errno=0;
|
||||
pb.i.length = recvfrom( pb.i.iif->rx_fullbrc_sock, pb.p.data,
|
||||
sizeof(pb.p.data) - 1, 0,
|
||||
(struct sockaddr *)&pb.i.addr, &addr_len );
|
||||
(struct sockaddr *)&pb.i.addr, (socklen_t*)&addr_len );
|
||||
|
||||
if ( pb.i.length < 0 && ( errno == EWOULDBLOCK || errno == EAGAIN ) ) {
|
||||
|
||||
@@ -503,7 +476,7 @@ loop4Event:
|
||||
if ( tv_stamp == NULL )
|
||||
ioctl( pb.i.iif->unicast_sock, SIOCGSTAMP, &(pb.i.tv_stamp) );
|
||||
else
|
||||
timercpy( tv_stamp, &(pb.i.tv_stamp) );
|
||||
timercpy( &(pb.i.tv_stamp), tv_stamp );
|
||||
|
||||
rx_packet( &pb );
|
||||
|
||||
@@ -585,12 +558,29 @@ loop4ActiveClients:
|
||||
}
|
||||
|
||||
wait4Event_end:
|
||||
|
||||
|
||||
keyNodes_block_and_sync(0, YES);
|
||||
|
||||
dbgf_all( DBGT_INFO, "end of function");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
IDM_T doNowOrLater(TIME_T *nextScheduled, TIME_T interval, IDM_T now)
|
||||
{
|
||||
|
||||
if (((TIME_T) (*nextScheduled - (bmx_time + 1))) >= ((TIME_T) interval) || now) {
|
||||
|
||||
*nextScheduled = interval +
|
||||
((((TIME_T) ((*nextScheduled + interval) - (bmx_time + 1))) >= ((TIME_T) interval)) ?
|
||||
bmx_time : *nextScheduled);
|
||||
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
void init_schedule( void ) {
|
||||
gettimeofday( &start_time_tv, NULL );
|
||||
curr_tv = start_time_tv;
|
||||
|
19
schedule.h
19
schedule.h
@@ -25,24 +25,6 @@ struct task_node {
|
||||
void *data; //NULL or pointer to data to be given to function. Data will be freed after functio is called.
|
||||
};
|
||||
|
||||
#define TX_TASK_MAX_DATA_LEN 20
|
||||
|
||||
struct tx_task_content {
|
||||
struct dev_node *dev; // the outgoing interface to be used for transmitting
|
||||
LinkDevNode *linkDev;
|
||||
uint8_t data[TX_TASK_MAX_DATA_LEN];
|
||||
uint16_t type;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tx_task_node {
|
||||
struct list_node list;
|
||||
|
||||
struct tx_task_content task;
|
||||
uint16_t frame_msgs_length;
|
||||
int16_t tx_iterations;
|
||||
TIME_T considered_ts;
|
||||
TIME_T send_ts;
|
||||
};
|
||||
|
||||
void upd_time( struct timeval *precise_tv );
|
||||
|
||||
@@ -54,3 +36,4 @@ IDM_T task_remove(void (* task) (void *), void *data);
|
||||
TIME_T task_next( void );
|
||||
void wait4Event( TIME_T timeout );
|
||||
|
||||
IDM_T doNowOrLater(TIME_T *nextScheduled, TIME_T interval, IDM_T now);
|
||||
|
90
sec.h
90
sec.h
@@ -40,15 +40,15 @@
|
||||
#define ARG_DESC_SIGN "descSignLen"
|
||||
#define MIN_DESC_SIGN 512
|
||||
#define MAX_DESC_SIGN 4096
|
||||
#define DEF_DESC_SIGN 3072
|
||||
#define DEF_DESC_SIGN 2048
|
||||
#define HLP_DESC_SIGN "sign own descriptions with given RSA key length"
|
||||
|
||||
|
||||
#define ARG_DESC_VERIFY "descVerificationLen"
|
||||
#define MIN_DESC_VERIFY 512
|
||||
#define MAX_DESC_VERIFY 4096
|
||||
#define DEF_DESC_VERIFY 4096
|
||||
#define HLP_DESC_VERIFY "verify description signatures up-to given RSA key length"
|
||||
#define ARG_DESC_VERIFY_MAX "descVerificationLenMax"
|
||||
#define MIN_DESC_VERIFY_MAX 512
|
||||
#define MAX_DESC_VERIFY_MAX 4096
|
||||
#define DEF_DESC_VERIFY_MAX 4096
|
||||
#define HLP_DESC_VERIFY_MAX "verify description signatures up-to given RSA key length"
|
||||
|
||||
#define ARG_PACKET_SIGN "packetSignLen"
|
||||
#define MIN_PACKET_SIGN 0
|
||||
@@ -62,7 +62,7 @@ extern int32_t packetSigning;
|
||||
// assuming 70 days to crack RSA512 keys (2009!) with a single dual-core machine,
|
||||
// means can be cracked in
|
||||
// ~6000 secs with ~1000 machines, or
|
||||
// ~600 secs with ~10000 machines, or
|
||||
// ~600 secs with ~10000 machines, or
|
||||
// ~60 secs with ~100000 machines
|
||||
// However, this would be for RSA512 but RSA896 is used by default!!:
|
||||
#define MIN_PACKET_SIGN_LT (60) // one minute, needs ~100000 machines to crack RSA512 before end of life
|
||||
@@ -72,12 +72,17 @@ extern int32_t packetSigning;
|
||||
|
||||
|
||||
|
||||
#define ARG_PACKET_VERIFY "packetVerification"
|
||||
#define MIN_PACKET_VERIFY 0
|
||||
#define MAX_PACKET_VERIFY 4096
|
||||
#define DEF_PACKET_VERIFY 1024
|
||||
#define HLP_PACKET_VERIFY "verify incoming packet signature up-to given RSA key length"
|
||||
#define ARG_PACKET_VERIFY_MAX "packetVerificationLenMax"
|
||||
#define MIN_PACKET_VERIFY_MAX 0
|
||||
#define MAX_PACKET_VERIFY_MAX 4096
|
||||
#define DEF_PACKET_VERIFY_MAX 2048
|
||||
#define HLP_PACKET_VERIFY_MAX "verify incoming packet signature up-to given RSA key length"
|
||||
|
||||
#define ARG_PACKET_VERIFY_MIN "packetVerificationLenMax"
|
||||
#define MIN_PACKET_VERIFY_MIN 0
|
||||
#define MAX_PACKET_VERIFY_MIN 4096
|
||||
#define DEF_PACKET_VERIFY_MIN 0
|
||||
#define HLP_PACKET_VERIFY_MIN "require incoming packet signature of at least given RSA key length"
|
||||
|
||||
extern CRYPTKEY_T *my_PubKey;
|
||||
extern CRYPTKEY_T *my_PktKey;
|
||||
@@ -89,8 +94,8 @@ extern CRYPTKEY_T *my_PktKey;
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct dsc_msg_pubkey {
|
||||
uint8_t type;
|
||||
uint8_t key[];
|
||||
uint8_t type;
|
||||
uint8_t key[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -100,30 +105,8 @@ struct dsc_msg_pubkey {
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct dsc_msg_signature {
|
||||
uint8_t type;
|
||||
uint8_t signature[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define FRAME_MSG_SIGNATURE_FORMAT { \
|
||||
{FIELD_TYPE_STRING_BINARY, -1, 8*sizeof(CRYPTSHA1_T), 1, FIELD_RELEVANCE_HIGH, "dhash"}, \
|
||||
{FIELD_TYPE_UINT, -1, 8*sizeof(uint8_t), 1, FIELD_RELEVANCE_HIGH, "type"}, \
|
||||
{FIELD_TYPE_STRING_BINARY, -1, 0, 1, FIELD_RELEVANCE_HIGH, "signature" }, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct frame_msg_signature {
|
||||
CRYPTSHA1_T dhash;
|
||||
uint8_t type;
|
||||
uint8_t signature[];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define DESCRIPTION_MSG_SHA_FORMAT { \
|
||||
{FIELD_TYPE_UINT, -1, 32, 0, FIELD_RELEVANCE_HIGH, "dataLen"}, \
|
||||
{FIELD_TYPE_STRING_BINARY, -1, 8*sizeof(SHA1_T), 1, FIELD_RELEVANCE_HIGH, "dataSha"}, \
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct dsc_msg_sha {
|
||||
uint32_t dataLen;
|
||||
CRYPTSHA1_T dataSha;
|
||||
uint8_t type;
|
||||
uint8_t signature[];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -134,20 +117,29 @@ struct dsc_msg_sha {
|
||||
FIELD_FORMAT_END }
|
||||
|
||||
struct dsc_msg_trust {
|
||||
CRYPTSHA1_T globalId;
|
||||
uint16_t reserved;
|
||||
CRYPTSHA1_T globalId;
|
||||
uint16_t reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
void free_internalNeighId(OGM_DEST_T ini);
|
||||
OGM_DEST_T allocate_internalNeighId(struct neigh_node *nn);
|
||||
struct dsc_msg_version {
|
||||
uint8_t comp_version;
|
||||
uint8_t capabilities;
|
||||
|
||||
DESC_SQN_T descSqn;
|
||||
uint32_t codeRevision;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
GLOBAL_ID_T *get_desc_id(uint8_t *desc_adv, uint32_t desc_len, struct dsc_msg_signature **signpp, struct dsc_msg_version **verspp);
|
||||
|
||||
struct content_node *test_description_signature(uint8_t *desc, uint32_t desc_len);
|
||||
|
||||
IDM_T setted_pubkey(struct desc_content *dc, uint8_t type, GLOBAL_ID_T *globalId);
|
||||
IDM_T supportedKnownKey(CRYPTSHA1_T *pkhash);
|
||||
INT_NEIGH_ID_T allocate_internalNeighId(struct neigh_node *nn);
|
||||
void free_internalNeighId(INT_NEIGH_ID_T ini);
|
||||
uint32_t *init_neighTrust(struct orig_node *on);
|
||||
IDM_T verify_neighTrust(struct orig_node *on, struct neigh_node *neigh);
|
||||
|
||||
IDM_T supported_pubkey( CRYPTSHA1_T *pkhash );
|
||||
IDM_T setted_pubkey(struct dhash_node *dhn, uint8_t type, GLOBAL_ID_T *globalId);
|
||||
|
||||
int process_signature(int32_t sig_msg_length, struct dsc_msg_signature *sig_msg, uint8_t *desc_frame, int32_t desc_frame_len, struct dsc_msg_pubkey *pkey_msg);
|
||||
|
||||
void init_sec( void );
|
||||
void cleanup_sec( void );
|
||||
void init_sec(void);
|
||||
void cleanup_sec(void);
|
||||
|
64
tools.c
64
tools.c
@@ -272,7 +272,7 @@ void init_set_bits_table256(void)
|
||||
|
||||
// clears byte range between and including begin and end
|
||||
// accept overlap of begin and end
|
||||
void byte_clear(uint8_t *array, uint16_t array_size, uint16_t begin, uint16_t end)
|
||||
void byte_clear(uint8_t *array, uint32_t array_size, uint32_t begin, uint32_t end)
|
||||
{
|
||||
|
||||
assertion(-500436, (array_size % 2 == 0));
|
||||
@@ -300,21 +300,21 @@ uint8_t bits_count(uint32_t v)
|
||||
return c;
|
||||
}
|
||||
|
||||
uint8_t bit_get(const uint8_t *array, const uint16_t array_bit_size, uint16_t bit)
|
||||
uint8_t bit_get(const uint8_t *array, const uint32_t array_bit_size, uint32_t bit)
|
||||
{
|
||||
bit = bit % array_bit_size;
|
||||
|
||||
uint16_t byte_pos = bit / 8;
|
||||
uint32_t byte_pos = bit / 8;
|
||||
uint8_t bit_pos = bit % 8;
|
||||
|
||||
return (array[byte_pos] & (0x01 << (7 - bit_pos))) ? 1 : 0;
|
||||
}
|
||||
|
||||
void bit_set(uint8_t *array, uint16_t array_bit_size, uint16_t bit, IDM_T value)
|
||||
void bit_set(uint8_t *array, uint32_t array_bit_size, uint32_t bit, IDM_T value)
|
||||
{
|
||||
bit = bit % array_bit_size;
|
||||
|
||||
uint16_t byte_pos = bit / 8;
|
||||
uint32_t byte_pos = bit / 8;
|
||||
uint8_t bit_pos = bit % 8;
|
||||
|
||||
if (value)
|
||||
@@ -326,22 +326,23 @@ void bit_set(uint8_t *array, uint16_t array_bit_size, uint16_t bit, IDM_T value)
|
||||
}
|
||||
|
||||
|
||||
uint16_t bits_get(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, uint16_t end_bit)
|
||||
uint32_t bits_get(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask)
|
||||
{
|
||||
assertion(-501058, ((uint16_t) (end_bit - begin_bit)) < array_bit_size);
|
||||
assertion(-502491, (array_bit_size % 8 == 0));
|
||||
assertion(-502492, ((range_mask & (end_bit - beg_bit)) < array_bit_size));
|
||||
|
||||
uint16_t begin_byte = (begin_bit % array_bit_size) / 8;
|
||||
uint16_t end_byte = (end_bit % array_bit_size) / 8;
|
||||
uint16_t array_byte_size = array_bit_size / 8;
|
||||
uint32_t begin_byte = (beg_bit % array_bit_size) / 8;
|
||||
uint32_t end_byte = (end_bit % array_bit_size) / 8;
|
||||
uint32_t array_byte_size = array_bit_size / 8;
|
||||
|
||||
uint16_t counted = 0;
|
||||
uint16_t pos = begin_byte;
|
||||
uint32_t counted = 0;
|
||||
uint32_t pos = begin_byte;
|
||||
|
||||
do {
|
||||
uint8_t val = array[pos];
|
||||
|
||||
if (pos == begin_byte)
|
||||
val = val & (0xFF >> (begin_bit % 8));
|
||||
val = val & (0xFF >> (beg_bit % 8));
|
||||
|
||||
if (pos == end_byte)
|
||||
val = val & (0xFF << (7-(end_bit % 8)));
|
||||
@@ -357,19 +358,19 @@ uint16_t bits_get(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, u
|
||||
|
||||
|
||||
// clears bit range between and including begin and end
|
||||
void bits_clear(uint8_t *array, uint16_t array_bit_size, uint16_t beg_bit, uint16_t end_bit, uint16_t range_mask)
|
||||
void bits_clear(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask)
|
||||
{
|
||||
assertion(-500435, (array_bit_size % 8 == 0));
|
||||
assertion(-501060, ((range_mask & (end_bit - beg_bit)) < array_bit_size));
|
||||
|
||||
uint16_t array_byte_size = array_bit_size / 8;
|
||||
uint32_t array_byte_size = array_bit_size / 8;
|
||||
|
||||
|
||||
beg_bit = beg_bit % array_bit_size;
|
||||
end_bit = end_bit % array_bit_size;
|
||||
|
||||
uint16_t beg_byte = beg_bit/8;
|
||||
uint16_t end_byte = end_bit/8;
|
||||
uint32_t beg_byte = beg_bit/8;
|
||||
uint32_t end_byte = end_bit/8;
|
||||
|
||||
|
||||
if (beg_byte == end_byte ? (beg_bit % 8) > (end_bit % 8) : (beg_byte + 1) % array_byte_size != end_byte)
|
||||
@@ -393,15 +394,18 @@ uint16_t bits_get(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, u
|
||||
}
|
||||
}
|
||||
|
||||
char* bits_print(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, uint16_t end_bit)
|
||||
char* bits_print(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask)
|
||||
{
|
||||
assertion(-502493, (array_bit_size % 8 == 0));
|
||||
assertion(-502494, ((range_mask & (end_bit - beg_bit)) < array_bit_size));
|
||||
|
||||
#define BITS_PRINT_MAX 256
|
||||
assertion(-501059, ((uint16_t) (end_bit - begin_bit)) < array_bit_size);
|
||||
assertion(-501059, ((uint32_t) (end_bit - beg_bit)) < array_bit_size);
|
||||
|
||||
uint16_t c = 0;
|
||||
static char output[BITS_PRINT_MAX + 4];
|
||||
|
||||
uint16_t pos = (begin_bit % array_bit_size);
|
||||
uint32_t pos = (beg_bit % array_bit_size);
|
||||
|
||||
do {
|
||||
sprintf(&output[c], "%s", bit_get(array, array_bit_size, pos) ? "1" : "0");
|
||||
@@ -422,9 +426,9 @@ char* bits_print(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, ui
|
||||
|
||||
|
||||
|
||||
uint8_t is_zero(void *data, int len)
|
||||
uint8_t is_zero(void *data, int32_t len)
|
||||
{
|
||||
int i;
|
||||
int32_t i;
|
||||
char *d = data;
|
||||
for (i = 0; i < len && !d[i]; i++);
|
||||
|
||||
@@ -579,6 +583,22 @@ void wordCopy( char *out, char *in ) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *find_array_data(uint8_t *arr, uint32_t arrLen, uint8_t *element, uint32_t elemLen) {
|
||||
|
||||
uint32_t p;
|
||||
|
||||
if (!arr || !arrLen || !element || !elemLen)
|
||||
return NULL;
|
||||
|
||||
for(p=0; p < arrLen; p+=elemLen ) {
|
||||
|
||||
if ( !memcmp(&arr[p], element, elemLen) )
|
||||
return &arr[p];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_UNUSED
|
||||
|
||||
|
13
tools.h
13
tools.h
@@ -67,17 +67,17 @@ float fast_inverse_sqrt(float x);
|
||||
|
||||
uint32_t rand_num(const uint32_t limit);
|
||||
|
||||
void byte_clear(uint8_t *array, uint16_t array_size, uint16_t begin, uint16_t range);
|
||||
void byte_clear(uint8_t *array, uint32_t array_size, uint32_t begin, uint32_t end);
|
||||
uint8_t bits_count(uint32_t v);
|
||||
uint8_t bit_get(const uint8_t *array, const uint16_t array_bit_size, uint16_t bit);
|
||||
uint8_t bit_get(const uint8_t *array, const uint32_t array_bit_size, uint32_t bit);
|
||||
|
||||
void bit_set(uint8_t *array, uint16_t array_bit_size, uint16_t bit, IDM_T value);
|
||||
void bit_set(uint8_t *array, uint32_t array_bit_size, uint32_t bit, IDM_T value);
|
||||
|
||||
uint16_t bits_get(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, uint16_t end_bit);
|
||||
uint32_t bits_get(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask);
|
||||
|
||||
void bits_clear(uint8_t *array, uint16_t array_bit_size, uint16_t beg_bit, uint16_t end_bit, uint16_t range_mask);
|
||||
void bits_clear(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask);
|
||||
|
||||
char* bits_print(uint8_t *array, uint16_t array_bit_size, uint16_t begin_bit, uint16_t end_bit);
|
||||
char* bits_print(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask);
|
||||
|
||||
|
||||
uint8_t is_zero(void *data, int len);
|
||||
@@ -91,6 +91,7 @@ int32_t check_file(char *path, uint8_t regular, uint8_t read, uint8_t write, uin
|
||||
int32_t check_dir( char *path, uint8_t create, uint8_t write );
|
||||
int32_t rm_dir_content(char* dir_name, char* prefix);
|
||||
|
||||
uint8_t *find_array_data(uint8_t *arr, uint32_t arrLen, uint8_t *element, uint32_t elemLen);
|
||||
|
||||
void init_tools(void);
|
||||
|
||||
|
41
z.c
41
z.c
@@ -98,14 +98,14 @@ int32_t z_compress( uint8_t *src, int32_t slen, uint8_t **dst, uint32_t dpos, ui
|
||||
|
||||
//decompress:
|
||||
/*
|
||||
* on success and when finished, returns new compressed size and adds to (*dst) + dpos
|
||||
* Therefore src and *dst can point to same memory area.
|
||||
* on failure returns -1 and (*dst) is untouched
|
||||
* if dst == NULL then dst is untouched
|
||||
* on success and when finished, returns new decompressed size and adds to (*dstA) + dpos
|
||||
* Therefore src and *dstA can point to same memory area.
|
||||
* on failure returns -1 and (*dstA) is untouched
|
||||
* if dstA == NULL then dstA is untouched
|
||||
*/
|
||||
int32_t z_decompress( uint8_t *src, uint32_t slen, uint8_t **dst, uint32_t dpos) {
|
||||
int32_t z_decompress( uint8_t *src, uint32_t slen, uint8_t *dstB, uint32_t dstBlen)
|
||||
{
|
||||
|
||||
uint8_t *tmp = NULL;
|
||||
int32_t tlen = 0;
|
||||
int z_ret;
|
||||
|
||||
@@ -117,33 +117,22 @@ int32_t z_decompress( uint8_t *src, uint32_t slen, uint8_t **dst, uint32_t dpos)
|
||||
strm.avail_in = slen;
|
||||
strm.next_in = (Bytef*)src;
|
||||
|
||||
do {
|
||||
tmp = debugRealloc(tmp, tlen + Z_CHUNK_SIZE, -300576);
|
||||
strm.avail_out = dstBlen;
|
||||
strm.next_out = dstB;
|
||||
|
||||
strm.avail_out = Z_CHUNK_SIZE;
|
||||
strm.next_out = tmp;
|
||||
if ((((z_ret = inflate(&strm, Z_NO_FLUSH)) != Z_OK) && z_ret != Z_STREAM_END && strm.avail_out == 0)) {
|
||||
// if (err==Z_STREAM_ERROR || err==Z_NEED_DICT || err==Z_DATA_ERROR || err==Z_MEM_ERROR) {
|
||||
dbgf_sys(DBGT_ERR, "slen=%d tlen=%d avaoi_out=%d z_ret=%d error: %s ???", slen, tlen, strm.avail_out, z_ret, strerror(errno));
|
||||
tlen = FAILURE;
|
||||
|
||||
if (tlen >= (INT32_MAX - Z_CHUNK_SIZE) || (((z_ret=inflate(&strm, Z_NO_FLUSH)) != Z_OK) && z_ret != Z_STREAM_END)) {
|
||||
// if (err==Z_STREAM_ERROR || err==Z_NEED_DICT || err==Z_DATA_ERROR || err==Z_MEM_ERROR) {
|
||||
dbgf_sys(DBGT_ERR, "slen=%d tlen=%d z_ret=%d error: %s ???", slen, tlen, z_ret, strerror(errno));
|
||||
tlen = FAILURE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
tlen += (Z_CHUNK_SIZE - strm.avail_out);
|
||||
|
||||
} while (strm.avail_out == 0);
|
||||
tlen += (dstBlen - strm.avail_out);
|
||||
}
|
||||
|
||||
// clean up and return:
|
||||
(void)inflateEnd(&strm);
|
||||
|
||||
if (dst && tmp && tlen > 0) {
|
||||
*dst = debugRealloc(*dst, dpos + tlen, -300577);
|
||||
memcpy( (*dst) + dpos, tmp, tlen);
|
||||
}
|
||||
|
||||
if(tmp)
|
||||
debugFree(tmp, -300578);
|
||||
|
||||
dbgf(tlen>0?DBGL_CHANGES:DBGL_SYS, tlen>0?DBGT_INFO:DBGT_ERR, "slen=%d tlen=%d", slen, tlen);
|
||||
|
||||
|
4
z.h
4
z.h
@@ -15,8 +15,8 @@
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define Z_CHUNK_SIZE 16384
|
||||
#define Z_CHUNK_SIZE (2*16384)
|
||||
|
||||
|
||||
int32_t z_compress( uint8_t *src, int32_t slen, uint8_t **dst, uint32_t dpos, uint8_t *darr, int32_t darr_max_size);
|
||||
int32_t z_decompress( uint8_t *src, uint32_t len, uint8_t **dst, uint32_t dst_pos);
|
||||
int32_t z_decompress(uint8_t *src, uint32_t slen, uint8_t *dstB, uint32_t dstBlen);
|
||||
|
Reference in New Issue
Block a user