diff --git a/Makefile b/Makefile deleted file mode 100644 index ffdcf1a5..00000000 --- a/Makefile +++ /dev/null @@ -1,800 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - -# Main Makefile.am for utun - root directory configuration - -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/utun -pkgincludedir = $(includedir)/utun -pkglibdir = $(libdir)/utun -pkglibexecdir = $(libexecdir)/utun -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = x86_64-pc-linux-gnu -host_triplet = x86_64-pc-linux-gnu -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_$(V)) -am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir distdir-am dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ - config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \ - $(top_srcdir)/build-aux/config.guess \ - $(top_srcdir)/build-aux/config.sub \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/missing build-aux/ar-lib \ - build-aux/compile build-aux/config.guess build-aux/config.sub \ - build-aux/depcomp build-aux/install-sh build-aux/missing -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -# Exists only to be overridden by the user if desired. -AM_DISTCHECK_DVI_TARGET = dvi -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} '/home/vnc1/proj/utun3/build-aux/missing' aclocal-1.16 -AMTAR = $${TAR-tar} -AM_DEFAULT_VERBOSITY = 1 -AR = ar -AUTOCONF = ${SHELL} '/home/vnc1/proj/utun3/build-aux/missing' autoconf -AUTOHEADER = ${SHELL} '/home/vnc1/proj/utun3/build-aux/missing' autoheader -AUTOMAKE = ${SHELL} '/home/vnc1/proj/utun3/build-aux/missing' automake-1.16 -AWK = mawk -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -CPPFLAGS = -CSCOPE = cscope -CTAGS = ctags -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -ECHO_C = -ECHO_N = -n -ECHO_T = -ETAGS = etags -EXEEXT = -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LDFLAGS = -LIBOBJS = -LIBS = -LTLIBOBJS = -MAKEINFO = ${SHELL} '/home/vnc1/proj/utun3/build-aux/missing' makeinfo -MKDIR_P = /usr/bin/mkdir -p -OBJEXT = o -PACKAGE = utun -PACKAGE_BUGREPORT = https://github.com/anomalyco/utun3/issues -PACKAGE_NAME = utun -PACKAGE_STRING = utun 2.0.0 -PACKAGE_TARNAME = utun -PACKAGE_URL = -PACKAGE_VERSION = 2.0.0 -PATH_SEPARATOR = : -RANLIB = ranlib -SET_MAKE = -SHELL = /bin/bash -STRIP = -TUN_LIBS = -VERSION = 2.0.0 -abs_builddir = /home/vnc1/proj/utun3 -abs_srcdir = /home/vnc1/proj/utun3 -abs_top_builddir = /home/vnc1/proj/utun3 -abs_top_srcdir = /home/vnc1/proj/utun3 -ac_ct_AR = ar -ac_ct_CC = gcc -am__include = include -am__leading_dot = . -am__quote = -am__tar = $${TAR-tar} chof - "$$tardir" -am__untar = $${TAR-tar} xf - -bindir = ${exec_prefix}/bin -build = x86_64-pc-linux-gnu -build_alias = -build_cpu = x86_64 -build_os = linux-gnu -build_vendor = pc -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host = x86_64-pc-linux-gnu -host_alias = -host_cpu = x86_64 -host_os = linux-gnu -host_vendor = pc -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = ${SHELL} /home/vnc1/proj/utun3/build-aux/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -mandir = ${datarootdir}/man -mkdir_p = $(MKDIR_P) -oldincludedir = /usr/include -pdfdir = ${docdir} -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -runstatedir = ${localstatedir}/run -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = . -sysconfdir = ${prefix}/etc -target_alias = -top_build_prefix = -top_builddir = . -top_srcdir = . - -# Order matters: lib -> src -> tests (tests depend on src objects) -SUBDIRS = lib src tests -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-zstd: distdir - tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - *.tar.zst*) \ - zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile config.h -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-local mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) all install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-am clean clean-cscope clean-generic \ - clean-local cscope cscopelist-am ctags ctags-am dist dist-all \ - dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip dist-zstd distcheck distclean distclean-generic \ - distclean-hdr distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Clean build directory -clean-local: - -rm -rf build/ - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/control_server.c b/src/control_server.c index d45ddea2..b99fa30b 100644 --- a/src/control_server.c +++ b/src/control_server.c @@ -11,6 +11,7 @@ #include "tun_if.h" #include "route_lib.h" #include "route_bgp.h" +#include "route_node.h" #include "pkt_normalizer.h" #include "../tools/etcpmon/etcpmon_protocol.h" #include "../lib/u_async.h" @@ -96,8 +97,19 @@ static void send_metrics(struct control_server* server, struct control_client* c static void send_debug_config(struct control_server* server, struct control_client* client, uint8_t seq_id); static void send_error(struct control_client* client, uint8_t error_code, const char* msg, uint8_t seq_id); +static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id); +static void send_single_node_info(struct control_server* server, struct control_client* client, struct NODEINFO_Q* nq); +static int control_client_send(struct control_server* server, struct control_client* client, uint8_t* dgram, uint16_t len); + static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instance, uint64_t peer_id); +/* From route_bgp.c */ +int nodeinfo_dyn_size(struct NODEINFO* node); + +/* ETCP ID/subcmd constants for BGP_NODEINFO_PACKET (from route_bgp.h) */ +#define CTRL_BGP_CMD 0x01 +#define CTRL_BGP_SUBCMD 0x04 + /* ============================================================================ * Server Initialization * ============================================================================ */ @@ -400,13 +412,26 @@ static void accept_callback(socket_t fd, void* arg) { client->fd = client_fd; client->server = server; /* Store back pointer to server */ -// client->connected = 1; client->selected_peer_id = 0; - + + client->output_queue = queue_new(server->ua, 0, 0, 0, "ctrl_out"); + if (!client->output_queue) { + DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to create output queue for client"); + u_free(client); +#ifdef _WIN32 + closesocket(client_fd); +#else + close(client_fd); +#endif + return; + } + client->subscribed_nodes = 0; + client->write_registered = 0; + /* Register with uasync */ client->socket_id = uasync_add_socket_t(server->ua, client_fd, client_read_callback, - NULL, /* write callback - not needed for now */ + client_write_callback, client_except_callback, client); @@ -544,9 +569,44 @@ static void client_read_callback(socket_t fd, void* arg) { } static void client_write_callback(socket_t fd, void* arg) { - /* Not used for now - writes are immediate */ + struct control_client* client = (struct control_client*)arg; + struct control_server* server = client->server; + struct ll_queue* q = client->output_queue; + + while (q->head) { + struct ll_entry* entry = q->head; + +#ifdef _WIN32 + int sent = send(fd, (const char*)entry->dgram, entry->len, 0); + if (sent == SOCKET_ERROR) { + int err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) { + DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Client send error: %d, closing", err); + close_client(server, client); + return; + } + return; + } +#else + ssize_t sent = send(fd, entry->dgram, entry->len, 0); + if (sent < 0) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Client send error: %s, closing", strerror(errno)); + close_client(server, client); + return; + } + return; + } +#endif + if ((size_t)sent < entry->len) { entry->dgram += sent; entry->len -= (uint16_t)sent; q->total_bytes -= (size_t)sent; return; } + + struct ll_entry* e = queue_data_get(q); + queue_dgram_free(e); queue_entry_free(e); + } + + uasync_set_socket_write(server->ua, client->socket_id, 0); + client->write_registered = 0; (void)fd; - (void)arg; } static void client_except_callback(socket_t fd, void* arg) { @@ -560,6 +620,21 @@ static void client_except_callback(socket_t fd, void* arg) { (void)fd; } +static int control_client_send(struct control_server* server, struct control_client* client, uint8_t* dgram, uint16_t len) { + (void)server; + if (!client || !client->output_queue || !dgram || len == 0) return -1; + struct ll_entry* entry = queue_entry_new(0); + if (!entry) { DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to allocate output queue entry"); return -1; } + entry->dgram = dgram; + entry->len = len; + entry->int_len = len; + queue_data_put(client->output_queue, entry); + if (!client->write_registered) { + uasync_set_socket_write(client->server->ua, client->socket_id, 1); + client->write_registered = 1; + } + return 0; +} static void close_client(struct control_server* server, struct control_client* client) { if (!server || !client) return; @@ -583,7 +658,9 @@ static void close_client(struct control_server* server, struct control_client* c close(client->fd); } #endif - + + if (client->output_queue) { queue_free(client->output_queue); client->output_queue = NULL; } + /* Remove from list */ struct control_client** curr = &server->clients; while (*curr) { @@ -614,7 +691,7 @@ static void handle_client_data(struct control_server* server, struct control_cli close_client(server, client); return; } - if (hdr->type < ETCPMON_CMD_LIST_CONN || hdr->type > ETCPMON_CMD_SET_DEBUG_CONFIG) { + if (hdr->type < ETCPMON_CMD_LIST_CONN || hdr->type > ETCPMON_CMD_SUBSCRIBE_NODES) { DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Invalid command type from client: 0x%02X", hdr->type); close_client(server, client); return; @@ -721,6 +798,17 @@ static void handle_client_data(struct control_server* server, struct control_cli } break; + case ETCPMON_CMD_SUBSCRIBE_NODES: + client->subscribed_nodes = 1; + if (server->log_file) { + fprintf(server->log_file, "%llu: [LOG] Client subscribed to node updates\n", + (unsigned long long)get_timestamp_ms()); + fflush(server->log_file); + } + DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Client subscribed to node updates"); + control_server_send_node_list(server, client, req_seq); + break; + case ETCPMON_CMD_DISCONNECT: if (server->log_file) { fprintf(server->log_file, "%llu: [LOG] Client requested disconnect\n", @@ -795,13 +883,7 @@ static void send_conn_list(struct control_server* server, struct control_client* fflush(server->log_file); } -#ifdef _WIN32 - send(client->fd, (const char*)buffer, rsp_size, 0); -#else - send(client->fd, buffer, rsp_size, 0); -#endif - - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); } static void send_socket_list(struct control_server* server, struct control_client* client, uint8_t seq_id) { @@ -819,8 +901,7 @@ static void send_socket_list(struct control_server* server, struct control_clien struct etcpmon_rsp_socket_list* rsp = (struct etcpmon_rsp_socket_list*)(buffer + sizeof(*hdr)); rsp->count = 0; - send(client->fd, buffer, rsp_size, 0); - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); return; } @@ -889,17 +970,11 @@ static void send_socket_list(struct control_server* server, struct control_clien if (server->log_file) { log_hex_data(server->log_file, "TX", buffer, rsp_size); fprintf(server->log_file, "%llu: [LOG] Sent RSP_SOCKET_LIST count=%d\n", - (unsigned long long)get_timestamp_ms(), count); + (unsigned long long)get_timestamp_ms(), count); fflush(server->log_file); } -#ifdef _WIN32 - send(client->fd, (const char*)buffer, rsp_size, 0); -#else - send(client->fd, buffer, rsp_size, 0); -#endif - - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); } static void send_metrics(struct control_server* server, struct control_client* client, uint8_t seq_id) { @@ -1136,13 +1211,7 @@ static void send_metrics(struct control_server* server, struct control_client* c fflush(server->log_file); } -#ifdef _WIN32 - send(client->fd, (const char*)buffer, rsp_size, 0); -#else - send(client->fd, buffer, rsp_size, 0); -#endif - - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); } static void send_error(struct control_client* client, uint8_t error_code, const char* msg, uint8_t seq_id) { @@ -1170,13 +1239,7 @@ static void send_error(struct control_client* client, uint8_t error_code, const fflush(server->log_file); } -#ifdef _WIN32 - send(client->fd, (const char*)buffer, rsp_size, 0); -#else - send(client->fd, buffer, rsp_size, 0); -#endif - - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); } static void send_debug_config(struct control_server* server, struct control_client* client, uint8_t seq_id) { @@ -1215,13 +1278,7 @@ static void send_debug_config(struct control_server* server, struct control_clie fflush(server->log_file); } -#ifdef _WIN32 - send(client->fd, (const char*)buffer, rsp_size, 0); -#else - send(client->fd, buffer, rsp_size, 0); -#endif - - u_free(buffer); + control_client_send(server, client, buffer, rsp_size); } /* ============================================================================ @@ -1240,6 +1297,87 @@ static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instan return NULL; } +/* ============================================================================ + * Node Info Helpers (send_single_node_info, send_node_list, notify_change) + * ============================================================================ */ + +static void send_single_node_info(struct control_server* server, struct control_client* client, struct NODEINFO_Q* nq) { + int dyn = nodeinfo_dyn_size(&nq->node); + size_t np_size = sizeof(struct etcpmon_msg_header) + 2 + sizeof(struct NODEINFO) + dyn; + + uint8_t* buffer = (uint8_t*)u_malloc(np_size); + if (!buffer) { DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to allocate node info buffer"); return; } + + struct etcpmon_msg_header* hdr = (struct etcpmon_msg_header*)buffer; + etcpmon_build_header(hdr, 2 + sizeof(struct NODEINFO) + dyn, ETCPMON_RSP_NODE_INFO, 0); + + uint8_t* pay = buffer + sizeof(*hdr); + pay[0] = CTRL_BGP_CMD; pay[1] = CTRL_BGP_SUBCMD; + memcpy(pay + 2, &nq->node, sizeof(struct NODEINFO)); + memcpy(pay + 2 + sizeof(struct NODEINFO), (uint8_t*)&nq->node + sizeof(struct NODEINFO), dyn); + + control_client_send(server, client, buffer, (uint16_t)np_size); +} + +static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id) { + struct ROUTE_BGP* bgp = server->instance->bgp; + if (!bgp) { send_error(client, ETCPMON_ERR_SERVER_BUSY, "BGP not available", seq_id); return; } + + /* Send local node first */ + if (bgp->local_node) send_single_node_info(server, client, bgp->local_node); + + /* Send all known remote nodes */ + struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; + while (e) { + struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; + send_single_node_info(server, client, nq); + e = e->next; + } + + /* Send end-of-list marker */ + uint8_t* buffer = (uint8_t*)u_malloc(sizeof(struct etcpmon_msg_header)); + if (!buffer) return; + struct etcpmon_msg_header* hdr = (struct etcpmon_msg_header*)buffer; + etcpmon_build_header(hdr, 0, ETCPMON_RSP_NODE_INFO_END, seq_id); + control_client_send(server, client, buffer, sizeof(struct etcpmon_msg_header)); + + DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Sent node list to client (seq=%d)", seq_id); +} + +void control_server_notify_node_change(struct control_server* server, struct NODEINFO_Q* node) { + if (!server || !node) return; + struct control_client* client = server->clients; + while (client) { + if (client->subscribed_nodes) send_single_node_info(server, client, node); + client = client->next; + } +} + +void control_server_notify_node_removed(struct control_server* server, uint64_t node_id) { + if (!server) return; + + uint8_t* buffer = (uint8_t*)u_malloc(sizeof(struct etcpmon_msg_header) + sizeof(uint64_t)); + if (!buffer) return; + + struct etcpmon_msg_header* hdr = (struct etcpmon_msg_header*)buffer; + etcpmon_build_header(hdr, sizeof(uint64_t), ETCPMON_RSP_NODE_REMOVED, 0); + *(uint64_t*)(buffer + sizeof(*hdr)) = node_id; + + struct control_client* client = server->clients; + while (client) { + if (client->subscribed_nodes) { + /* Every client needs its own copy since ownership transfers to the queue */ + uint8_t* copy = (uint8_t*)u_malloc(sizeof(struct etcpmon_msg_header) + sizeof(uint64_t)); + if (copy) { + memcpy(copy, buffer, sizeof(struct etcpmon_msg_header) + sizeof(uint64_t)); + control_client_send(server, client, copy, sizeof(struct etcpmon_msg_header) + sizeof(uint64_t)); + } + } + client = client->next; + } + u_free(buffer); +} + /* ============================================================================ * Public API Implementation * ============================================================================ */ diff --git a/src/control_server.h b/src/control_server.h index aa966871..27de068b 100644 --- a/src/control_server.h +++ b/src/control_server.h @@ -19,6 +19,8 @@ extern "C" { /* Forward declarations */ struct UTUN_INSTANCE; struct UASYNC; +struct NODEINFO_Q; +struct ll_queue; /* Forward declaration */ struct control_server; @@ -36,9 +38,10 @@ struct control_client { /* Selected connection */ uint64_t selected_peer_id; /* 0 = none selected */ - - /* Client state */ -// uint8_t connected; + + struct ll_queue* output_queue; /* Output queue for async sends */ + uint8_t subscribed_nodes; /* 1 = subscribed to node updates */ + uint8_t write_registered; /* 1 = write events registered in uasync */ }; /* Control server state */ @@ -113,6 +116,9 @@ void control_server_process_updates(struct control_server* server); */ uint32_t control_server_get_client_count(const struct control_server* server); +void control_server_notify_node_change(struct control_server* server, struct NODEINFO_Q* node); +void control_server_notify_node_removed(struct control_server* server, uint64_t node_id); + #ifdef __cplusplus } #endif diff --git a/src/route_bgp.c b/src/route_bgp.c index 1bc6f0e5..f03f4633 100644 --- a/src/route_bgp.c +++ b/src/route_bgp.c @@ -20,6 +20,7 @@ #include "route_bgp.h" #include "route_ping.h" #include "route_connectivity.h" +#include "control_server.h" // ============================================================================ @@ -442,6 +443,8 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) { if (route_bgp_remove_path(nq, conn) == 1) { need_withdraw = true; if (rt) route_delete(rt, nq); + if (conn->instance && conn->instance->control_srv) + control_server_notify_node_removed(conn->instance->control_srv, nq->node.node_id); nq->dirty = 1; route_connectivity_cancel_node(conn->instance, nq); if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } @@ -830,6 +833,8 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co route_node_lmdb_put(bgp, nodeinfo1); } + if (bgp->instance->control_srv) control_server_notify_node_change(bgp->instance->control_srv, nodeinfo1); + int hop_count=nodeinfo1->node.hop_count; // рассылаем по узлам которых нет в hop_list этой ноды (loop prevention) @@ -875,6 +880,7 @@ int route_bgp_process_withdraw(struct ROUTE_BGP* bgp, struct ETCP_CONN* sender, int ret=route_bgp_remove_path_by_hop(nq, wd_source); if (ret>0 || !nq->paths || (nq->paths && queue_entry_count(nq->paths) == 0)) { if (bgp->instance && bgp->instance->rt) route_delete(bgp->instance->rt, nq); + if (bgp->instance->control_srv) control_server_notify_node_removed(bgp->instance->control_srv, node_id); nq->dirty = 1; route_connectivity_cancel_node(bgp->instance, nq); if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } diff --git a/tools/etcpmon/etcpmon_protocol.h b/tools/etcpmon/etcpmon_protocol.h index bbe9c903..185a8c04 100644 --- a/tools/etcpmon/etcpmon_protocol.h +++ b/tools/etcpmon/etcpmon_protocol.h @@ -53,12 +53,16 @@ extern "C" { #define ETCPMON_CMD_ACTION 0x06 /* Execute action (text command) */ #define ETCPMON_CMD_GET_DEBUG_CONFIG 0x07 /* Request current debug levels */ #define ETCPMON_CMD_SET_DEBUG_CONFIG 0x08 /* Set debug levels (byte array) */ +#define ETCPMON_CMD_SUBSCRIBE_NODES 0x09 /* Subscribe to node changes */ /* Server -> Client responses */ #define ETCPMON_RSP_CONN_LIST 0x81 /* Connection list response */ #define ETCPMON_RSP_METRICS 0x82 /* Metrics response */ #define ETCPMON_RSP_SOCKET_LIST 0x83 /* Socket list response */ #define ETCPMON_RSP_DEBUG_CONFIG 0x84 /* Debug levels response */ +#define ETCPMON_RSP_NODE_INFO 0x85 /* Single node info (payload: raw BGP_NODEINFO_PACKET) */ +#define ETCPMON_RSP_NODE_INFO_END 0x86 /* End of node list (no payload) */ +#define ETCPMON_RSP_NODE_REMOVED 0x88 /* Node removed (payload: uint64_t node_id) */ #define ETCPMON_RSP_ERROR 0xFF /* Error response */ /* Error codes for RSP_ERROR */