Apple/BSD port (#30)

* Add MacOS to Github CI builds.
* Fixed libnDPI-4.8 CI build.
* Fixed missing include for `struct sockaddr*`.
* Reworked IPv4 address and netmask retrieval.

Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
This commit is contained in:
Toni
2023-11-06 13:25:49 +01:00
committed by GitHub
parent 1b67927169
commit 93498fff02
10 changed files with 268 additions and 99 deletions

View File

@@ -18,13 +18,17 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
CMAKE_C_COMPILER: ${{ matrix.compiler }} CMAKE_C_COMPILER: ${{ matrix.compiler }}
CMAKE_C_FLAGS: -Werror CMAKE_C_FLAGS: -Werror ${{ matrix.cflags }}
CMAKE_C_EXE_LINKER_FLAGS: ${{ matrix.ldflags }}
CMAKE_MODULE_LINKER_FLAGS: ${{ matrix.ldflags }}
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
include: include:
- compiler: "gcc" - compiler: "gcc"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF" sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -35,6 +39,8 @@ jobs:
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "gcc" - compiler: "gcc"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=ON" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=ON"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF" sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -45,6 +51,8 @@ jobs:
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "clang" - compiler: "clang"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=OFF" ndpid_zlib: "-DENABLE_ZLIB=OFF"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF" sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -55,6 +63,8 @@ jobs:
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "gcc" - compiler: "gcc"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON" sanitizer: "-DENABLE_SANITIZER=ON"
@@ -64,24 +74,30 @@ jobs:
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "clang" - compiler: "clang"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON" sanitizer: "-DENABLE_SANITIZER=ON"
coverage: "-DENABLE_COVERAGE=ON" coverage: "-DENABLE_COVERAGE=OFF"
poll: "-DFORCE_POLL=OFF" poll: "-DFORCE_POLL=OFF"
upload: false upload: false
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "clang-12" - compiler: "clang-12"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER_THREAD=ON" sanitizer: "-DENABLE_SANITIZER_THREAD=ON"
coverage: "-DENABLE_COVERAGE=ON" coverage: "-DENABLE_COVERAGE=OFF"
poll: "-DFORCE_POLL=OFF" poll:
upload: false upload: false
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "gcc-10" - compiler: "gcc-10"
os: "ubuntu-latest" os: "ubuntu-latest"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=OFF" ndpid_zlib: "-DENABLE_ZLIB=OFF"
sanitizer: "-DENABLE_SANITIZER=ON" sanitizer: "-DENABLE_SANITIZER=ON"
@@ -91,6 +107,8 @@ jobs:
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "gcc-7" - compiler: "gcc-7"
os: "ubuntu-20.04" os: "ubuntu-20.04"
ndpi_build: "-DBUILD_NDPI=ON"
ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF" ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON" ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON" sanitizer: "-DENABLE_SANITIZER=ON"
@@ -98,6 +116,18 @@ jobs:
poll: "-DFORCE_POLL=OFF" poll: "-DFORCE_POLL=OFF"
upload: false upload: false
ndpi_min_version: "4.8" ndpi_min_version: "4.8"
- compiler: "cc"
os: "macOS-latest"
ndpi_build: "-DBUILD_NDPI=OFF"
ndpid_examples: "-DBUILD_EXAMPLES=OFF"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
examples: "-DBUILD_EXAMPLES=OFF"
sanitizer: "-DENABLE_SANITIZER=OFF"
coverage: "-DENABLE_COVERAGE=OFF"
poll:
upload: false
ndpi_min_version: "4.8"
steps: steps:
- name: Print Matrix - name: Print Matrix
@@ -105,9 +135,13 @@ jobs:
echo '----------------------------------------' echo '----------------------------------------'
echo '| OS.......: ${{ matrix.os }}' echo '| OS.......: ${{ matrix.os }}'
echo '| CC.......: ${{ matrix.compiler }}' echo '| CC.......: ${{ matrix.compiler }}'
echo "| CFLAGS...: $CMAKE_C_FLAGS"
echo "| LDFLAGS..: $CMAKE_C_EXE_LINKER_FLAGS"
echo '|---------------------------------------' echo '|---------------------------------------'
echo '| nDPI min.: ${{ matrix.ndpi_min_version }}'
echo '| GCRYPT...: ${{ matrix.ndpid_gcrypt }}' echo '| GCRYPT...: ${{ matrix.ndpid_gcrypt }}'
echo '| ZLIB.....: ${{ matrix.ndpid_zlib }}' echo '| ZLIB.....: ${{ matrix.ndpid_zlib }}'
echo '| ForcePoll: ${{ matrix.poll }}'
echo '|---------------------------------------' echo '|---------------------------------------'
echo '| SANITIZER: ${{ matrix.sanitizer }}' echo '| SANITIZER: ${{ matrix.sanitizer }}'
echo '| COVERAGE.: ${{ matrix.coverage }}' echo '| COVERAGE.: ${{ matrix.coverage }}'
@@ -118,6 +152,19 @@ jobs:
with: with:
submodules: false submodules: false
fetch-depth: 1 fetch-depth: 1
- name: Install MacOS Prerequisites
if: startsWith(matrix.os, 'macOS')
run: |
brew install coreutils flock automake make unzip
wget 'https://www.tcpdump.org/release/libpcap-1.10.4.tar.gz'
tar -xzvf libpcap-1.10.4.tar.gz
cd libpcap-1.10.4
./configure && make install
cd ..
wget 'https://github.com/ntop/nDPI/archive/refs/heads/dev.zip' -O libndpi-dev.zip
unzip libndpi-dev.zip
cd nDPI-dev
./autogen.sh --prefix=/usr/local --with-only-libndpi && make install
- name: Install Ubuntu Prerequisites - name: Install Ubuntu Prerequisites
if: startsWith(matrix.os, 'ubuntu') if: startsWith(matrix.os, 'ubuntu')
run: | run: |
@@ -139,13 +186,15 @@ jobs:
test ${C_VAL} = ${PY_VAL} test ${C_VAL} = ${PY_VAL}
- name: Configure nDPId - name: Configure nDPId
run: | run: |
mkdir build && cd build cmake -S . -B build -DCMAKE_C_COMPILER="$CMAKE_C_COMPILER" -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" -DCMAKE_MODULE_LINKER_FLAGS="$CMAKE_MODULE_LINKER_FLAGS" -DCMAKE_C_EXE_LINKER_FLAGS="$CMAKE_C_EXE_LINKER_FLAGS" \
cmake .. -DENABLE_SYSTEMD=ON -DBUILD_EXAMPLES=ON -DBUILD_NDPI=ON ${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.sanitizer }} ${{ matrix.ndpid_zlib }} ${{ matrix.ndpid_gcrypt }} -DENABLE_SYSTEMD=ON \
${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.sanitizer }} ${{ matrix.ndpi_build }} \
${{ matrix.ndpid_examples }} ${{ matrix.ndpid_zlib }} ${{ matrix.ndpid_gcrypt }}
- name: Build nDPId - name: Build nDPId
run: | run: |
make -C build all VERBOSE=1 cmake --build build --verbose
- name: Build single nDPId executable (invoke CC directly) - name: Build single nDPId executable (invoke CC directly)
if: startsWith(matrix.coverage, '-DENABLE_COVERAGE=OFF') && startsWith(matrix.sanitizer, '-DENABLE_SANITIZER=ON') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF') && startsWith(matrix.ndpid_zlib, '-DENABLE_ZLIB=ON') if: (endsWith(matrix.compiler, 'gcc') || endsWith(matrix.compiler, 'clang')) && startsWith(matrix.coverage, '-DENABLE_COVERAGE=OFF') && startsWith(matrix.sanitizer, '-DENABLE_SANITIZER=ON') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF') && startsWith(matrix.ndpid_zlib, '-DENABLE_ZLIB=ON')
run: | run: |
cc -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fsanitize=enum -fsanitize=leak nDPId.c nio.c utils.c -I./build/libnDPI/include/ndpi -I. -I./dependencies -I./dependencies/jsmn -I./dependencies/uthash/include -o /tmp/a.out -lpcap ./build/libnDPI/lib/libndpi.a -pthread -lm -lz cc -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fsanitize=enum -fsanitize=leak nDPId.c nio.c utils.c -I./build/libnDPI/include/ndpi -I. -I./dependencies -I./dependencies/jsmn -I./dependencies/uthash/include -o /tmp/a.out -lpcap ./build/libnDPI/lib/libndpi.a -pthread -lm -lz
- name: Test EXEC - name: Test EXEC
@@ -154,10 +203,11 @@ jobs:
./build/nDPId -h || test $? -eq 1 ./build/nDPId -h || test $? -eq 1
./build/nDPIsrvd -h || test $? -eq 1 ./build/nDPIsrvd -h || test $? -eq 1
- name: Test DIFF - name: Test DIFF
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF') if: startsWith(matrix.os, 'macOS') == false && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF')
run: | run: |
./test/run_tests.sh ./libnDPI ./build/nDPId-test ./test/run_tests.sh ./libnDPI ./build/nDPId-test
- name: Daemon - name: Daemon
if: endsWith(matrix.compiler, 'gcc') || endsWith(matrix.compiler, 'clang')
run: | run: |
make -C ./build daemon VERBOSE=1 make -C ./build daemon VERBOSE=1
make -C ./build daemon VERBOSE=1 make -C ./build daemon VERBOSE=1
@@ -166,20 +216,21 @@ jobs:
run: | run: |
make -C ./build coverage make -C ./build coverage
- name: Dist - name: Dist
if: matrix.upload == false if: startsWith(matrix.os, 'macOS') == false && matrix.upload == false
run: | run: |
make -C ./build dist make -C ./build dist
- name: CPack DEB - name: CPack DEB
if: startsWith(matrix.os, 'macOS') == false
run: | run: |
cd ./build && cpack -G DEB && sudo dpkg -i nDPId-*.deb && cd .. cd ./build && cpack -G DEB && sudo dpkg -i nDPId-*.deb && cd ..
- name: Upload DEB - name: Upload DEB
if: matrix.upload if: startsWith(matrix.os, 'macOS') == false && matrix.upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: nDPId-debian-packages_${{ matrix.compiler }}${{ matrix.upload_suffix }} name: nDPId-debian-packages_${{ matrix.compiler }}${{ matrix.upload_suffix }}
path: build/*.deb path: build/*.deb
- name: systemd test - name: Test systemd
if: startsWith(matrix.os, 'ubuntu-latest') && startsWith(matrix.compiler, 'gcc') if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.compiler, 'gcc')
run: | run: |
ip -c address ip -c address
sudo systemctl daemon-reload sudo systemctl daemon-reload
@@ -190,14 +241,22 @@ jobs:
sudo systemctl show ndpisrvd.service ndpid@lo.service -p SubState,ActiveState || true sudo systemctl show ndpisrvd.service ndpid@lo.service -p SubState,ActiveState || true
journalctl --no-tail --no-pager -u ndpisrvd.service -u ndpid@lo.service journalctl --no-tail --no-pager -u ndpisrvd.service -u ndpid@lo.service
- name: Build against libnDPI-${{ matrix.ndpi_min_version }} - name: Build against libnDPI-${{ matrix.ndpi_min_version }}
if: matrix.upload == false if: matrix.upload == false && startsWith(matrix.os, 'ubuntu')
run: | run: |
mkdir build-local-ndpi && cd build-local-ndpi mkdir build-local-ndpi && cd build-local-ndpi
WGET_RET=0 WGET_RET=0
wget 'https://github.com/ntop/nDPI/archive/refs/tags/${{ matrix.ndpi_min_version }}.tar.gz' || { WGET_RET=$?; true; } wget 'https://github.com/ntop/nDPI/archive/refs/tags/${{ matrix.ndpi_min_version }}.tar.gz' || { WGET_RET=$?; true; }
echo "wget returned: ${WGET_RET}" echo "wget returned: ${WGET_RET}"
test $WGET_RET -ne 8 || echo "::warning file=nDPId.c::New libnDPI release required to build against release tarball." test $WGET_RET -ne 8 || echo "::warning file=nDPId.c::New libnDPI release required to build against release tarball."
test $WGET_RET -ne 0 || { tar -xzvf ${{ matrix.ndpi_min_version }}.tar.gz && cd nDPI-${{ matrix.ndpi_min_version }} && ./autogen.sh --prefix=/usr --with-only-libndpi CC=${{ matrix.compiler }} CXX=false CFLAGS='-Werror' && sudo make install && cd .. ; } test $WGET_RET -ne 0 || { tar -xzvf ${{ matrix.ndpi_min_version }}.tar.gz && \
test $WGET_RET -ne 0 || { echo "running cmake .."; cmake .. -DBUILD_EXAMPLES=ON -DBUILD_NDPI=OFF -DENABLE_SANITIZER=OFF ${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.ndpi_min_version }} ; } cd nDPI-${{ matrix.ndpi_min_version }} && \
test $WGET_RET -ne 0 || { echo "running make .."; make all VERBOSE=1 ; } ./autogen.sh --prefix=/usr --with-only-libndpi CC="${{ matrix.compiler }}" CXX=false \
CFLAGS="$CMAKE_C_FLAGS" && make && sudo make install; cd ..; }
test $WGET_RET -ne 0 || { echo "::info file=CMakeLists.txt::Running CMake.."; \
cmake -S .. -DCMAKE_C_COMPILER="$CMAKE_C_COMPILER" -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" \
-DCMAKE_C_EXE_LINKER_FLAGS="$CMAKE_C_EXE_LINKER_FLAGS" \
-DBUILD_NDPI=OFF -DENABLE_SANITIZER=OFF \
${{ matrix.poll }} ${{ matrix.coverage }} \
${{ matrix.ndpid_examples }}; }
test $WGET_RET -ne 0 || { echo "::info file=CMakeLists.txt:Running Make.."; cmake --build . --verbose; }
test $WGET_RET -eq 0 -o $WGET_RET -eq 8 test $WGET_RET -eq 0 -o $WGET_RET -eq 8

View File

@@ -31,6 +31,7 @@ set(CPACK_PACKAGE_VERSION_PATCH 0)
include(CPack) include(CPack)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckEpoll) include(CheckEpoll)
check_epoll(HAS_EPOLL) check_epoll(HAS_EPOLL)
@@ -49,14 +50,19 @@ if(NOT MATH_FUNCTION_EXISTS AND NOT NEED_LINKING_AGAINST_LIBM)
CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS) CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS)
if(NOT MATH_FUNCTION_EXISTS) if(NOT MATH_FUNCTION_EXISTS)
unset(MATH_FUNCTION_EXISTS CACHE) unset(MATH_FUNCTION_EXISTS CACHE)
list(APPEND CMAKE_REQUIRED_LIBRARIES m) list(APPEND CMAKE_REQUIRED_LIBRARIES m)
CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS) CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS)
if(MATH_FUNCTION_EXISTS) if(MATH_FUNCTION_EXISTS)
set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE) set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE)
else() else()
message(FATAL_ERROR "Failed making the log2f() function available") check_library_exists(m sqrt "" NEED_LINKING_AGAINST_LIBM)
endif() if(NOT NEED_LINKING_AGAINST_LIBM)
endif() # Was not able to figure out if explicit linkage against libm is required.
# Forcing libm linkage. Good idea?
set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE)
endif()
endif()
endif()
endif() endif()
if(NEED_LINKING_AGAINST_LIBM) if(NEED_LINKING_AGAINST_LIBM)

View File

@@ -5,6 +5,7 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <netinet/in.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>

View File

@@ -923,7 +923,9 @@ static enum nDPIsrvd_callback_return distributor_json_printer(struct nDPIsrvd_so
static void * distributor_client_mainloop_thread(void * const arg) static void * distributor_client_mainloop_thread(void * const arg)
{ {
struct nio io; struct nio io;
#if !defined(__FreeBSD__) && !defined(__APPLE__)
int signalfd = -1; int signalfd = -1;
#endif
struct distributor_return_value * const drv = (struct distributor_return_value *)arg; struct distributor_return_value * const drv = (struct distributor_return_value *)arg;
struct thread_return_value * const trv = &drv->thread_return_value; struct thread_return_value * const trv = &drv->thread_return_value;
struct nDPIsrvd_socket * mock_sock = nDPIsrvd_socket_init(sizeof(struct distributor_global_user_data), struct nDPIsrvd_socket * mock_sock = nDPIsrvd_socket_init(sizeof(struct distributor_global_user_data),
@@ -960,12 +962,14 @@ static void * distributor_client_mainloop_thread(void * const arg)
THREAD_ERROR_GOTO(trv); THREAD_ERROR_GOTO(trv);
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
signalfd = setup_signalfd(&io); signalfd = setup_signalfd(&io);
if (signalfd < 0) if (signalfd < 0)
{ {
logger(1, "Distributor signal fd setup failed: %s", strerror(errno)); logger(1, "Distributor signal fd setup failed: %s", strerror(errno));
THREAD_ERROR_GOTO(trv); THREAD_ERROR_GOTO(trv);
} }
#endif
if (thread_block_signals() != 0) if (thread_block_signals() != 0)
{ {
@@ -1159,6 +1163,7 @@ static void * distributor_client_mainloop_thread(void * const arg)
* I am just here to trigger some IP code paths. * I am just here to trigger some IP code paths.
*/ */
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
else if (fd == signalfd) else if (fd == signalfd)
{ {
struct signalfd_siginfo fdsi; struct signalfd_siginfo fdsi;
@@ -1178,6 +1183,7 @@ static void * distributor_client_mainloop_thread(void * const arg)
THREAD_ERROR_GOTO(trv); THREAD_ERROR_GOTO(trv);
} }
} }
#endif
else else
{ {
logger(1, logger(1,
@@ -1251,7 +1257,9 @@ static void * distributor_client_mainloop_thread(void * const arg)
} }
error: error:
#if !defined(__FreeBSD__) && !defined(__APPLE__)
del_event(&io, signalfd); del_event(&io, signalfd);
#endif
del_event(&io, mock_testfds[PIPE_TEST_READ]); del_event(&io, mock_testfds[PIPE_TEST_READ]);
del_event(&io, mock_bufffds[PIPE_BUFFER_READ]); del_event(&io, mock_bufffds[PIPE_BUFFER_READ]);
del_event(&io, mock_nullfds[PIPE_NULL_READ]); del_event(&io, mock_nullfds[PIPE_NULL_READ]);
@@ -1260,7 +1268,9 @@ error:
close(mock_bufffds[PIPE_BUFFER_READ]); close(mock_bufffds[PIPE_BUFFER_READ]);
close(mock_nullfds[PIPE_NULL_READ]); close(mock_nullfds[PIPE_NULL_READ]);
close(mock_arpafds[PIPE_ARPA_READ]); close(mock_arpafds[PIPE_ARPA_READ]);
#if !defined(__FreeBSD__) && !defined(__APPLE__)
close(signalfd); close(signalfd);
#endif
nio_free(&io); nio_free(&io);
nDPIsrvd_socket_free(&mock_sock); nDPIsrvd_socket_free(&mock_sock);
@@ -1351,6 +1361,7 @@ static void usage(char const * const arg0)
static int thread_wait_for_termination(pthread_t thread, time_t wait_time_secs, struct thread_return_value * const trv) static int thread_wait_for_termination(pthread_t thread, time_t wait_time_secs, struct thread_return_value * const trv)
{ {
#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct timespec ts; struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
@@ -1370,6 +1381,11 @@ static int thread_wait_for_termination(pthread_t thread, time_t wait_time_secs,
} }
return 1; return 1;
#else
(void)wait_time_secs;
return pthread_join(thread, (void **)&trv) != 0;
#endif
} }
static int base64_selftest() static int base64_selftest()

92
nDPId.c
View File

@@ -1,3 +1,6 @@
#if defined(__FreeBSD__) || defined(__APPLE__)
#include <sys/types.h>
#endif
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -17,7 +20,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <sys/signalfd.h> #include <sys/signalfd.h>
#endif
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#ifdef ENABLE_ZLIB #ifdef ENABLE_ZLIB
@@ -429,7 +434,6 @@ static struct nDPId_reader_thread reader_threads[nDPId_MAX_READER_THREADS] = {};
static struct nDPIsrvd_address collector_address; static struct nDPIsrvd_address collector_address;
static MT_VALUE(nDPId_main_thread_shutdown, int) = MT_INIT(0); static MT_VALUE(nDPId_main_thread_shutdown, int) = MT_INIT(0);
static MT_VALUE(global_flow_id, uint64_t) = MT_INIT(1); static MT_VALUE(global_flow_id, uint64_t) = MT_INIT(1);
static int ip4_interface_avail = 0, ip6_interface_avail = 0;
#ifdef ENABLE_MEMORY_PROFILING #ifdef ENABLE_MEMORY_PROFILING
static MT_VALUE(ndpi_memory_alloc_count, uint64_t) = MT_INIT(0); static MT_VALUE(ndpi_memory_alloc_count, uint64_t) = MT_INIT(0);
@@ -929,10 +933,17 @@ static void get_ip6_from_sockaddr(struct sockaddr_in6 const * const saddr, union
switch (saddr->sin6_family) switch (saddr->sin6_family)
{ {
case AF_INET6: case AF_INET6:
#if defined(__FreeBSD__) || defined(__APPLE__)
dest->v6.ip_u32[0] = saddr->sin6_addr.__u6_addr.__u6_addr32[0];
dest->v6.ip_u32[1] = saddr->sin6_addr.__u6_addr.__u6_addr32[1];
dest->v6.ip_u32[2] = saddr->sin6_addr.__u6_addr.__u6_addr32[2];
dest->v6.ip_u32[3] = saddr->sin6_addr.__u6_addr.__u6_addr32[3];
#else
dest->v6.ip_u32[0] = saddr->sin6_addr.s6_addr32[0]; dest->v6.ip_u32[0] = saddr->sin6_addr.s6_addr32[0];
dest->v6.ip_u32[1] = saddr->sin6_addr.s6_addr32[1]; dest->v6.ip_u32[1] = saddr->sin6_addr.s6_addr32[1];
dest->v6.ip_u32[2] = saddr->sin6_addr.s6_addr32[2]; dest->v6.ip_u32[2] = saddr->sin6_addr.s6_addr32[2];
dest->v6.ip_u32[3] = saddr->sin6_addr.s6_addr32[3]; dest->v6.ip_u32[3] = saddr->sin6_addr.s6_addr32[3];
#endif
break; break;
default: default:
return; return;
@@ -996,7 +1007,11 @@ static int get_ip6_address_and_netmask(char const * const ifa_name, size_t ifnam
memset(&sap.sin6_addr.s6_addr, 0xFF, plen / 8); memset(&sap.sin6_addr.s6_addr, 0xFF, plen / 8);
if (plen < 128 && (plen % 32) != 0) if (plen < 128 && (plen % 32) != 0)
{ {
#if defined(__FreeBSD__) || defined(__APPLE__)
sap.sin6_addr.__u6_addr.__u6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32));
#else
sap.sin6_addr.s6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32)); sap.sin6_addr.s6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32));
#endif
} }
inet_ntop(AF_INET6, &sap.sin6_addr, netmask6, sizeof(netmask6)); inet_ntop(AF_INET6, &sap.sin6_addr, netmask6, sizeof(netmask6));
sap.sin6_family = AF_INET6; sap.sin6_family = AF_INET6;
@@ -1024,50 +1039,14 @@ error:
return retval; return retval;
} }
static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnamelen) static void get_ip4_address_and_netmask(struct ifaddrs const * const ifaddr)
{ {
int retval = 0; get_ip4_from_sockaddr((struct sockaddr_in *)ifaddr->ifa_netmask, &nDPId_options.pcap_dev_netmask4);
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); get_ip4_from_sockaddr((struct sockaddr_in *)ifaddr->ifa_addr, &nDPId_options.pcap_dev_ip4);
struct ifreq ifr;
if (sock < 0)
{
retval = 1;
goto error;
}
if (ifnamelen >= sizeof(ifr.ifr_name))
{
retval = 1;
goto error;
}
memset(&ifr, 0, sizeof(ifr));
memcpy(ifr.ifr_name, ifa_name, ifnamelen);
ifr.ifr_name[ifnamelen] = '\0';
ifr.ifr_netmask.sa_family = AF_INET;
if (ioctl(sock, SIOCGIFNETMASK, &ifr) == -1)
{
retval = 1;
goto error;
}
get_ip4_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_netmask4);
memset(&ifr, 0, sizeof(ifr));
memcpy(ifr.ifr_name, ifa_name, ifnamelen);
ifr.ifr_name[ifnamelen] = '\0';
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(sock, SIOCGIFADDR, &ifr) == -1)
{
retval = 1;
goto error;
}
get_ip4_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_ip4);
ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip4, ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip4,
&nDPId_options.pcap_dev_netmask4, &nDPId_options.pcap_dev_netmask4,
&nDPId_options.pcap_dev_subnet4, &nDPId_options.pcap_dev_subnet4,
L3_IP); L3_IP);
{ {
char addr[INET_ADDRSTRLEN]; char addr[INET_ADDRSTRLEN];
char netm[INET_ADDRSTRLEN]; char netm[INET_ADDRSTRLEN];
@@ -1082,15 +1061,12 @@ static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnam
inet_ntop(AF_INET, snetm, netm, sizeof(netm)), inet_ntop(AF_INET, snetm, netm, sizeof(netm)),
inet_ntop(AF_INET, ssubn, subn, sizeof(subn))); inet_ntop(AF_INET, ssubn, subn, sizeof(subn)));
} }
error:
close(sock);
return retval;
} }
static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev) static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
{ {
int retval = 0, found_dev = 0; int retval = 0, found_dev = 0;
int ip4_interface_avail = 0, ip6_interface_avail = 0;
struct ifaddrs * ifaddrs = NULL; struct ifaddrs * ifaddrs = NULL;
struct ifaddrs * ifa; struct ifaddrs * ifa;
@@ -1113,10 +1089,7 @@ static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
switch (ifa->ifa_addr->sa_family) switch (ifa->ifa_addr->sa_family)
{ {
case AF_INET: case AF_INET:
if (ip4_interface_avail == 0 && get_ip4_address_and_netmask(ifa->ifa_name, ifnamelen) != 0) get_ip4_address_and_netmask(ifa);
{
retval = 1;
}
ip4_interface_avail = 1; ip4_interface_avail = 1;
break; break;
case AF_INET6: case AF_INET6:
@@ -1586,6 +1559,8 @@ static int setup_reader_threads(void)
"Could not get netmask for pcap device %s: %s", "Could not get netmask for pcap device %s: %s",
get_cmdarg(&nDPId_options.pcap_file_or_interface), get_cmdarg(&nDPId_options.pcap_file_or_interface),
strerror(errno)); strerror(errno));
} else {
logger_early(1, "Unexpected error while retrieving netmask for pcap device %s", get_cmdarg(&nDPId_options.pcap_file_or_interface));
} }
return 1; return 1;
} }
@@ -2245,8 +2220,8 @@ static int connect_to_collector(struct nDPId_reader_thread * const reader_thread
} }
int sock_type = (collector_address.raw.sa_family == AF_UNIX ? SOCK_STREAM : SOCK_DGRAM); int sock_type = (collector_address.raw.sa_family == AF_UNIX ? SOCK_STREAM : SOCK_DGRAM);
reader_thread->collector_sockfd = socket(collector_address.raw.sa_family, sock_type | SOCK_CLOEXEC, 0); reader_thread->collector_sockfd = socket(collector_address.raw.sa_family, sock_type, 0);
if (reader_thread->collector_sockfd < 0) if (reader_thread->collector_sockfd < 0 || set_fd_cloexec(reader_thread->collector_sockfd) < 0)
{ {
reader_thread->collector_sock_last_errno = errno; reader_thread->collector_sock_last_errno = errno;
return 1; return 1;
@@ -3458,7 +3433,7 @@ static int process_datalink_layer(struct nDPId_reader_thread * const reader_thre
break; break;
case ETHERTYPE_PAE: /* 802.1X Authentication */ case ETHERTYPE_PAE: /* 802.1X Authentication */
return 1; return 1;
case ETH_P_ARP: /* ARP */ case ETHERTYPE_ARP: /* ARP */
return 1; return 1;
default: default:
if (is_error_event_threshold(reader_thread->workflow) == 0) if (is_error_event_threshold(reader_thread->workflow) == 0)
@@ -4274,6 +4249,7 @@ static void get_current_time(struct timeval * const tval)
gettimeofday(tval, NULL); gettimeofday(tval, NULL);
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
static void ndpi_log_flow_walker(void const * const A, ndpi_VISIT which, int depth, void * const user_data) static void ndpi_log_flow_walker(void const * const A, ndpi_VISIT which, int depth, void * const user_data)
{ {
struct nDPId_reader_thread const * const reader_thread = (struct nDPId_reader_thread *)user_data; struct nDPId_reader_thread const * const reader_thread = (struct nDPId_reader_thread *)user_data;
@@ -4358,6 +4334,7 @@ static void log_all_flows(struct nDPId_reader_thread const * const reader_thread
ndpi_twalk(workflow->ndpi_flows_active[scan_index], ndpi_log_flow_walker, (void *)reader_thread); ndpi_twalk(workflow->ndpi_flows_active[scan_index], ndpi_log_flow_walker, (void *)reader_thread);
} }
} }
#endif
static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread) static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
{ {
@@ -4380,6 +4357,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
} }
else else
{ {
#if !defined(__FreeBSD__) && !defined(__APPLE__)
sigset_t thread_signal_set, old_signal_set; sigset_t thread_signal_set, old_signal_set;
sigfillset(&thread_signal_set); sigfillset(&thread_signal_set);
if (pthread_sigmask(SIG_BLOCK, &thread_signal_set, &old_signal_set) != 0) if (pthread_sigmask(SIG_BLOCK, &thread_signal_set, &old_signal_set) != 0)
@@ -4392,13 +4370,14 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
sigaddset(&thread_signal_set, SIGINT); sigaddset(&thread_signal_set, SIGINT);
sigaddset(&thread_signal_set, SIGTERM); sigaddset(&thread_signal_set, SIGTERM);
sigaddset(&thread_signal_set, SIGUSR1); sigaddset(&thread_signal_set, SIGUSR1);
int signal_fd = signalfd(-1, &thread_signal_set, SFD_NONBLOCK | SFD_CLOEXEC); int signal_fd = signalfd(-1, &thread_signal_set, SFD_NONBLOCK);
if (signal_fd < 0) if (signal_fd < 0 || set_fd_cloexec(signal_fd) < 0)
{ {
logger(1, "signalfd: %s", strerror(errno)); logger(1, "signalfd: %s", strerror(errno));
MT_GET_AND_ADD(reader_thread->workflow->error_or_eof, 1); MT_GET_AND_ADD(reader_thread->workflow->error_or_eof, 1);
return; return;
} }
#endif
int pcap_fd = pcap_get_selectable_fd(reader_thread->workflow->pcap_handle); int pcap_fd = pcap_get_selectable_fd(reader_thread->workflow->pcap_handle);
if (pcap_fd < 0) if (pcap_fd < 0)
@@ -4433,6 +4412,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
nio_free(&io); nio_free(&io);
return; return;
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
errno = 0; errno = 0;
if (nio_add_fd(&io, signal_fd, NIO_EVENT_INPUT, NULL) != NIO_SUCCESS) if (nio_add_fd(&io, signal_fd, NIO_EVENT_INPUT, NULL) != NIO_SUCCESS)
{ {
@@ -4443,6 +4423,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
nio_free(&io); nio_free(&io);
return; return;
} }
#endif
int const timeout_ms = 1000; /* TODO: Configurable? */ int const timeout_ms = 1000; /* TODO: Configurable? */
struct timeval tval_before_epoll, tval_after_epoll; struct timeval tval_before_epoll, tval_after_epoll;
@@ -4482,6 +4463,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
int fd = nio_get_fd(&io, i); int fd = nio_get_fd(&io, i);
#if !defined(__FreeBSD__) && !defined(__APPLE__)
if (fd == signal_fd) if (fd == signal_fd)
{ {
struct signalfd_siginfo fdsi; struct signalfd_siginfo fdsi;
@@ -4513,7 +4495,9 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
logger(1, "Received signal %d (%s)", fdsi.ssi_signo, signame); logger(1, "Received signal %d (%s)", fdsi.ssi_signo, signame);
} }
} }
else if (fd == pcap_fd) else
#endif
if (fd == pcap_fd)
{ {
switch (pcap_dispatch( switch (pcap_dispatch(
reader_thread->workflow->pcap_handle, -1, ndpi_process_packet, (uint8_t *)reader_thread)) reader_thread->workflow->pcap_handle, -1, ndpi_process_packet, (uint8_t *)reader_thread))

View File

@@ -9,7 +9,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <sys/signalfd.h> #include <sys/signalfd.h>
#endif
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@@ -43,15 +45,19 @@ struct remote_desc
{ {
struct sockaddr_un peer; struct sockaddr_un peer;
unsigned long long int json_bytes; unsigned long long int json_bytes;
#if !defined(__FreeBSD__) && !defined(__APPLE__)
pid_t pid; pid_t pid;
#endif
struct nDPIsrvd_json_buffer main_read_buffer; struct nDPIsrvd_json_buffer main_read_buffer;
} event_collector_un; } event_collector_un;
struct struct
{ {
struct sockaddr_un peer; struct sockaddr_un peer;
#if !defined(__FreeBSD__) && !defined(__APPLE__)
pid_t pid; pid_t pid;
char * user_name; char * user_name;
#endif
struct nDPIsrvd_write_buffer main_write_buffer; struct nDPIsrvd_write_buffer main_write_buffer;
UT_array * additional_write_buffers; UT_array * additional_write_buffers;
@@ -79,7 +85,7 @@ static int collector_un_sockfd = -1;
static int distributor_un_sockfd = -1; static int distributor_un_sockfd = -1;
static int distributor_in_sockfd = -1; static int distributor_in_sockfd = -1;
static struct nDPIsrvd_address distributor_in_address = { static struct nDPIsrvd_address distributor_in_address = {
.raw.sa_family = 0xFFFF, .raw.sa_family = (sa_family_t)0xFFFF,
}; };
static struct static struct
@@ -278,12 +284,16 @@ static void logger_nDPIsrvd(struct remote_desc const * const remote,
switch (remote->sock_type) switch (remote->sock_type)
{ {
case DISTRIBUTOR_UN: case DISTRIBUTOR_UN:
#if !defined(__FreeBSD__) && !defined(__APPLE__)
logger(1, logger(1,
"%s PID %d (User: %s) %s", "%s PID %d (User: %s) %s",
prefix, prefix,
remote->event_distributor_un.pid, remote->event_distributor_un.pid,
remote->event_distributor_un.user_name, remote->event_distributor_un.user_name,
logbuf); logbuf);
#else
logger(1, "%s %s", prefix, logbuf);
#endif
break; break;
case DISTRIBUTOR_IN: case DISTRIBUTOR_IN:
logger(1, logger(1,
@@ -295,7 +305,11 @@ static void logger_nDPIsrvd(struct remote_desc const * const remote,
logbuf); logbuf);
break; break;
case COLLECTOR_UN: case COLLECTOR_UN:
#if !defined(__FreeBSD__) && !defined(__APPLE__)
logger(1, "%s PID %d %s", prefix, remote->event_collector_un.pid, logbuf); logger(1, "%s PID %d %s", prefix, remote->event_collector_un.pid, logbuf);
#else
logger(1, "%s %s", prefix, logbuf);
#endif
break; break;
} }
@@ -435,9 +449,12 @@ static int handle_outgoing_data(struct nio * const io, struct remote_desc * cons
{ {
struct nDPIsrvd_write_buffer * const write_buffer = get_write_buffer(remote); struct nDPIsrvd_write_buffer * const write_buffer = get_write_buffer(remote);
if (write_buffer->buf.used == 0) { if (write_buffer->buf.used == 0)
{
return set_in_event(io, remote); return set_in_event(io, remote);
} else { }
else
{
return drain_main_buffer(remote); return drain_main_buffer(remote);
} }
} }
@@ -473,7 +490,8 @@ static int create_listen_sockets(void)
{ {
collector_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); collector_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
distributor_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); distributor_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (collector_un_sockfd < 0 || distributor_un_sockfd < 0) if (collector_un_sockfd < 0 || distributor_un_sockfd < 0 || set_fd_cloexec(collector_un_sockfd) < 0 ||
set_fd_cloexec(distributor_un_sockfd) < 0)
{ {
logger(1, "Error creating UNIX socket: %s", strerror(errno)); logger(1, "Error creating UNIX socket: %s", strerror(errno));
return 1; return 1;
@@ -482,7 +500,7 @@ static int create_listen_sockets(void)
if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0) if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0)
{ {
distributor_in_sockfd = socket(distributor_in_address.raw.sa_family, SOCK_STREAM, 0); distributor_in_sockfd = socket(distributor_in_address.raw.sa_family, SOCK_STREAM, 0);
if (distributor_in_sockfd < 0) if (distributor_in_sockfd < 0 || set_fd_cloexec(distributor_in_sockfd) < 0)
{ {
logger(1, "Error creating TCP/IP socket: %s", strerror(errno)); logger(1, "Error creating TCP/IP socket: %s", strerror(errno));
return 1; return 1;
@@ -716,7 +734,9 @@ static void free_remote(struct nio * const io, struct remote_desc * remote)
utarray_free(remote->event_distributor_un.additional_write_buffers); utarray_free(remote->event_distributor_un.additional_write_buffers);
} }
nDPIsrvd_buffer_free(&remote->event_distributor_un.main_write_buffer.buf); nDPIsrvd_buffer_free(&remote->event_distributor_un.main_write_buffer.buf);
#if !defined(__FreeBSD__) && !defined(__APPLE__)
free(remote->event_distributor_un.user_name); free(remote->event_distributor_un.user_name);
#endif
break; break;
case DISTRIBUTOR_IN: case DISTRIBUTOR_IN:
if (errno != 0) if (errno != 0)
@@ -935,7 +955,7 @@ static struct remote_desc * accept_remote(int server_fd,
int client_fd; int client_fd;
while ((client_fd = accept(server_fd, sockaddr, addrlen)) < 0 && errno == EINTR) {} while ((client_fd = accept(server_fd, sockaddr, addrlen)) < 0 && errno == EINTR) {}
if (client_fd < 0) if (client_fd < 0 || set_fd_cloexec(client_fd) < 0)
{ {
logger(1, "Accept failed: %s", strerror(errno)); logger(1, "Accept failed: %s", strerror(errno));
return NULL; return NULL;
@@ -1005,6 +1025,7 @@ static int new_connection(struct nio * const io, int eventfd)
return 1; return 1;
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct ucred ucred = {}; struct ucred ucred = {};
socklen_t ucred_len = sizeof(ucred); socklen_t ucred_len = sizeof(ucred);
if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1) if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1)
@@ -1012,8 +1033,8 @@ static int new_connection(struct nio * const io, int eventfd)
logger(1, "Error getting credentials from UNIX socket: %s", strerror(errno)); logger(1, "Error getting credentials from UNIX socket: %s", strerror(errno));
return 1; return 1;
} }
current->event_collector_un.pid = ucred.pid; current->event_collector_un.pid = ucred.pid;
#endif
logger_nDPIsrvd(current, "New collector connection from", ""); logger_nDPIsrvd(current, "New collector connection from", "");
break; break;
@@ -1023,6 +1044,7 @@ static int new_connection(struct nio * const io, int eventfd)
{ {
current->event_distributor_un.peer = sockaddr.saddr_distributor_un; current->event_distributor_un.peer = sockaddr.saddr_distributor_un;
#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct ucred ucred = {}; struct ucred ucred = {};
socklen_t ucred_len = sizeof(ucred); socklen_t ucred_len = sizeof(ucred);
if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1) if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1)
@@ -1047,6 +1069,7 @@ static int new_connection(struct nio * const io, int eventfd)
current->event_distributor_un.pid = ucred.pid; current->event_distributor_un.pid = ucred.pid;
current->event_distributor_un.user_name = strdup(pwres->pw_name); current->event_distributor_un.user_name = strdup(pwres->pw_name);
#endif
} }
else else
{ {
@@ -1351,6 +1374,7 @@ static int handle_data_event(struct nio * const io, int index)
} }
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
static int setup_signalfd(struct nio * const io) static int setup_signalfd(struct nio * const io)
{ {
sigset_t mask; sigset_t mask;
@@ -1383,10 +1407,13 @@ static int setup_signalfd(struct nio * const io)
return sfd; return sfd;
} }
#endif
static int mainloop(struct nio * const io) static int mainloop(struct nio * const io)
{ {
#if !defined(__FreeBSD__) && !defined(__APPLE__)
int signalfd = setup_signalfd(io); int signalfd = setup_signalfd(io);
#endif
while (nDPIsrvd_main_thread_shutdown == 0) while (nDPIsrvd_main_thread_shutdown == 0)
{ {
@@ -1433,6 +1460,7 @@ static int mainloop(struct nio * const io)
continue; continue;
} }
} }
#if !defined(__FreeBSD__) && !defined(__APPLE__)
else if (fd == signalfd) else if (fd == signalfd)
{ {
struct signalfd_siginfo fdsi; struct signalfd_siginfo fdsi;
@@ -1441,10 +1469,18 @@ static int mainloop(struct nio * const io)
s = read(signalfd, &fdsi, sizeof(struct signalfd_siginfo)); s = read(signalfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo)) if (s != sizeof(struct signalfd_siginfo))
{ {
logger(1, if (s < 0)
"Invalid signal fd read size. Got %zd, wanted %zu bytes.", {
s, logger(1, "Read from signal fd returned: %s", strerror(errno));
sizeof(struct signalfd_siginfo)); nDPIsrvd_main_thread_shutdown = 1;
}
else
{
logger(1,
"Invalid signal fd read size. Got %zd, wanted %zu bytes.",
s,
sizeof(struct signalfd_siginfo));
}
continue; continue;
} }
@@ -1454,6 +1490,7 @@ static int mainloop(struct nio * const io)
continue; continue;
} }
} }
#endif
else else
{ {
/* Incoming data / Outoing data ready to receive / send. */ /* Incoming data / Outoing data ready to receive / send. */
@@ -1467,7 +1504,9 @@ static int mainloop(struct nio * const io)
free_remotes(io); free_remotes(io);
nio_free(io); nio_free(io);
#if !defined(__FreeBSD__) && !defined(__APPLE__)
close(signalfd); close(signalfd);
#endif
return 0; return 0;
} }
@@ -1627,7 +1666,7 @@ int main(int argc, char ** argv)
"everyone with access to the device/network. You've been warned!"); "everyone with access to the device/network. You've been warned!");
break; break;
case AF_UNIX: case AF_UNIX:
case 0xFFFF: case (sa_family_t)0xFFFF:
break; break;
} }

View File

@@ -27,7 +27,15 @@ if [ -r "${NROOT}/nDPId-${NSUFFIX}.pid" -o -r "${NROOT}/nDPIsrvd-${NSUFFIX}.pid"
if [ x"${nDPId_PID}" != x ]; then if [ x"${nDPId_PID}" != x ]; then
sudo kill "${nDPId_PID}" 2>/dev/null || true sudo kill "${nDPId_PID}" 2>/dev/null || true
while ps -p "${nDPId_PID}" > /dev/null; do sleep 1; done
MAX_TRIES=10
while ps -p "${nDPId_PID}" > /dev/null; do
test ${MAX_TRIES} -gt 0 || break
sleep 1
MAX_TRIES=$((MAX_TRIES - 1))
done
test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPId not started' >&2; }
rm -f "${NROOT}/nDPId-${NSUFFIX}.pid" rm -f "${NROOT}/nDPId-${NSUFFIX}.pid"
else else
printf '%s\n' "${1} not started .." >&2 printf '%s\n' "${1} not started .." >&2
@@ -36,7 +44,15 @@ if [ -r "${NROOT}/nDPId-${NSUFFIX}.pid" -o -r "${NROOT}/nDPIsrvd-${NSUFFIX}.pid"
if [ x"${nDPIsrvd_PID}" != x ]; then if [ x"${nDPIsrvd_PID}" != x ]; then
kill "${nDPIsrvd_PID}" 2>/dev/null || true kill "${nDPIsrvd_PID}" 2>/dev/null || true
while ps -p "${nDPIsrvd_PID}" > /dev/null; do sleep 1; done
MAX_TRIES=10
while ps -p "${nDPIsrvd_PID}" > /dev/null; do
test ${MAX_TRIES} -gt 0 || break
sleep 1
MAX_TRIES=$((MAX_TRIES - 1))
done
test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd not started' >&2; }
rm -f "${NROOT}/nDPIsrvd-${NSUFFIX}.pid" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock" "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock" rm -f "${NROOT}/nDPIsrvd-${NSUFFIX}.pid" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock" "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock"
else else
printf '%s\n' "${2} not started .." >&2 printf '%s\n' "${2} not started .." >&2
@@ -54,14 +70,14 @@ else
sleep 0.5 sleep 0.5
MAX_TRIES=$((MAX_TRIES - 1)) MAX_TRIES=$((MAX_TRIES - 1))
done done
test ${MAX_TRIES} -eq 0 && RETVAL=1 test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd collector socket not available' >&2; }
MAX_TRIES=10 MAX_TRIES=10
while [ ! -S "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock" -a ${MAX_TRIES} -gt 0 ]; do while [ ! -S "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock" -a ${MAX_TRIES} -gt 0 ]; do
sleep 0.5 sleep 0.5
MAX_TRIES=$((MAX_TRIES - 1)) MAX_TRIES=$((MAX_TRIES - 1))
done done
test ${MAX_TRIES} -eq 0 && RETVAL=1 test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd distributor socket not available' >&2; }
sudo chgrp "$(id -n -g "${NUSER}")" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock" sudo chgrp "$(id -n -g "${NUSER}")" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock"
test $? -eq 0 || RETVAL=1 test $? -eq 0 || RETVAL=1

View File

@@ -32,7 +32,9 @@ if [ ! -z "${CC}" ]; then
fi fi
if [ ! -z "${MAKEFLAGS}" ]; then if [ ! -z "${MAKEFLAGS}" ]; then
MAKEFLAGS="-${MAKEFLAGS}" case "$(uname -s)" in
Linux*) MAKEFLAGS="-${MAKEFLAGS}" ;;
esac
fi fi
cat <<EOF cat <<EOF
@@ -102,7 +104,7 @@ MAKE_PROGRAM="${MAKE_PROGRAM:-make -j4}"
HOST_ARG="--host=${HOST_TRIPLET}" HOST_ARG="--host=${HOST_TRIPLET}"
./autogen.sh --enable-option-checking=fatal \ ./autogen.sh --enable-option-checking=fatal \
--prefix="/" \ --prefix="/" \
--with-only-libndpi ${HOST_ARG} ${ADDITIONAL_ARGS} --with-only-libndpi ${HOST_ARG} ${ADDITIONAL_ARGS} || { cat config.log | grep -v '^|'; false; }
${MAKE_PROGRAM} ${MAKEFLAGS} install DESTDIR="${DEST_INSTALL}" ${MAKE_PROGRAM} ${MAKEFLAGS} install DESTDIR="${DEST_INSTALL}"
rm -f "${LOCKFILE}" rm -f "${LOCKFILE}"

48
utils.c
View File

@@ -141,6 +141,7 @@ int is_path_absolute(char const * const prefix, char const * const path)
int daemonize_with_pidfile(char const * const pidfile) int daemonize_with_pidfile(char const * const pidfile)
{ {
pid_str ps = {}; pid_str ps = {};
int nullfd;
if (daemonize != 0) if (daemonize != 0)
{ {
@@ -156,12 +157,44 @@ int daemonize_with_pidfile(char const * const pidfile)
return 1; return 1;
} }
if (daemon(0, 0) != 0) nullfd = open("/dev/null", O_NONBLOCK, O_WRONLY);
if (nullfd < 0 || dup2(nullfd, STDIN_FILENO) < 0 || dup2(nullfd, STDOUT_FILENO) < 0 ||
dup2(nullfd, STDERR_FILENO) < 0)
{ {
logger_early(1, "daemon: %s", strerror(errno)); logger_early(1, "Opening /dev/null or replacing stdin/stdout/stderr failed: %s", strerror(errno));
return 1; return 1;
} }
// For compatiblity reasons, we use the UNIX double fork() technique.
switch (fork())
{
case 0:
break;
case -1:
logger_early(1, "Could not fork (first time): %s", strerror(errno));
return 1;
default:
exit(0);
}
if (chdir("/") < 0 || setsid() < 0)
{
logger_early(1, "chdir() / setsid() failed: %s", strerror(errno));
return 1;
}
switch (fork())
{
case 0:
break;
case -1:
logger_early(1, "Could not fork (second time): %s", strerror(errno));
return 1;
default:
exit(0);
}
if (create_pidfile(pidfile) != 0) if (create_pidfile(pidfile) != 0)
{ {
return 1; return 1;
@@ -401,6 +434,17 @@ __attribute__((format(printf, 2, 3))) void logger_early(int is_error, char const
log_to_console = old_log_to_console; log_to_console = old_log_to_console;
} }
int set_fd_cloexec(int fd)
{
int flags = fcntl(fd, F_GETFD, 0);
if (flags < 0)
{
return -1;
}
return fcntl(fd, F_SETFD, FD_CLOEXEC);
}
char const * get_nDPId_version(void) char const * get_nDPId_version(void)
{ {
return "nDPId version " return "nDPId version "

View File

@@ -56,6 +56,8 @@ __attribute__((format(printf, 2, 3))) void logger(int is_error, char const * con
__attribute__((format(printf, 2, 3))) void logger_early(int is_error, char const * const format, ...); __attribute__((format(printf, 2, 3))) void logger_early(int is_error, char const * const format, ...);
int set_fd_cloexec(int fd);
char const * get_nDPId_version(void); char const * get_nDPId_version(void);
#endif #endif