Compare commits

..

2 commits

Author SHA1 Message Date
Tim Wojtulewicz
1addeab4fe Updating CHANGES and VERSION. 2025-08-04 09:44:48 -07:00
Christian Kreibich
c1cb1a2e5f Compile contributors for Zeek 8.0 in the NEWS file
(cherry picked from commit 4fdd83f3f5)
2025-08-04 09:39:08 -07:00
648 changed files with 4221 additions and 312670 deletions

View file

@ -48,108 +48,53 @@ freebsd_environment: &FREEBSD_ENVIRONMENT
ZEEK_CI_CPUS: 8 ZEEK_CI_CPUS: 8
ZEEK_CI_BTEST_JOBS: 8 ZEEK_CI_BTEST_JOBS: 8
only_if_pr_master_release: &ONLY_IF_PR_MASTER_RELEASE builds_only_if_template: &BUILDS_ONLY_IF_TEMPLATE
# Rules for skipping builds:
# - Do not run builds for anything that's cron triggered
# - Don't do darwin builds on zeek-security repo because they use up a ton of compute credits.
# - Always build PRs, but not if they come from dependabot
# - Always build master and release/* builds from the main repo
only_if: > only_if: >
( $CIRRUS_CRON == '' ) &&
( ( $CIRRUS_PR != '' && $CIRRUS_BRANCH !=~ 'dependabot/.*' ) ||
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) && ( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
( $CIRRUS_CRON != 'weekly' ) && (
( $CIRRUS_PR != '' || $CIRRUS_BRANCH == 'master' ||
$CIRRUS_BRANCH == 'master' || $CIRRUS_BRANCH =~ 'release/.*'
$CIRRUS_BRANCH =~ 'release/.*'
) )
) ) )
only_if_pr_master_release_nightly: &ONLY_IF_PR_MASTER_RELEASE_NIGHTLY skip_task_on_pr: &SKIP_TASK_ON_PR
# Skip this task on PRs if it does not have the CI: Full label,
# it continues to run for direct pushes to master/release.
skip: >
( ! ($CIRRUS_PR == '' || $CIRRUS_PR_LABELS =~ '.*CI: Full.*') || $CIRRUS_PR_LABELS =~ '.*CI: Skip All' )
skip_cluster_test_on_pr: &SKIP_CLUSTER_TEST_ON_PR
# Skip this task on PRs if it does not have the CI: Full label,
# it continues to run for direct pushes to master/release.
skip: >
( ! ($CIRRUS_PR == '' || $CIRRUS_PR_LABELS =~ '.*CI: (Full|Cluster Test).*') || $CIRRUS_PR_LABELS =~ '.*CI: Skip All' )
zam_skip_task_on_pr: &ZAM_SKIP_TASK_ON_PR
# Skip this task on PRs unless it has the "CI: Full" or "CI: ZAM" label
# or files in src/script_opt/** were modified.
# It continues to run for direct pushes to master/release, as
# CIRRUS_PR will be empty.
skip: >
( ! ($CIRRUS_PR == '' || $CIRRUS_PR_LABELS =~ '.*CI: (Full|ZAM).*' || changesInclude('src/script_opt/**')) || $CIRRUS_PR_LABELS =~ '.*CI: Skip All' )
benchmark_only_if_template: &BENCHMARK_ONLY_IF_TEMPLATE
# only_if condition for cron-triggered benchmarking tests.
# These currently do not run for release/.*
only_if: > only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) && ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
( $CIRRUS_CRON != 'weekly' ) && ( $CIRRUS_CRON == 'benchmark-nightly' ||
( $CIRRUS_PR != '' || $CIRRUS_PR_LABELS =~ '.*CI: (Full|Benchmark).*' )
$CIRRUS_BRANCH == 'master' ||
$CIRRUS_BRANCH =~ 'release/.*' ||
( $CIRRUS_CRON == 'nightly' && $CIRRUS_BRANCH == 'master' )
)
)
only_if_pr_release_and_nightly: &ONLY_IF_PR_RELEASE_AND_NIGHTLY
only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
( $CIRRUS_CRON != 'weekly' ) &&
( $CIRRUS_PR != '' ||
$CIRRUS_BRANCH =~ 'release/.*' ||
( $CIRRUS_CRON == 'nightly' && $CIRRUS_BRANCH == 'master' )
)
)
only_if_pr_nightly: &ONLY_IF_PR_NIGHTLY
only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
( $CIRRUS_CRON != 'weekly' ) &&
( $CIRRUS_PR != '' ||
( $CIRRUS_CRON == 'nightly' && $CIRRUS_BRANCH == 'master' )
)
)
only_if_release_tag_nightly: &ONLY_IF_RELEASE_TAG_NIGHTLY
only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' ) &&
( $CIRRUS_CRON != 'weekly' ) &&
( ( $CIRRUS_BRANCH =~ 'release/.*' && $CIRRUS_TAG =~ 'v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$' ) ||
( $CIRRUS_CRON == 'nightly' && $CIRRUS_BRANCH == 'master' )
)
)
only_if_nightly: &ONLY_IF_NIGHTLY
only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' ) &&
( $CIRRUS_CRON == 'nightly' && $CIRRUS_BRANCH == 'master' )
)
only_if_weekly: &ONLY_IF_WEEKLY
only_if: >
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
( $CIRRUS_CRON == 'weekly' && $CIRRUS_BRANCH == 'master' )
)
skip_if_pr_skip_all: &SKIP_IF_PR_SKIP_ALL
skip: >
( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
skip_if_pr_not_full_ci: &SKIP_IF_PR_NOT_FULL_CI
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: Full.*") ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
skip_if_pr_not_full_or_benchmark: &SKIP_IF_PR_NOT_FULL_OR_BENCHMARK
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: (Full|Benchmark).*" ) ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
skip_if_pr_not_full_or_cluster_test: &SKIP_IF_PR_NOT_FULL_OR_CLUSTER_TEST
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: (Full|Cluster Test).*" ) ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
skip_if_pr_not_full_or_zam: &SKIP_IF_PR_NOT_FULL_OR_ZAM
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: (Full|ZAM).*" ) ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
skip_if_pr_not_full_or_zeekctl: &SKIP_IF_PR_NOT_FULL_OR_ZEEKCTL
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: (Full|Zeekctl).*" ) ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
skip_if_pr_not_full_or_windows: &SKIP_IF_PR_NOT_FULL_OR_WINDOWS
skip: >
( ( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ ".*CI: (Full|Windows).*" ) ||
( $CIRRUS_PR_LABELS =~ ".*CI: Skip All.*" )
)
ci_template: &CI_TEMPLATE ci_template: &CI_TEMPLATE
<< : *BUILDS_ONLY_IF_TEMPLATE
# Default timeout is 60 minutes, Cirrus hard limit is 120 minutes for free # Default timeout is 60 minutes, Cirrus hard limit is 120 minutes for free
# tasks, so may as well ask for full time. # tasks, so may as well ask for full time.
timeout_in: 120m timeout_in: 120m
@ -191,9 +136,12 @@ ci_template: &CI_TEMPLATE
# Evit some of the cached build artifacts not used in this build. # Evit some of the cached build artifacts not used in this build.
CCACHE_MAXSIZE=${ZEEK_CCACHE_PRUNE_SIZE} ccache -c CCACHE_MAXSIZE=${ZEEK_CCACHE_PRUNE_SIZE} ccache -c
# Always skip all tasks on a PR if the "CI: Skip All" label is applied.
skip: >
$CIRRUS_PR != '' && $CIRRUS_PR_LABELS =~ '.*CI: Skip All.*'
env: env:
CIRRUS_WORKING_DIR: /zeek CIRRUS_WORKING_DIR: /zeek
CIRRUS_LOG_TIMESTAMP: true
ZEEK_CI_CPUS: *CPUS ZEEK_CI_CPUS: *CPUS
ZEEK_CI_BTEST_JOBS: *BTEST_JOBS ZEEK_CI_BTEST_JOBS: *BTEST_JOBS
ZEEK_CI_BTEST_RETRIES: *BTEST_RETRIES ZEEK_CI_BTEST_RETRIES: *BTEST_RETRIES
@ -244,10 +192,6 @@ fedora42_task:
dockerfile: ci/fedora-42/Dockerfile dockerfile: ci/fedora-42/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
env:
ZEEK_CI_CONFIGURE_FLAGS: *BINARY_CONFIG
fedora41_task: fedora41_task:
container: container:
@ -255,71 +199,14 @@ fedora41_task:
dockerfile: ci/fedora-41/Dockerfile dockerfile: ci/fedora-41/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
centosstream9_task: centosstream9_task:
container: container:
# Stream 9 EOL: 31 May 2027 # Stream 9 EOL: Around Dec 2027
dockerfile: ci/centos-stream-9/Dockerfile dockerfile: ci/centos-stream-9/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
centosstream10_task:
container:
# Stream 10 EOL: 01 January 2030
dockerfile: ci/centos-stream-10/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
debian13_task:
container:
# Debian 13 (trixie) EOL: TBD
dockerfile: ci/debian-13/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
arm_debian13_task:
arm_container:
# Debian 13 (trixie) EOL: TBD
dockerfile: ci/debian-13/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
debian13_static_task:
container:
# Just use a recent/common distro to run a static compile test.
# Debian 13 (trixie) EOL: TBD
dockerfile: ci/debian-13/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
env:
ZEEK_CI_CONFIGURE_FLAGS: *STATIC_CONFIG
debian13_binary_task:
container:
# Just use a recent/common distro to run binary mode compile test.
# As of 2024-03, the used configure flags are equivalent to the flags
# that we use to create binary packages.
# Just use a recent/common distro to run a static compile test.
# Debian 13 (trixie) EOL: TBD
dockerfile: ci/debian-13/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
env:
ZEEK_CI_CONFIGURE_FLAGS: *BINARY_CONFIG
debian12_task: debian12_task:
container: container:
@ -327,8 +214,48 @@ debian12_task:
dockerfile: ci/debian-12/Dockerfile dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI arm_debian12_task:
arm_container:
# Debian 12 (bookworm) EOL: TBD
dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
env:
ZEEK_CI_CONFIGURE_FLAGS: *NO_SPICY_CONFIG
debian12_static_task:
container:
# Just use a recent/common distro to run a static compile test.
# Debian 12 (bookworm) EOL: TBD
dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *SKIP_TASK_ON_PR
env:
ZEEK_CI_CONFIGURE_FLAGS: *STATIC_CONFIG
debian12_binary_task:
container:
# Just use a recent/common distro to run binary mode compile test.
# As of 2024-03, the used configure flags are equivalent to the flags
# that we use to create binary packages.
# Just use a recent/common distro to run a static compile test.
# Debian 12 (bookworm) EOL: TBD
dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *SKIP_TASK_ON_PR
env:
ZEEK_CI_CONFIGURE_FLAGS: *BINARY_CONFIG
debian11_task:
container:
# Debian 11 EOL: June 2026
dockerfile: ci/debian-11/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *SKIP_TASK_ON_PR
opensuse_leap_15_6_task: opensuse_leap_15_6_task:
container: container:
@ -336,8 +263,6 @@ opensuse_leap_15_6_task:
dockerfile: ci/opensuse-leap-15.6/Dockerfile dockerfile: ci/opensuse-leap-15.6/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
opensuse_tumbleweed_task: opensuse_tumbleweed_task:
container: container:
@ -346,8 +271,7 @@ opensuse_tumbleweed_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
prepare_script: ./ci/opensuse-tumbleweed/prepare.sh prepare_script: ./ci/opensuse-tumbleweed/prepare.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE # << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
weekly_current_gcc_task: weekly_current_gcc_task:
container: container:
@ -356,7 +280,8 @@ weekly_current_gcc_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
prepare_script: ./ci/opensuse-tumbleweed/prepare-weekly.sh prepare_script: ./ci/opensuse-tumbleweed/prepare-weekly.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_WEEKLY only_if: >
$CIRRUS_REPO_NAME == 'zeek' && $CIRRUS_BRANCH == 'master' && $CIRRUS_CRON == 'weekly'
env: env:
ZEEK_CI_COMPILER: gcc ZEEK_CI_COMPILER: gcc
@ -367,42 +292,33 @@ weekly_current_clang_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
prepare_script: ./ci/opensuse-tumbleweed/prepare-weekly.sh prepare_script: ./ci/opensuse-tumbleweed/prepare-weekly.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_WEEKLY only_if: >
$CIRRUS_REPO_NAME == 'zeek' && $CIRRUS_BRANCH == 'master' && $CIRRUS_CRON == 'weekly'
env: env:
ZEEK_CI_COMPILER: clang ZEEK_CI_COMPILER: clang
ubuntu25_04_task: ubuntu24_10_task:
container: container:
# Ubuntu 25.04 EOL: 2026-01-31 # Ubuntu 24.10 EOL: 2025-07-30
dockerfile: ci/ubuntu-25.04/Dockerfile dockerfile: ci/ubuntu-24.10/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
ubuntu24_04_task: ubuntu24_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 24.04 EOL: Jun 2029
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-24.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
env:
ZEEK_CI_CREATE_ARTIFACT: 1
upload_binary_artifacts:
path: build.tgz
benchmark_script: ./ci/benchmark.sh
# Same as above, but running the ZAM tests instead of the regular tests. # Same as above, but running the ZAM tests instead of the regular tests.
ubuntu24_04_zam_task: ubuntu24_zam_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 24.04 EOL: Jun 2029
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-24.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_OR_ZAM
env: env:
ZEEK_CI_SKIP_UNIT_TESTS: 1 ZEEK_CI_SKIP_UNIT_TESTS: 1
ZEEK_CI_SKIP_EXTERNAL_BTESTS: 1 ZEEK_CI_SKIP_EXTERNAL_BTESTS: 1
@ -411,41 +327,62 @@ ubuntu24_04_zam_task:
ZEEK_CI_BTEST_JOBS: 3 ZEEK_CI_BTEST_JOBS: 3
# Same as above, but using Clang and libc++ # Same as above, but using Clang and libc++
ubuntu24_04_clang_libcpp_task: ubuntu24_clang_libcpp_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 24.04 EOL: Jun 2029
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-24.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
env: env:
CC: clang-19 CC: clang-19
CXX: clang++-19 CXX: clang++-19
CXXFLAGS: -stdlib=libc++ CXXFLAGS: -stdlib=libc++
ubuntu24_04_clang_tidy_task: ubuntu24_clang_tidy_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 24.04 EOL: Jun 2029
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-24.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE # Run on merges to master and release/.* and benchmark-nightly cron.
<< : *SKIP_IF_PR_NOT_FULL_CI only_if: >
( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
$CIRRUS_BRANCH == 'master' ||
$CIRRUS_BRANCH =~ 'release/.*' ||
$CIRRUS_CRON == 'benchmark-nightly'
env: env:
CC: clang-19 CC: clang-19
CXX: clang++-19 CXX: clang++-19
ZEEK_CI_CONFIGURE_FLAGS: *CLANG_TIDY_CONFIG ZEEK_CI_CONFIGURE_FLAGS: *CLANG_TIDY_CONFIG
# Also enable Spicy SSL for this
ubuntu24_04_spicy_task: ubuntu22_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 22.04 EOL: June 2027
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-22.04/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
env:
ZEEK_CI_CREATE_ARTIFACT: 1
upload_binary_artifacts:
path: build.tgz
benchmark_script: ./ci/benchmark.sh
# Run on PRs, merges to master and release/.* and benchmark-nightly cron.
only_if: >
( $CIRRUS_PR != '' && $CIRRUS_BRANCH !=~ 'dependabot/.*' ) ||
( ( $CIRRUS_REPO_NAME == 'zeek' || $CIRRUS_REPO_NAME == 'zeek-security' ) &&
$CIRRUS_BRANCH == 'master' ||
$CIRRUS_BRANCH =~ 'release/.*' ||
$CIRRUS_CRON == 'benchmark-nightly' )
# Also enable Spicy SSL for this
ubuntu22_spicy_task:
container:
# Ubuntu 22.04 EOL: April 2027
dockerfile: ci/ubuntu-22.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_OR_BENCHMARK
env: env:
ZEEK_CI_CREATE_ARTIFACT: 1 ZEEK_CI_CREATE_ARTIFACT: 1
ZEEK_CI_CONFIGURE_FLAGS: *SPICY_SSL_CONFIG ZEEK_CI_CONFIGURE_FLAGS: *SPICY_SSL_CONFIG
@ -453,15 +390,14 @@ ubuntu24_04_spicy_task:
upload_binary_artifacts: upload_binary_artifacts:
path: build.tgz path: build.tgz
benchmark_script: ./ci/benchmark.sh benchmark_script: ./ci/benchmark.sh
<< : *BENCHMARK_ONLY_IF_TEMPLATE
ubuntu24_04_spicy_head_task: ubuntu22_spicy_head_task:
container: container:
# Ubuntu 24.04 EOL: Jun 2029 # Ubuntu 22.04 EOL: April 2027
dockerfile: ci/ubuntu-24.04/Dockerfile dockerfile: ci/ubuntu-22.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE_NIGHTLY
<< : *SKIP_IF_PR_NOT_FULL_OR_BENCHMARK
env: env:
ZEEK_CI_CREATE_ARTIFACT: 1 ZEEK_CI_CREATE_ARTIFACT: 1
ZEEK_CI_CONFIGURE_FLAGS: *SPICY_SSL_CONFIG ZEEK_CI_CONFIGURE_FLAGS: *SPICY_SSL_CONFIG
@ -471,15 +407,10 @@ ubuntu24_04_spicy_head_task:
upload_binary_artifacts: upload_binary_artifacts:
path: build.tgz path: build.tgz
benchmark_script: ./ci/benchmark.sh benchmark_script: ./ci/benchmark.sh
# Don't run this job on release branches. It tests against spicy HEAD, which
ubuntu22_04_task: # will frequently require other fixes that won't be in a release branch.
container: skip: $CIRRUS_BRANCH =~ 'release/.*'
# Ubuntu 22.04 EOL: June 2027 << : *BENCHMARK_ONLY_IF_TEMPLATE
dockerfile: ci/ubuntu-22.04/Dockerfile
<< : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
alpine_task: alpine_task:
container: container:
@ -489,8 +420,6 @@ alpine_task:
dockerfile: ci/alpine/Dockerfile dockerfile: ci/alpine/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_CI
# Cirrus only supports the following macos runner currently, selecting # Cirrus only supports the following macos runner currently, selecting
# anything else automatically upgrades to this one. # anything else automatically upgrades to this one.
@ -503,8 +432,6 @@ macos_sequoia_task:
image: ghcr.io/cirruslabs/macos-runner:sequoia image: ghcr.io/cirruslabs/macos-runner:sequoia
prepare_script: ./ci/macos/prepare.sh prepare_script: ./ci/macos/prepare.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
<< : *MACOS_ENVIRONMENT << : *MACOS_ENVIRONMENT
# FreeBSD EOL timelines: https://www.freebsd.org/security/#sup # FreeBSD EOL timelines: https://www.freebsd.org/security/#sup
@ -516,8 +443,6 @@ freebsd14_task:
prepare_script: ./ci/freebsd/prepare.sh prepare_script: ./ci/freebsd/prepare.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
<< : *FREEBSD_ENVIRONMENT << : *FREEBSD_ENVIRONMENT
freebsd13_task: freebsd13_task:
@ -528,8 +453,7 @@ freebsd13_task:
prepare_script: ./ci/freebsd/prepare.sh prepare_script: ./ci/freebsd/prepare.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
<< : *FREEBSD_ENVIRONMENT << : *FREEBSD_ENVIRONMENT
asan_sanitizer_task: asan_sanitizer_task:
@ -539,8 +463,6 @@ asan_sanitizer_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_SKIP_ALL
test_fuzzers_script: ./ci/test-fuzzers.sh test_fuzzers_script: ./ci/test-fuzzers.sh
coverage_script: ./ci/upload-coverage.sh coverage_script: ./ci/upload-coverage.sh
env: env:
@ -557,8 +479,6 @@ asan_sanitizer_zam_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_NIGHTLY
<< : *SKIP_IF_PR_NOT_FULL_OR_ZAM
env: env:
ZEEK_CI_CONFIGURE_FLAGS: *ASAN_SANITIZER_CONFIG ZEEK_CI_CONFIGURE_FLAGS: *ASAN_SANITIZER_CONFIG
ASAN_OPTIONS: detect_leaks=1:detect_odr_violation=0 ASAN_OPTIONS: detect_leaks=1:detect_odr_violation=0
@ -567,6 +487,7 @@ asan_sanitizer_zam_task:
ZEEK_CI_BTEST_EXTRA_ARGS: -a zam ZEEK_CI_BTEST_EXTRA_ARGS: -a zam
# Use a lower number of jobs due to OOM issues with ZAM tasks # Use a lower number of jobs due to OOM issues with ZAM tasks
ZEEK_CI_BTEST_JOBS: 3 ZEEK_CI_BTEST_JOBS: 3
<< : *ZAM_SKIP_TASK_ON_PR
ubsan_sanitizer_task: ubsan_sanitizer_task:
container: container:
@ -575,8 +496,7 @@ ubsan_sanitizer_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_NIGHTLY << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
test_fuzzers_script: ./ci/test-fuzzers.sh test_fuzzers_script: ./ci/test-fuzzers.sh
env: env:
CC: clang-19 CC: clang-19
@ -592,8 +512,6 @@ ubsan_sanitizer_zam_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_NIGHTLY
<< : *SKIP_IF_PR_NOT_FULL_OR_ZAM
env: env:
CC: clang-19 CC: clang-19
CXX: clang++-19 CXX: clang++-19
@ -605,6 +523,7 @@ ubsan_sanitizer_zam_task:
ZEEK_CI_BTEST_EXTRA_ARGS: -a zam ZEEK_CI_BTEST_EXTRA_ARGS: -a zam
# Use a lower number of jobs due to OOM issues with ZAM tasks # Use a lower number of jobs due to OOM issues with ZAM tasks
ZEEK_CI_BTEST_JOBS: 3 ZEEK_CI_BTEST_JOBS: 3
<< : *ZAM_SKIP_TASK_ON_PR
tsan_sanitizer_task: tsan_sanitizer_task:
container: container:
@ -613,8 +532,7 @@ tsan_sanitizer_task:
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
<< : *ONLY_IF_PR_NIGHTLY << : *SKIP_TASK_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_CI
env: env:
CC: clang-19 CC: clang-19
CXX: clang++-19 CXX: clang++-19
@ -638,12 +556,13 @@ windows_task:
prepare_script: ci/windows/prepare.cmd prepare_script: ci/windows/prepare.cmd
build_script: ci/windows/build.cmd build_script: ci/windows/build.cmd
test_script: ci/windows/test.cmd test_script: ci/windows/test.cmd
<< : *ONLY_IF_PR_MASTER_RELEASE
<< : *SKIP_IF_PR_NOT_FULL_OR_WINDOWS
env: env:
ZEEK_CI_CPUS: 8 ZEEK_CI_CPUS: 8
# Give verbose error output on a test failure. # Give verbose error output on a test failure.
CTEST_OUTPUT_ON_FAILURE: 1 CTEST_OUTPUT_ON_FAILURE: 1
<< : *BUILDS_ONLY_IF_TEMPLATE
skip: >
$CIRRUS_PR != '' && $CIRRUS_PR_LABELS =~ '.*CI: Skip All.*'
# Container images # Container images
@ -724,18 +643,22 @@ arm64_container_image_docker_builder:
env: env:
CIRRUS_ARCH: arm64 CIRRUS_ARCH: arm64
<< : *DOCKER_BUILD_TEMPLATE << : *DOCKER_BUILD_TEMPLATE
<< : *ONLY_IF_RELEASE_TAG_NIGHTLY << : *SKIP_TASK_ON_PR
amd64_container_image_docker_builder: amd64_container_image_docker_builder:
env: env:
CIRRUS_ARCH: amd64 CIRRUS_ARCH: amd64
<< : *DOCKER_BUILD_TEMPLATE << : *DOCKER_BUILD_TEMPLATE
<< : *ONLY_IF_PR_MASTER_RELEASE_NIGHTLY << : *SKIP_CLUSTER_TEST_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_OR_CLUSTER_TEST
container_image_manifest_docker_builder: container_image_manifest_docker_builder:
cpu: 1 cpu: 1
<< : *ONLY_IF_RELEASE_TAG_NIGHTLY # Push master builds to zeek/zeek-dev, or tagged release branches to zeek/zeek
only_if: >
( $CIRRUS_CRON == '' ) &&
( $CIRRUS_REPO_FULL_NAME == 'zeek/zeek' &&
( $CIRRUS_BRANCH == 'master' ||
$CIRRUS_TAG =~ 'v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$' ) )
env: env:
DOCKER_USERNAME: ENCRYPTED[!505b3dee552a395730a7e79e6aab280ffbe1b84ec62ae7616774dfefe104e34f896d2e20ce3ad701f338987c13c33533!] DOCKER_USERNAME: ENCRYPTED[!505b3dee552a395730a7e79e6aab280ffbe1b84ec62ae7616774dfefe104e34f896d2e20ce3ad701f338987c13c33533!]
DOCKER_PASSWORD: ENCRYPTED[!6c4b2f6f0e5379ef1091719cc5d2d74c90cfd2665ac786942033d6d924597ffb95dbbc1df45a30cc9ddeec76c07ac620!] DOCKER_PASSWORD: ENCRYPTED[!6c4b2f6f0e5379ef1091719cc5d2d74c90cfd2665ac786942033d6d924597ffb95dbbc1df45a30cc9ddeec76c07ac620!]
@ -814,7 +737,8 @@ container_image_manifest_docker_builder:
# images from the public ECR repository to stay within free-tier bounds. # images from the public ECR repository to stay within free-tier bounds.
public_ecr_cleanup_docker_builder: public_ecr_cleanup_docker_builder:
cpu: 1 cpu: 1
<< : *ONLY_IF_NIGHTLY only_if: >
$CIRRUS_CRON == '' && $CIRRUS_REPO_FULL_NAME == 'zeek/zeek' && $CIRRUS_BRANCH == 'master'
env: env:
AWS_ACCESS_KEY_ID: ENCRYPTED[!eff52f6442e1bc78bce5b15a23546344df41bf519f6201924cb70c7af12db23f442c0e5f2b3687c2d856ceb11fcb8c49!] AWS_ACCESS_KEY_ID: ENCRYPTED[!eff52f6442e1bc78bce5b15a23546344df41bf519f6201924cb70c7af12db23f442c0e5f2b3687c2d856ceb11fcb8c49!]
AWS_SECRET_ACCESS_KEY: ENCRYPTED[!748bc302dd196140a5fa8e89c9efd148882dc846d4e723787d2de152eb136fa98e8dea7e6d2d6779d94f72dd3c088228!] AWS_SECRET_ACCESS_KEY: ENCRYPTED[!748bc302dd196140a5fa8e89c9efd148882dc846d4e723787d2de152eb136fa98e8dea7e6d2d6779d94f72dd3c088228!]
@ -854,8 +778,7 @@ cluster_testing_docker_builder:
path: "testing/external/zeek-testing-cluster/.tmp/**" path: "testing/external/zeek-testing-cluster/.tmp/**"
depends_on: depends_on:
- amd64_container_image - amd64_container_image
<< : *ONLY_IF_PR_RELEASE_AND_NIGHTLY << : *SKIP_CLUSTER_TEST_ON_PR
<< : *SKIP_IF_PR_NOT_FULL_OR_CLUSTER_TEST
# Test zeekctl upon master and release pushes and also when # Test zeekctl upon master and release pushes and also when
@ -866,11 +789,16 @@ cluster_testing_docker_builder:
zeekctl_debian12_task: zeekctl_debian12_task:
cpu: *CPUS cpu: *CPUS
memory: *MEMORY memory: *MEMORY
<< : *ONLY_IF_PR_MASTER_RELEASE only_if: >
<< : *SKIP_IF_PR_NOT_FULL_OR_ZEEKCTL ( $CIRRUS_CRON == 'zeekctl-nightly' ) ||
( $CIRRUS_PR != '' && $CIRRUS_PR_LABELS =~ '.*CI: (Zeekctl|Full).*' ) ||
( $CIRRUS_REPO_NAME == 'zeek' && (
$CIRRUS_BRANCH == 'master' ||
$CIRRUS_BRANCH =~ 'release/.*' )
)
container: container:
# Debian 13 (trixie) EOL: TBD # Debian 12 (bookworm) EOL: TBD
dockerfile: ci/debian-13/Dockerfile dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
sync_submodules_script: git submodule update --recursive --init sync_submodules_script: git submodule update --recursive --init
always: always:
@ -893,8 +821,8 @@ include_plugins_debian12_task:
cpu: *CPUS cpu: *CPUS
memory: *MEMORY memory: *MEMORY
container: container:
# Debian 13 (trixie) EOL: TBD # Debian 12 (bookworm) EOL: TBD
dockerfile: ci/debian-13/Dockerfile dockerfile: ci/debian-12/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
sync_submodules_script: git submodule update --recursive --init sync_submodules_script: git submodule update --recursive --init
fetch_external_plugins_script: fetch_external_plugins_script:
@ -925,5 +853,5 @@ include_plugins_debian12_task:
on_failure: on_failure:
upload_include_plugins_testing_artifacts: upload_include_plugins_testing_artifacts:
path: "testing/builtin-plugins/.tmp/**" path: "testing/builtin-plugins/.tmp/**"
<< : *ONLY_IF_PR_MASTER_RELEASE << : *BUILDS_ONLY_IF_TEMPLATE
<< : *SKIP_IF_PR_NOT_FULL_CI << : *SKIP_TASK_ON_PR

View file

@ -3,7 +3,6 @@ Checks: [-*,
performance-*, performance-*,
modernize-*, modernize-*,
readability-isolate-declaration, readability-isolate-declaration,
readability-container-contains,
# Enable a very limited number of the cppcoreguidelines checkers. # Enable a very limited number of the cppcoreguidelines checkers.
# See the notes for some of the rest of them below. # See the notes for some of the rest of them below.

View file

@ -66,14 +66,16 @@ jobs:
make \ make \
python3 \ python3 \
python3-dev \ python3-dev \
python3-pip \ python3-pip\
sqlite3 \ sqlite3 \
swig \ swig \
zlib1g-dev zlib1g-dev
python3 -m venv ci-docs-venv # Many distros adhere to PEP 394's recommendation for `python` =
source ci-docs-venv/bin/activate # `python2` so this is a simple workaround until we drop Python 2
pip3 install -r doc/requirements.txt # support and explicitly use `python3` for all invocations.
pip3 install pre-commit sudo ln -sf /usr/bin/python3 /usr/local/bin/python
sudo pip3 install --break-system-packages -r doc/requirements.txt
sudo pip3 install --break-system-packages pre-commit
- name: ccache - name: ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
@ -110,7 +112,6 @@ jobs:
- name: Generate Docs - name: Generate Docs
run: | run: |
source ci-docs-venv/bin/activate
git config --global user.name zeek-bot git config --global user.name zeek-bot
git config --global user.email info@zeek.org git config --global user.email info@zeek.org

15
.gitmodules vendored
View file

@ -1,6 +1,9 @@
[submodule "auxil/zeek-aux"] [submodule "auxil/zeek-aux"]
path = auxil/zeek-aux path = auxil/zeek-aux
url = https://github.com/zeek/zeek-aux url = https://github.com/zeek/zeek-aux
[submodule "auxil/binpac"]
path = auxil/binpac
url = https://github.com/zeek/binpac
[submodule "auxil/zeekctl"] [submodule "auxil/zeekctl"]
path = auxil/zeekctl path = auxil/zeekctl
url = https://github.com/zeek/zeekctl url = https://github.com/zeek/zeekctl
@ -10,12 +13,18 @@
[submodule "cmake"] [submodule "cmake"]
path = cmake path = cmake
url = https://github.com/zeek/cmake url = https://github.com/zeek/cmake
[submodule "src/3rdparty"]
path = src/3rdparty
url = https://github.com/zeek/zeek-3rdparty
[submodule "auxil/broker"] [submodule "auxil/broker"]
path = auxil/broker path = auxil/broker
url = https://github.com/zeek/broker url = https://github.com/zeek/broker
[submodule "auxil/netcontrol-connectors"] [submodule "auxil/netcontrol-connectors"]
path = auxil/netcontrol-connectors path = auxil/netcontrol-connectors
url = https://github.com/zeek/zeek-netcontrol url = https://github.com/zeek/zeek-netcontrol
[submodule "auxil/bifcl"]
path = auxil/bifcl
url = https://github.com/zeek/bifcl
[submodule "doc"] [submodule "doc"]
path = doc path = doc
url = https://github.com/zeek/zeek-docs url = https://github.com/zeek/zeek-docs
@ -37,6 +46,9 @@
[submodule "auxil/zeek-client"] [submodule "auxil/zeek-client"]
path = auxil/zeek-client path = auxil/zeek-client
url = https://github.com/zeek/zeek-client url = https://github.com/zeek/zeek-client
[submodule "auxil/gen-zam"]
path = auxil/gen-zam
url = https://github.com/zeek/gen-zam
[submodule "auxil/c-ares"] [submodule "auxil/c-ares"]
path = auxil/c-ares path = auxil/c-ares
url = https://github.com/c-ares/c-ares url = https://github.com/c-ares/c-ares
@ -46,6 +58,9 @@
[submodule "auxil/spicy"] [submodule "auxil/spicy"]
path = auxil/spicy path = auxil/spicy
url = https://github.com/zeek/spicy url = https://github.com/zeek/spicy
[submodule "auxil/zeek-af_packet-plugin"]
path = auxil/zeek-af_packet-plugin
url = https://github.com/zeek/zeek-af_packet-plugin.git
[submodule "auxil/libunistd"] [submodule "auxil/libunistd"]
path = auxil/libunistd path = auxil/libunistd
url = https://github.com/zeek/libunistd url = https://github.com/zeek/libunistd

View file

@ -10,7 +10,7 @@ repos:
language: python language: python
files: '\.(h|c|cpp|cc|spicy|evt)$' files: '\.(h|c|cpp|cc|spicy|evt)$'
types: [file] types: [file]
exclude: '^(testing/btest/(Baseline|plugins|spicy|scripts)/.*|testing/builtin-plugins/.*|src/3rdparty/.*)$' exclude: '^(testing/btest/(Baseline|plugins|spicy|scripts)/.*|testing/builtin-plugins/.*)$'
- id: btest-command-commented - id: btest-command-commented
name: Check that all BTest command lines are commented out name: Check that all BTest command lines are commented out
@ -19,26 +19,25 @@ repos:
files: '^testing/btest/.*$' files: '^testing/btest/.*$'
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: v20.1.8 rev: v20.1.7
hooks: hooks:
- id: clang-format - id: clang-format
types_or: types_or:
- "c" - "c"
- "c++" - "c++"
- "json" - "json"
exclude: '^src/3rdparty/.*'
- repo: https://github.com/maxwinterstein/shfmt-py - repo: https://github.com/maxwinterstein/shfmt-py
rev: v3.12.0.1 rev: v3.11.0.2
hooks: hooks:
- id: shfmt - id: shfmt
args: ["-w", "-i", "4", "-ci"] args: ["-w", "-i", "4", "-ci"]
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.8 rev: v0.12.1
hooks: hooks:
- id: ruff-check - id: ruff
args: ["--fix"] args: [--fix]
- id: ruff-format - id: ruff-format
- repo: https://github.com/cheshirekow/cmake-format-precommit - repo: https://github.com/cheshirekow/cmake-format-precommit
@ -47,10 +46,10 @@ repos:
- id: cmake-format - id: cmake-format
- repo: https://github.com/crate-ci/typos - repo: https://github.com/crate-ci/typos
rev: v1.35.3 rev: v1.33.1
hooks: hooks:
- id: typos - id: typos
exclude: '^(.typos.toml|src/SmithWaterman.cc|testing/.*|auxil/.*|scripts/base/frameworks/files/magic/.*|CHANGES|scripts/base/protocols/ssl/mozilla-ca-list.zeek|src/3rdparty/.*)$' exclude: '^(.typos.toml|src/SmithWaterman.cc|testing/.*|auxil/.*|scripts/base/frameworks/files/magic/.*|CHANGES|scripts/base/protocols/ssl/mozilla-ca-list.zeek)$'
- repo: https://github.com/bbannier/spicy-format - repo: https://github.com/bbannier/spicy-format
rev: v0.26.0 rev: v0.26.0

724
CHANGES
View file

@ -1,728 +1,12 @@
8.1.0-dev.626 | 2025-10-02 14:10:44 +0200 8.0.0-rc1 | 2025-08-04 09:39:08 -0700
* GH-4845: iosource/Packet: Allow ToRawPktHdrVal() for reassembled packets (Arne Welzel, Corelight) * Release 8.0.0-rc1.
Closes #4845 8.0.0-dev.828 | 2025-08-04 09:38:55 -0700
8.1.0-dev.624 | 2025-10-02 09:15:17 +0200
* Conn: Improve packing, drop bitfields and boolenize (Arne Welzel, Corelight)
There's a few holes in Conn, particularly now that TransportProto has
become a uint8_t. Pack things a bit more neatly.
* Conn: Lazily initialize weird_state when needed (Arne Welzel, Corelight)
A std::unordered_map takes 56 bytes on my system. Switch to a unique_ptr
an initialize weird_state lazily. That saves ~48 bytes per connection.
Particularly for scan or non-weird traffic, this should allow some
memory savings.
8.1.0-dev.621 | 2025-09-30 20:46:27 +0000
* GH-2686: fixes for re-declaring type identifiers in inconsistent ways - addresses GH-2686 (Vern Paxson, Corelight)
8.1.0-dev.619 | 2025-09-30 20:45:19 +0000
* Fix for standalone initializations that require BiFs, and streamlining of standalone BiF-tracking (Vern Paxson, Corelight)
8.1.0-dev.617 | 2025-09-30 20:12:14 +0000
* fixed bug in logic for including/excluding files for script optimization (Vern Paxson, Corelight)
8.1.0-dev.615 | 2025-09-30 19:12:05 +0000
* Remove checks for OpenSSL 1.x versions (Tim Wojtulewicz, Corelight)
* Remove some additional LibreSSL checks (Tim Wojtulewicz, Corelight)
8.1.0-dev.612 | 2025-09-29 18:04:24 +0200
* Supervisor: Make last_signal atomic to squelch data race (Arne Welzel, Corelight)
When the stem process terminates and SIGCHLD is sent to the supervisor,
the signal might be handled by the main thread or any other threads that
aren't blocking SIGCHLD explicitly. Convert last_signal to a std::atomic<int>
such that non-main threads can safely set last_signal without triggering
data race as reported by TSAN. This doesn't make it less racy to work
last_signal, but it appears we only use it for debug printing anyhow and
another option might have been to just remove last_signal altogether.
Follow-up for #4849
8.1.0-dev.610 | 2025-09-29 08:21:01 -0700
* Update docs submodule [nomail] (Tim Wojtulewicz, Corelight)
8.1.0-dev.609 | 2025-09-29 13:08:15 +0200
* cluster/zeromq: Fix Cluster::subscribe() block if not initialized (Arne Welzel, Corelight)
If Cluster::init() hasn't been invoked yet, Cluster::subscribe() with the
ZeroMQ backend would block because the main_inproc socket didn't
yet have a connection from the child thread. Prevent this by connecting
the main and child socket pair at construction time.
This will queue the subscriptions and start processing them once the
child thread has started.
8.1.0-dev.607 | 2025-09-26 14:19:40 -0700
* Fixes for -O gen-standalone-C++ for tracking BiFs, lambdas, attribute types, and independent globals (Vern Paxson, Corelight)
8.1.0-dev.605 | 2025-09-26 11:19:17 -0700
* OpaqueVal, OCSP, X509: drop outdated LibreSSL guards to fix OpenBSD (Klemens Nanni)
build
Whatever is used with recent OpenSSL is also available with latest LibreSSL
on OpenBSD 7.8-beta as of today.
Some of these hunks have been in the net/bro port for years, others I
recently added whilst gradually updating from 6.0.5 to 8.0.1.
8.1.0-dev.603 | 2025-09-26 02:56:58 +0000
* Ignore src/3rdparty for pre-commit (Tim Wojtulewicz, Corelight)
* Merge src/3rdparty repo into the main Zeek repo (Tim Wojtulewicz, Corelight)
* cluster/zeromq: Improve EINTR handling (Arne Welzel, Corelight)
When using ZeroMQ also within the Supervisor process, zmq::poll() and
recv() were observed to return EINTR, handle these.
8.1.0-dev.572 | 2025-09-25 13:52:46 +0200
* cluster/zeromq: Improve EINTR handling (Arne Welzel, Corelight)
When using ZeroMQ also within the Supervisor process, zmq::poll() and
recv() were observed to return EINTR, handle these.
8.1.0-dev.570 | 2025-09-23 09:05:53 -0700
* BTests & baselines for testing selective skipping of script optimization (Vern Paxson, Corelight)
* added &no_ZAM_opt/&no_CPP_opt attributes and --no-opt-files/--no-opt-funcs for controlling skipping script optimization (Vern Paxson, Corelight)
8.1.0-dev.567 | 2025-09-23 13:07:24 +0200
* GH-4842: utils/decompose_uri: Support URIs containing IPv6 addresses (Arne Welzel, Corelight)
An URI containing a bracketed or non-bracketed IPv6 address of the form
http://[::1]:42 was previously split on the first colon for port extraction,
causing a subsequent to_count() call to fail. Harden this to check for a
digits in the last :[0-9]+ component.
Fixes #4842
8.1.0-dev.565 | 2025-09-22 07:45:57 -0700
* Restore the SetType constructor and destructor (Tim Wojtulewicz, Corelight)
8.1.0-dev.563 | 2025-09-22 07:33:42 -0700
* Bump libkqueue to latest upstream master (Tim Wojtulewicz, Corelight)
* Fix clang-tidy finding in recent script_opt changes (Tim Wojtulewicz, Corelight)
8.1.0-dev.559 | 2025-09-17 14:28:32 -0700
* tracking of event groups for compilation to standalone-C++ (Vern Paxson, Corelight)
* Deprecate SetType, as it can be replaced by TableType (Vern Paxson, Corelight)
8.1.0-dev.555 | 2025-09-17 08:44:43 -0700
* Avoid starting up storage expiration thread with zero backends (Tim Wojtulewicz, Corelight)
* Remove a couple of obsolete TODOs in storage manager (Tim Wojtulewicz, Corelight)
8.1.0-dev.552 | 2025-09-16 13:31:39 -0700
* Reword comment about when ZeroMQ is required for the build (Tim Wojtulewicz, Corelight)
* CI: Add label for enabling the Windows build in PRs (Tim Wojtulewicz)
* Enable building ZeroMQ support on Windows (Tim Wojtulewicz)
8.1.0-dev.548 | 2025-09-16 12:41:52 -0700
* Force SQLite to be in thread-safe mode during CMake (Tim Wojtulewicz, Corelight)
This allows us to remove the need to check for thread-safe mode in the
various SQLite plugins. See https://www.sqlite.org/compile.html#threadsafe
for why `1` is a good choice here.
8.1.0-dev.546 | 2025-09-16 11:31:04 -0700
* full tracking of the characteristics of globals when compiling scripts to C++ (Vern Paxson, Corelight)
8.1.0-dev.544 | 2025-09-16 11:02:35 -0700
* fix for associating attributes with globals for -O gen-standalone-C++ (Vern Paxson, Corelight)
8.1.0-dev.542 | 2025-09-16 10:53:04 -0700
* fix for tracking identifiers and aggregates when compiling to standalone-C++ (Vern Paxson, Corelight)
8.1.0-dev.540 | 2025-09-16 10:52:44 -0700
* fix for '?' operator precedence when compiling scripts to C++ (Vern Paxson, Corelight)
8.1.0-dev.538 | 2025-09-12 09:24:51 -0700
* for -O gen-standalone-C++, make the presence of uncompilable functions fatal unless -O allow-cond is used (Vern Paxson, Corelight)
8.1.0-dev.536 | 2025-09-12 09:24:12 -0700
* Bump zeekctl for new trace-summary/pysubnettree versions (Tim Wojtulewicz, Corelight)
8.1.0-dev.534 | 2025-09-11 10:57:17 -0700
* Clean up initialization of DNS_Interpreter (Tim Wojtulewicz, Corelight)
* Switch types used in DNS analyzer to be more consistent (Tim Wojtulewicz, Corelight)
8.1.0-dev.531 | 2025-09-08 11:19:36 -0700
* btest/core/suspend_processing: Add WebSocket example (Arne Welzel, Corelight)
Add a test/example forwarding all new_connection() events produced during
`zeek -r wikipedia.trace` as my_new_connection() to a WebSocket client.
This is mostly to demonstrate and verify usage of suspend_processing(),
websocket_client_added(), resume_processing(), Pcap::file_done(),
websocket_client_lost() and terminate() together.
8.1.0-dev.529 | 2025-09-08 11:02:39 -0700
* Bump Spicy for Coverity fixes (Evan Typanski, Corelight)
8.1.0-dev.527 | 2025-09-08 11:02:05 -0700
* Update src/3rdparty submodule for doctest v2.4.12 and include fix (Tim Wojtulewicz, Corelight)
8.1.0-dev.525 | 2025-09-06 04:26:32 +0000
* CI: Fix warning about ENV usage in CI dockerfiles (Tim Wojtulewicz, Corelight)
This also bumps the dates on the DOCKERFILE_VERSION values
* CI: Add centos stream 10 build (Tim Wojtulewicz, Corelight)
8.1.0-dev.522 | 2025-09-05 19:52:31 -0700
* Bump zeek-client to pull in more resilient controller I/O (Christian Kreibich, Corelight)
8.1.0-dev.520 | 2025-09-05 12:56:24 -0700
* Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight)
8.1.0-dev.518 | 2025-09-04 16:21:52 -0700
* libkqueue: Switch to using HEAD from upstream master (Tim Wojtulewicz, Corelight)
The upstream recently merge Christian's fixes for the fd_map allocations
so that patch doesn't need to be in our fork anymore. I also tested removing
the patch about timers from our fork, and it seems to only matter for Linux
kernels earlier than 5.3. All of our supported platforms are newer than
that.
8.1.0-dev.516 | 2025-09-04 09:04:27 -0700
* Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight)
* Fix clang-tidy warning from recent SVCB merge (Tim Wojtulewicz, Corelight)
* NEWS: Add note about DNS SVCB changes (Tim Wojtulewicz, Corelight)
8.1.0-dev.511 | 2025-09-03 15:35:49 -0700
* Parse SVCB/HTTPS SvcParams list (Klemens Nanni)
Add full support for RFC 9460's SvcParams list.
Amend the existing `dns_svcb_rr` record by a vector of new
`dns_svcb_param` records containing aptly typed SvcParamKey and
SvcParamValue pairs. Example output:
```
@load base/protocols/dns
event dns_HTTPS( c: connection , msg: dns_msg , ans: dns_answer , https: dns_svcb_rr ) {
for (_, param in https$svc_params)
print to_json(param); # filter uninitialised values
}
```
```
$ dig https cloudflare-ech.com +short | tr [:space:] \\n
1
.
alpn="h3,h2"
ipv4hint=104.18.10.118,104.18.11.118
ech=AEX+DQBBHgAgACBGL2e9TiFwjK/w1Zg9AmRm7mgXHz3PjffP0mTFNMxmDQAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA=
ipv6hint=2606:4700::6812:a76,2606:4700::6812:b76
```
```
{"key":1,"alpn":["h3","h2"]}
{"key":4,"hint":["104.18.10.118","104.18.11.118"]}
{"key":5,"ech":"AEX+DQBBHgAgACBGL2e9TiFwjK/w1Zg9AmRm7mgXHz3PjffP0mTFNMxmDQAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA="}
{"key":6,"hint":["2606:4700::6812:a76","2606:4700::6812:b76"]}
```
Values with malformed data or belonging to invalid/reserved keys
are passed raw bytes in network order for script-level inspection.
Follow up to "Initial Support to DNS SVCB/HTTPS RR"
https://github.com/zeek/zeek/pull/1808
* Clang-tidy fixes for recent IDPtr changes (Tim Wojtulewicz, Corelight)
8.1.0-dev.508 | 2025-09-03 15:02:41 -0700
* fixup! fixup! shift much of the internal use of ID* identifier pointers over to IDPtr objects (Vern Paxson, Corelight)
* fixup! shift much of the internal use of ID* identifier pointers over to IDPtr objects (Vern Paxson, Corelight)
* fixup! shift much of the internal use of ID* identifier pointers over to IDPtr objects (Vern Paxson, Corelight)
* fixup! shift much of the internal use of ID* identifier pointers over to IDPtr objects (Vern Paxson, Corelight)
* annotate a number of BTests as unsuited for -O gen-C++ testing due to multiple Zeek runs (Vern Paxson, Corelight)
* BTest baseline updates for -O gen-C++ - all minor tweaks (Vern Paxson, Corelight)
* BTest updates for script optimization tracking of BiFs (Vern Paxson, Corelight)
* regression test for former ASAN issue with script optimization of lambdas (Vern Paxson, Corelight)
* shift much of the internal use of ID* identifier pointers over to IDPtr objects (Vern Paxson, Corelight)
* maintenance update for script optimization's knowledge of BiFs (Vern Paxson, Corelight)
* logger fix for interoperability with -O gen-C++ code (Vern Paxson, Corelight)
8.1.0-dev.496 | 2025-09-03 16:17:23 -0400
* tightened up parsing of $field=X record constructor expressions (Vern Paxson, Corelight)
8.1.0-dev.494 | 2025-09-03 14:50:12 +0200
* Remove unnecessary peer signature from test `scripts.base.protocols.bittorrent.tracker` (Benjamin Bannier, Corelight)
8.1.0-dev.492 | 2025-09-02 16:00:17 -0700
* Remove some unnecessary #includes from binpac source files (Tim Wojtulewicz, Corelight)
8.1.0-dev.490 | 2025-09-02 11:47:44 -0700
* Fix a few more random clang-tidy findings (Tim Wojtulewicz, Corelight)
* Use std::numbers::pi instead of hard-coded value (Tim Wojtulewicz, Corelight)
* Use std::scoped_lock instead of std::lock_guard (Tim Wojtulewicz, Corelight)
* Use .contains() instead of .find() or .count() (Tim Wojtulewicz, Corelight)
8.1.0-dev.484 | 2025-08-29 21:53:19 -0700
* Bump zeek-testing-cluster to pull in WebSocket TLS updates (Christian Kreibich, Corelight)
* Bump zeek-client to pull in TLS config updates (Christian Kreibich, Corelight)
* Management framework: add TLS options for controller's websocket server (Arne Welzel, Corelight)
8.1.0-dev.480 | 2025-08-29 15:08:29 -0700
* Move benchmarking to Ubnutu 24 task, add to normal PR builds (Tim Wojtulewicz, Corelight)
We already have a "regular Linux" build for PRs, but I'm adding this one
in so that we have benchmark coverage on PRs as well.
* Reorder ubuntu builds so 22.04 comes last (Tim Wojtulewicz, Corelight)
* Rename Ubuntu-based tasks to have the full version name (Tim Wojtulewicz, Corelight)
* Switch Zeek Spicy builds to Ubuntu 24 (Tim Wojtulewicz, Corelight)
8.1.0-dev.475 | 2025-08-28 15:19:59 -0700
* gen-zam: Move source files up a directory (Tim Wojtulewicz, Corelight)
* bifcl: Fix clang-tidy warnings (Tim Wojtulewicz, Corelight)
* bifcl: Run clang-format on c++ code embedded in builtin-func.{l,y} (Tim Wojtulewicz, Corelight)
* binpac: Fix a large number of clang-tidy warnings (Tim Wojtulewicz, Corelight)
* binpac: Replace delete_list macro uses (Tim Wojtulewicz, Corelight)
* binpac: Run clang-format on c++ code embedded in pac_parse.{ll,yy} (Tim Wojtulewicz, Corelight)
8.1.0-dev.468 | 2025-08-28 13:06:25 -0700
* Link Prometheus symbols via Broker instead of directly (Tim Wojtulewicz, Corelight)
* CI: Restore build steps for ubuntu22 task (Tim Wojtulewicz, Corelight)
This got accidentally deleted during the reorganization of the CI tasks
* Fix ruff check legacy alias for pre-commit (Tim Wojtulewicz, Corelight)
8.1.0-dev.461 | 2025-08-26 14:39:50 -0700
* CI: Rework layout of when each task runs (Tim Wojtulewicz, Corelight)
8.1.0-dev.459 | 2025-08-26 08:59:20 -0700
* Fix installation of symlink with `DESTDIR` (Benjamin Bannier, Corelight)
We install test data which we also make available under an alternative
path for backwards compatibility. The installation of this symlink did
not take `DESTDIR` installs like used by Zeek's packaging into account
which caused installations from packages to behave different from
installs from source.
This patch fixes the symlink to respect a possible `DESTDIR`.
Closes #3266.
8.1.0-dev.456 | 2025-08-25 12:29:32 -0700
* Bump zeekctl (Arne Welzel, Corelight)
8.1.0-dev.454 | 2025-08-22 10:12:35 +0200
* cluster/Backend: Fallback to current network time when current event has not timestamp (Arne Welzel, Corelight)
When a WebSocket client sends an event to Zeek without explicit network
timestamp metadata, Zeek would use -1.0 as a timestamp for any events
published while handling this event. Instead, it seems far more sensible
to use the current network time in that scenario.
* cluster/serializer/broker: Do not send empty metadata vectors around (Arne Welzel, Corelight)
Event when there's no metadata attached to an event, we'd still use the
constructor passing an empty metadata vector, resulting in an on-the-wire
representation with an empty trailing vector.
Particularly visible when just snooping events via websocat. There also
seems to be some bug with the timestamp -1 handling.
8.1.0-dev.451 | 2025-08-21 17:10:05 -0700
* Minor fixes to a few NEWS entries. (Christian Kreibich, Corelight)
8.1.0-dev.449 | 2025-08-21 17:02:51 +0200
* README.md: Add Mastodon and Bluesky links (Arne Welzel, Corelight)
* README: Drop "Follow us on Twitter" (Arne Welzel, Corelight)
* Merge a number of submodules into Zeek (Tim Wojtulewicz, Corelight)
The code from the gen-zam, bifcl, binpac and zeek-af_packet-plugin
submodules has been merged into the Zeek tree.
8.1.0-dev.101 | 2025-08-20 11:38:37 -0400
* Fix Coverity issue with new `Attributes` ctor (Evan Typanski, Corelight)
8.1.0-dev.99 | 2025-08-19 15:08:35 -0700
* CI: Update CentOS 9 to Python 3.13 (Tim Wojtulewicz, Corelight)
8.1.0-dev.97 | 2025-08-19 20:27:13 +0200
* logging/Manager: Also pass non-null vector and set (Arne Welzel, Corelight)
Primarily to align with strings and also to keep the plugin
API the same.
* logging/Manager: Non-null strings for empty strings (Arne Welzel, Corelight)
After #4724, empty strings would result in nullptrs being stored in the
threading::Value's string_val.data field instead of a valid pointer to
an empty strings. This upsets UBSAN's nonnull check for memcpy()
[01:29:45.807] ../../src/SerializationFormat.cc:80:33: runtime error: null pointer passed as argument 2, which is declared to never be null
[01:29:45.807] /usr/include/string.h:44:28: note: nonnull attribute specified here
[01:29:45.807] #0 0x5b2e9c933a3f in zeek::detail::SerializationFormat::WriteData(void const*, unsigned long) /zeek/build/src/../../src/SerializationFormat.cc:80:5
[01:29:45.807] #1 0x5b2e9c935184 in zeek::detail::BinarySerializationFormat::Write(char const*, int, char const*) /zeek/build/src/../../src/SerializationFormat.cc:371:40
Continue to allocate the empty string for now as a fix.
* CI: Ubuntu 24.10 is eol, add Ubuntu 25.04 (Johanna Amann, Corelight)
8.1.0-dev.91 | 2025-08-18 14:59:41 -0700
* Add a missing header for the broker cluster serializer (Tim Wojtulewicz, Corelight)
8.1.0-dev.89 | 2025-08-18 14:46:57 -0700
* Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight)
8.1.0-dev.87 | 2025-08-18 14:39:10 -0400
* Fix parameter attributes pretending to be records (Evan Typanski, Corelight)
Parameters relied on is_record for a couple of validations, but they are
not records and should not be treated as such. This way we can validate
&optional better.
* Only allow `&optional` in records (Evan Typanski, Corelight)
There was some confusing behavior with &optional and locals, so this
should get rid of that by making it an error. However, there is a case
where function parameters are still allowed to have &optional - this is
because there are checks for &default in parameters as well.
8.1.0-dev.83 | 2025-08-18 09:40:41 -0700
* Add `record_type_to_vector` deprecation to NEWS (Evan Typanski, Corelight)
8.1.0-dev.81 | 2025-08-18 16:44:30 +0200
* cluster/serializer/broker: Drop unused include (Arne Welzel, Corelight)
* cluster/serializer/broker: fixup inconsistent param comment (Arne Welzel, Corelight)
References #4754 #4756
8.1.0-dev.78 | 2025-08-18 13:13:21 +0200
* Changed behavior of var-extraction-uri.zeek from policy/protocol/http to extract only the URI parameter names. Do not include the path in the first parameter name. Only extract uri vars if parameters actually exist. (Benjamin Grap)
8.1.0-dev.76 | 2025-08-18 09:40:05 +0200
* Report PostgreSQL login success only after ReadyForQuery (Fupeng Zhao)
Previously, Zeek treated the receipt of `AuthenticationOk` as a
successful login. However, according to the PostgreSQL
Frontend/Backend Protocol, the startup phase is not complete until
the server sends `ReadyForQuery`. It is still possible for the server
to emit an `ErrorResponse` (e.g. ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION)
after `AuthenticationOk` but before `ReadyForQuery`.
This change updates the PostgreSQL analyzer to defer reporting login
success until `ReadyForQuery` is observed. This prevents false
positives in cases where authentication succeeds but session startup
fails.
8.1.0-dev.74 | 2025-08-17 17:28:59 +0200
* maintenance updates for ZAM BiF-tracking (Vern Paxson, Corelight)
* fix line numbers associated with "if" and initialization statements (Vern Paxson, Corelight)
8.1.0-dev.71 | 2025-08-17 16:56:57 +0200
* cluster/serializer/broker: Do not special case Broker::Data anymore (Arne Welzel, Corelight)
The previous approach ignored the fact that nested / inner values might
also be Broker::Data values. I'm not super sure about the validity of
the test, because it's essentially demonstrating any-nesting, but
it's not leading to extra Broker::Data encoding.
* broker/Data: Support unwrapping Broker::Data records (Arne Welzel, Corelight)
Calling val_to_data() on a Broker::Data ends up wrapping the
Broker::Data record instead of using the contained broker::value
directly.
Seems this should be the default behavior and wonder if the flag
even makes sense, but for a 8.0 backport that seems more reasonable.
8.1.0-dev.68 | 2025-08-15 15:20:36 -0700
* Revert "Move BinPAC, bifcl, af_packet, and gen_zam submodules into main zeek repo" (Tim Wojtulewicz)
* Fix some clang-tidy findings in generated BIF code (Tim Wojtulewicz, Corelight)
* Fix clang-tidy and pre-commit warnings for gen-zam code files (Tim Wojtulewicz, Corelight)
* Move gen-zam code into the main Zeek repository (Tim Wojtulewicz, Corelight)
This is based on commit 56a6db00b887c79d26f303676677cb490d1c296d from
the gen-zam repository.
* Move zeek-af_packet-plugin code into the main Zeek repository (Tim Wojtulewicz, Corelight)
This is based on commit b89a6f64123f778090d1dd6ec48e6b8e8906ea11 from
the zeek-af_packet-plugin repository.
* Move the bifcl code into the main Zeek repository (Tim Wojtulewicz, Corelight)
This is based on commit 5947749f7850b075f11d6a2aaefe7dad4f63cb62f from
the bifcl repository.
* Fix clang-tidy findings in the binpac lib code (Tim Wojtulewicz, Corelight)
* Add copyright headers to all of the binpac source files (Tim Wojtulewicz, Corelight)
* Move binpac code into the main Zeek repository (Tim Wojtulewicz, Corelight)
This is based on commit 48f75b5f6415fe9d597e3e991cec635b1bc400dc from
the binpac repository.
8.1.0-dev.56 | 2025-08-13 21:20:50 +0200
* ci: Run zeekctl and builtin tasks with Debian 13, too (Arne Welzel, Corelight)
* ci: Prepend timestamps to output (Arne Welzel, Corelight)
* ci: Enable Spicy for arm_debian13 (Arne Welzel, Corelight)
* ci: Add Debian 13.0 (trixie) (Arne Welzel, Corelight)
* docker: Bump to debian:trixie-slim (Arne Welzel, Corelight)
8.1.0-dev.50 | 2025-08-12 17:42:46 -0700
* Add NEWS entry for field length limiting (Tim Wojtulewicz, Corelight)
* Tag truncated values with a flag, plus pack threading::Value better (Tim Wojtulewicz, Corelight)
* Remove length limiting on string fields for HTTP (Tim Wojtulewicz, Corelight)
* Make total_size counter a member in logging::Manager (Tim Wojtulewicz, Corelight)
* Remove using numeric_limits and just check for zero instead (Tim Wojtulewicz, Corelight)
* Expand the size of the log-size filters for x509 (Tim Wojtulewicz, Corelight)
* Add options to filter at the stream level as well as globally (Tim Wojtulewicz, Corelight)
* Add a weird that gets emitted when strings/containers are over the limits (Tim Wojtulewicz, Corelight)
* Add metrics to track string and container fields limited by length (Tim Wojtulewicz, Corelight)
* Replace unused stream argument from RecordToLogRecord with WriterInfo (Tim Wojtulewicz, Corelight)
This also adds a WriterInfo argument to ValToLogVal and passes the one from
RecordToLogRecord into it.
* Implement string- and container-length filtering at the log record level (Tim Wojtulewicz, Corelight)
8.1.0-dev.38 | 2025-08-12 12:38:24 -0700
* Bump pre-commit hooks (Benjamin Bannier, Corelight)
* Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight)
8.1.0-dev.35 | 2025-08-12 11:01:12 -0700
* Pass DNS complete_flag along as a uint8_t instead of a String (Tim Wojtulewicz, Corelight)
* Update docs submodule with 8.1 deprecation removals (Tim Wojtulewicz, Corelight)
* Update zeekjs submodule with 8.1 deprecation fixes (Tim Wojtulewicz, Corelight)
* Remove deprecations tagged for v8.1 (Tim Wojtulewicz, Corelight)
8.1.0-dev.29 | 2025-08-11 11:37:22 -0700
* smb2/read: Parse only 1 byte for data_offset, ignore reserved1 (Arne Welzel, Corelight)
A user provided a SMB2 pcap with the reserved1 field of a ReadResponse
set to 1 instead of 0. This confused the padding computation due to
including this byte into the offset. Properly split data_offset and
reserved1 into individual byte fields.
Closes #4730
8.1.0-dev.27 | 2025-08-10 21:28:33 -0700
* GH-4176: cluster: Add on_subscribe() and on_unsubscribe() hooks (Arne Welzel, Corelight)
Closes #4176
8.1.0-dev.24 | 2025-08-08 14:23:51 +0200
* GH-4176: cluster: Add on_subscribe() and on_unsubscribe() hooks (Arne Welzel, Corelight)
8.1.0-dev.22 | 2025-08-07 08:39:27 -0700
* Update zeek-aux to remove BRO_DIST from plugin skeleton (Tim Wojtulewicz, Corelight)
* cmake_minimum_required() should come before project() (Tim Wojtulewicz, Corelight)
8.1.0-dev.19 | 2025-08-07 10:48:40 +0200
* btest/tap-analyzer: Update existing test and add new one for UpdateConnVal() (Arne Welzel, Corelight)
This also changes the output of connection UIDs from the tap analyzer to be
prefixed with C for easier correlation with other logs.
* SessionAdapter: Keep tap_analyzers until destruction (Arne Welzel, Corelight)
connection_state_remove() is invoked after Done(), so it's not a good
idea to remove the tap analyzers before in case they have up-to-date
information for the connection val.
* tcp,udp,icmp adapters: Move TapPacket() to earlier (Arne Welzel, Corelight)
Writing a test, the packet was tapped after protocol analysis at least
for TCP. Ensure tapping happens before. The adapter->Process() moving
after pkt->session made me a bit wondering if things are underspecified
here, but seems reasonable to set the session on pkt before adapter->Process().
* tcp,udp,icmp adapters: Fix UpdateConnVal() superclass call (Arne Welzel, Corelight)
Now that SessionAdapter implements UpdateConnVal(), the individual
adapters need to call that instead of Analyzer::UpdateConnVal()
Thanks clang-tidy.
8.1.0-dev.14 | 2025-08-06 14:37:50 +0100
* Add proto to analyzer.log (Johanna Amann, Corelight)
The analyzer.log file was missing the protocol field to distinguish
tcp/udp connections.
8.1.0-dev.12 | 2025-08-06 09:10:08 -0400
* GH-4722: Fix record coercion with compatible types (Evan Typanski, Corelight)
Fixes #4722
8.1.0-dev.10 | 2025-08-06 14:27:32 +0200
* TapAnalyzer: Fix docstring (Arne Welzel, Corelight)
Relates to #4337 #4725 #4734
* btest/plugins/tap-analyzer: Update baseline (Arne Welzel, Corelight)
Relates to #4337 #4725 #4734
8.1.0-dev.7 | 2025-08-05 20:00:19 +0200
* TapAnalyzer: More verdict to action rename (Arne Welzel, Corelight)
Relates to #4725 #4337
8.1.0-dev.5 | 2025-08-05 19:48:50 +0200
* IPBasedAnalyzer: Call TapPacket() when skipping (Arne Welzel, Corelight)
When skip_further_processing() is called, a TapAnalyzer should still see
the packets as skipped with SkipReason "skipping".
* SessionAdapter: Introduce TapAnalyzer for session adapter (Arne Welzel, Corelight)
This commit introduces a mechanism to attach light weight analyzers to
the root analyzer of sessions in order to tap into the packets delivered
to child analyzer.
8.1.0-dev.2 | 2025-08-04 09:35:41 -0700
* Compile contributors for Zeek 8.0 in the NEWS file (Christian Kreibich, Corelight) * Compile contributors for Zeek 8.0 in the NEWS file (Christian Kreibich, Corelight)
* Start of 8.1.0 development (Tim Wojtulewicz, Corelight) (cherry picked from commit 4fdd83f3f50a0e4631cb8e08ac931cc37f4637a3)
8.0.0-dev.827 | 2025-08-01 17:10:13 +0200 8.0.0-dev.827 | 2025-08-01 17:10:13 +0200

View file

@ -396,14 +396,14 @@ endfunction ()
add_zeek_dynamic_plugin_build_interface_include_directories( add_zeek_dynamic_plugin_build_interface_include_directories(
${PROJECT_SOURCE_DIR}/src/include ${PROJECT_SOURCE_DIR}/src/include
${PROJECT_SOURCE_DIR}/tools/binpac/lib ${PROJECT_SOURCE_DIR}/auxil/binpac/lib
${PROJECT_SOURCE_DIR}/auxil/broker/libbroker ${PROJECT_SOURCE_DIR}/auxil/broker/libbroker
${PROJECT_SOURCE_DIR}/auxil/paraglob/include ${PROJECT_SOURCE_DIR}/auxil/paraglob/include
${PROJECT_SOURCE_DIR}/auxil/prometheus-cpp/core/include ${PROJECT_SOURCE_DIR}/auxil/prometheus-cpp/core/include
${PROJECT_SOURCE_DIR}/auxil/expected-lite/include ${PROJECT_SOURCE_DIR}/auxil/expected-lite/include
${CMAKE_BINARY_DIR}/src ${CMAKE_BINARY_DIR}/src
${CMAKE_BINARY_DIR}/src/include ${CMAKE_BINARY_DIR}/src/include
${CMAKE_BINARY_DIR}/tools/binpac/lib ${CMAKE_BINARY_DIR}/auxil/binpac/lib
${CMAKE_BINARY_DIR}/auxil/broker/libbroker ${CMAKE_BINARY_DIR}/auxil/broker/libbroker
${CMAKE_BINARY_DIR}/auxil/prometheus-cpp/core/include) ${CMAKE_BINARY_DIR}/auxil/prometheus-cpp/core/include)
@ -892,26 +892,28 @@ if (BUILD_STATIC_BINPAC)
set(ENABLE_STATIC_ONLY true) set(ENABLE_STATIC_ONLY true)
endif () endif ()
add_subdirectory(tools/binpac) add_subdirectory(auxil/binpac)
set(ENABLE_STATIC_ONLY ${ENABLE_STATIC_ONLY_SAVED}) set(ENABLE_STATIC_ONLY ${ENABLE_STATIC_ONLY_SAVED})
# FIXME: avoid hard-coding a path for multi-config generator support. See the # FIXME: avoid hard-coding a path for multi-config generator support. See the
# TODO in ZeekPluginConfig.cmake.in. # TODO in ZeekPluginConfig.cmake.in.
set(BINPAC_EXE_PATH "${CMAKE_BINARY_DIR}/tools/binpac/src/binpac${CMAKE_EXECUTABLE_SUFFIX}") set(BINPAC_EXE_PATH "${CMAKE_BINARY_DIR}/auxil/binpac/src/binpac${CMAKE_EXECUTABLE_SUFFIX}")
set(_binpac_exe_path "included") set(_binpac_exe_path "included")
# Need to call find_package so it sets up the include paths used by plugin builds. # Need to call find_package so it sets up the include paths used by plugin builds.
find_package(BinPAC REQUIRED) find_package(BinPAC REQUIRED)
add_executable(Zeek::BinPAC ALIAS binpac) add_executable(Zeek::BinPAC ALIAS binpac)
add_subdirectory(tools/bifcl) add_subdirectory(auxil/bifcl)
add_executable(Zeek::BifCl ALIAS bifcl) add_executable(Zeek::BifCl ALIAS bifcl)
# FIXME: avoid hard-coding a path for multi-config generator support. See the # FIXME: avoid hard-coding a path for multi-config generator support. See the
# TODO in ZeekPluginConfig.cmake.in. # TODO in ZeekPluginConfig.cmake.in.
set(BIFCL_EXE_PATH "${CMAKE_BINARY_DIR}/tools/bifcl/bifcl${CMAKE_EXECUTABLE_SUFFIX}") set(BIFCL_EXE_PATH "${CMAKE_BINARY_DIR}/auxil/bifcl/bifcl${CMAKE_EXECUTABLE_SUFFIX}")
set(_bifcl_exe_path "included") set(_bifcl_exe_path "included")
add_subdirectory(tools/gen-zam) if (NOT GEN_ZAM_EXE_PATH)
add_subdirectory(auxil/gen-zam)
endif ()
if (ENABLE_JEMALLOC) if (ENABLE_JEMALLOC)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
@ -1187,6 +1189,18 @@ endif ()
# Tell the plugin code that we're building as part of the main tree. # Tell the plugin code that we're building as part of the main tree.
set(ZEEK_PLUGIN_INTERNAL_BUILD true CACHE INTERNAL "" FORCE) set(ZEEK_PLUGIN_INTERNAL_BUILD true CACHE INTERNAL "" FORCE)
set(ZEEK_HAVE_AF_PACKET no)
if (${CMAKE_SYSTEM_NAME} MATCHES Linux)
if (NOT DISABLE_AF_PACKET)
if (NOT AF_PACKET_PLUGIN_PATH)
set(AF_PACKET_PLUGIN_PATH ${CMAKE_SOURCE_DIR}/auxil/zeek-af_packet-plugin)
endif ()
list(APPEND ZEEK_INCLUDE_PLUGINS ${AF_PACKET_PLUGIN_PATH})
set(ZEEK_HAVE_AF_PACKET yes)
endif ()
endif ()
set(ZEEK_HAVE_JAVASCRIPT no) set(ZEEK_HAVE_JAVASCRIPT no)
if (NOT DISABLE_JAVASCRIPT) if (NOT DISABLE_JAVASCRIPT)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/auxil/zeekjs/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/auxil/zeekjs/cmake)
@ -1206,7 +1220,6 @@ if (NOT DISABLE_JAVASCRIPT)
endif () endif ()
endif () endif ()
set(ZEEK_HAVE_AF_PACKET no CACHE INTERNAL "Zeek has AF_PACKET support")
set(ZEEK_HAVE_JAVASCRIPT ${ZEEK_HAVE_JAVASCRIPT} CACHE INTERNAL "Zeek has JavaScript support") set(ZEEK_HAVE_JAVASCRIPT ${ZEEK_HAVE_JAVASCRIPT} CACHE INTERNAL "Zeek has JavaScript support")
set(DEFAULT_ZEEKPATH_PATHS set(DEFAULT_ZEEKPATH_PATHS
@ -1545,8 +1558,11 @@ message("")
output_summary_bool("AF_PACKET" ${ZEEK_HAVE_AF_PACKET}) output_summary_bool("AF_PACKET" ${ZEEK_HAVE_AF_PACKET})
output_summary_bool("Aux. Tools" ${INSTALL_AUX_TOOLS}) output_summary_bool("Aux. Tools" ${INSTALL_AUX_TOOLS})
output_summary_line("BifCL" ${_bifcl_exe_path})
output_summary_line("BinPAC" ${_binpac_exe_path})
output_summary_bool("BTest" ${INSTALL_BTEST}) output_summary_bool("BTest" ${INSTALL_BTEST})
output_summary_line("BTest tooling" ${_install_btest_tools_msg}) output_summary_line("BTest tooling" ${_install_btest_tools_msg})
output_summary_line("Gen-ZAM" ${_gen_zam_exe_path})
output_summary_bool("JavaScript" ${ZEEK_HAVE_JAVASCRIPT}) output_summary_bool("JavaScript" ${ZEEK_HAVE_JAVASCRIPT})
output_summary_line("Spicy" ${_spicy}) output_summary_line("Spicy" ${_spicy})
output_summary_bool("Spicy analyzers" ${USE_SPICY_ANALYZERS}) output_summary_bool("Spicy analyzers" ${USE_SPICY_ANALYZERS})

88
NEWS
View file

@ -3,83 +3,6 @@ This document summarizes the most important changes in the current Zeek
release. For an exhaustive list of changes, see the ``CHANGES`` file release. For an exhaustive list of changes, see the ``CHANGES`` file
(note that submodules, such as Broker, come with their own ``CHANGES``.) (note that submodules, such as Broker, come with their own ``CHANGES``.)
Zeek 8.1.0
==========
We would like to thank @chrisjlly, Klemens Nanni (@klemensn), and Klemens Nanni
(@klemens-ya) for their contributions to this release.
Breaking Changes
----------------
- Python 3.10 is now required for Zeek and all of its associated subprojects.
- The ``&optional`` script attribute will now error when applied to anything that's
not a record field. Previously, this would have surprising behavior.
- The BinPAC, Bifcl, and Gen-ZAM tools have all moved directly into the Zeek repo, which
should ease maintenance on them a bit. They were moved from the ``auxil`` directory to the
tools directory. Along with this, the ``--gen-zam`` argument for ``configure`` was
removed and the internal version will always be used.
- The zeek-af_packet-plugin git submodule was moved directly into the Zeek repo. This used
to live in the ``auxil`` directory, after having moved there from an external plugin.
It is now built as part of main Zeek build whenever building on Linux.
New Functionality
-----------------
- A new TapAnalyzer class was added allowing to tap into all packets delivered
to child analyzers attached to session adapters.
- Two new hooks, ``Cluster::on_subscribe()`` and ``Cluster::on_unsubscribe()`` have
been added to allow observing ``Subscribe()`` and ``Unsubscribe()`` calls on
backends by Zeek scripts.
- The ability to control the length of strings and containers in log output was added. The
maximum length of individual log fields can be set, as well as the total length of all
string or container fields in a single log record. This feature is controlled via four
new script-level variables:
Log::default_max_field_string_bytes
Log::default_max_total_string_bytes
Log::default_max_field_container_elements
Log::default_max_total_container_elements
When one of the ``field`` limits is reached, the individual field is truncated. When one
of the ``total`` limits is reached, all further strings will returned as empty and all
further container elements will not be output. See the documentation for those variables
for more detail.
The above variables control the truncation globally, but they can also be set for log
streams individually. This is controlled by variables with the same names that can be
set when the log stream is created.
Two new weirds were added to report the truncation: ``log_string_field_truncated`` and
``log_container_field_truncated``. New metrics were added to track how many truncations
have occurred: ``zeek_log_writer_truncated_string_fields_total`` and
``zeek_log_writer_truncated_containers_total``. The metrics are reported for each log
stream.
- The DNS analyzer now returns the set of parameters for SVCB data. It previously handled
SVCB packets, but omitted the parameters while parsing.
Changed Functionality
---------------------
- The var-extraction-uri.zeek policy does not include the path in the ``uri_vars``
field anymore.
- The ``get_current_packet_header()`` now populates the returned record also for
fragmented IP datagrams.
Removed Functionality
---------------------
Deprecated Functionality
------------------------
Zeek 8.0.0 Zeek 8.0.0
========== ==========
@ -365,7 +288,7 @@ New Functionality
- Zeek now supports extracting the PPPoE session ID. The ``PacketAnalyzer::PPPoE::session_id`` - Zeek now supports extracting the PPPoE session ID. The ``PacketAnalyzer::PPPoE::session_id``
BiF can be used to get the session ID of the current packet. BiF can be used to get the session ID of the current packet.
The ``conn/pppoe-session-id-logging.zeek`` policy script adds pppoe session IDs to the The ``onn/pppoe-session-id-logging.zeek`` policy script adds pppoe session IDs to the
connection log. connection log.
The ``get_conn_stats()`` function's return value now includes the number of packets The ``get_conn_stats()`` function's return value now includes the number of packets
@ -435,7 +358,7 @@ Changed Functionality
times in X509 certificates as local times. times in X509 certificates as local times.
- The PPPoE parser now respects the size value given in the PPPoE header. Data - The PPPoE parser now respects the size value given in the PPPoE header. Data
beyond the size given in the header will be truncated. beyon the size given in the header will be truncated.
- Record fields with ``&default`` attributes initializing empty ``vector``, ``table`` - Record fields with ``&default`` attributes initializing empty ``vector``, ``table``
or ``set`` instances are now deferred until they are accessed, potentially or ``set`` instances are now deferred until they are accessed, potentially
@ -502,9 +425,6 @@ Deprecated Functionality
``std::string`` and ``std::string_view`` added ``begins_with`` and ``ends_with`` methods ``std::string`` and ``std::string_view`` added ``begins_with`` and ``ends_with`` methods
in C++ 20, and those should be used instead. in C++ 20, and those should be used instead.
- The ``record_type_to_vector`` BIF is deprecated in favor of using the newly ordered
``record_fields`` BIF.
Zeek 7.2.0 Zeek 7.2.0
========== ==========
@ -827,7 +747,7 @@ New Functionality
some updates to Zeek's internal DNS resolver due to changes in the c-ares some updates to Zeek's internal DNS resolver due to changes in the c-ares
API. At least version v1.28.0 is now required to build Zeek. API. At least version v1.28.0 is now required to build Zeek.
- Python 3.9 is now required for Zeek and all of its associated subprojects. - Python 3.9 is now required for Zeek and all of it's associated subprojects.
- IP-based connections that were previously not logged due to using an unknown - IP-based connections that were previously not logged due to using an unknown
IP protocol (e.g. not TCP, UDP, or ICMP) now appear in conn.log. All conn.log IP protocol (e.g. not TCP, UDP, or ICMP) now appear in conn.log. All conn.log
@ -918,7 +838,7 @@ New Functionality
analyzer used for processing the packet when the event is raised. The analyzer used for processing the packet when the event is raised. The
``unknown_protocol.log`` file was extended to include this information. ``unknown_protocol.log`` file was extended to include this information.
- The MySQL analyzer now generates a ``mysql_change_user()`` event when the user - The MySQL analyzer now generates a ``mysql_user_change()`` event when the user
changes mid-session via the ``COM_USER_CHANGE`` command. changes mid-session via the ``COM_USER_CHANGE`` command.
- The DNS analyzer was extended to support TKEY RRs (RFC 2390). A corresponding - The DNS analyzer was extended to support TKEY RRs (RFC 2390). A corresponding

2
README
View file

@ -3,7 +3,7 @@ The Zeek Network Security Monitor
================================= =================================
Zeek is a powerful framework for network traffic analysis and security Zeek is a powerful framework for network traffic analysis and security
monitoring. monitoring. Follow us on Twitter at @zeekurity.
Key Features Key Features
============ ============

View file

@ -15,15 +15,14 @@ traffic analysis and security monitoring.
[_Development_](#development) — [_Development_](#development) —
[_License_](#license) [_License_](#license)
Follow us on Twitter at [@zeekurity](https://twitter.com/zeekurity).
[![Coverage Status](https://coveralls.io/repos/github/zeek/zeek/badge.svg?branch=master)](https://coveralls.io/github/zeek/zeek?branch=master) [![Coverage Status](https://coveralls.io/repos/github/zeek/zeek/badge.svg?branch=master)](https://coveralls.io/github/zeek/zeek?branch=master)
[![Build Status](https://img.shields.io/cirrus/github/zeek/zeek)](https://cirrus-ci.com/github/zeek/zeek) [![Build Status](https://img.shields.io/cirrus/github/zeek/zeek)](https://cirrus-ci.com/github/zeek/zeek)
[![Slack](https://img.shields.io/badge/slack-@zeek-brightgreen.svg?logo=slack)](https://zeek.org/slack) [![Slack](https://img.shields.io/badge/slack-@zeek-brightgreen.svg?logo=slack)](https://zeek.org/slack)
[![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fcommunity.zeek.org)](https://community.zeek.org) [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fcommunity.zeek.org)](https://community.zeek.org)
[![Mastodon](https://img.shields.io/badge/mastodon-@zeek@infosec.exchange-brightgreen.svg?logo=mastodon)](https://infosec.exchange/@zeek)
[![Bluesky](https://img.shields.io/badge/bluesky-@zeek-brightgreen.svg?logo=bluesky)](https://bsky.app/profile/zeek.org)
</h4> </h4>

View file

@ -1 +1 @@
8.1.0-dev.626 8.0.0-rc1

1
auxil/bifcl Submodule

@ -0,0 +1 @@
Subproject commit 5947749f7850b075f11d6a2aaefe7dad4f63cb62

1
auxil/binpac Submodule

@ -0,0 +1 @@
Subproject commit 48f75b5f6415fe9d597e3e991cec635b1bc400dc

1
auxil/gen-zam Submodule

@ -0,0 +1 @@
Subproject commit 56a6db00b887c79d26f303676677cb490d1c296d

@ -1 +1 @@
Subproject commit ea30540c77679ced3ce7886199384e8743628921 Subproject commit af5612bb0db00831b82e706d63176094243c8ad7

@ -1 +1 @@
Subproject commit 7635e113080be6fc20cb308636c8c38565c95c8a Subproject commit 140e88c9a8e04eca801bbd891e085cc180eee43f

@ -0,0 +1 @@
Subproject commit b89a6f64123f778090d1dd6ec48e6b8e8906ea11

@ -1 +1 @@
Subproject commit 9a51ce1940a808aaad253077905c2b34f15f1e08 Subproject commit 6c72725b184cc5fd7d12cea5084f0f51de3e82e3

@ -1 +1 @@
Subproject commit 16849ca3ec2f8637e3f8ef8ee27e2c279724387f Subproject commit 4440c7a05ba4be229ac88d70e8f4eef2465afc50

@ -1 +1 @@
Subproject commit 485abcad45daeea6d09680e5fc7d29e97d2e3fbe Subproject commit 93459b37c3deab4bec9e886211672024fa3e4759

@ -1 +1 @@
Subproject commit e5985abfffc1ef5ead3a0bab196fa5d86bc5276f Subproject commit df112dc70ad7c2b854e4aeaad0742cdfa3927945

View file

@ -2,7 +2,7 @@ FROM alpine:latest
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250306
RUN apk add --no-cache \ RUN apk add --no-cache \
bash \ bash \

View file

@ -1,49 +0,0 @@
FROM quay.io/centos/centos:stream10
# A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905
# dnf config-manager isn't available at first, and
# we need it to install the CRB repo below.
RUN dnf -y install 'dnf-command(config-manager)'
# What used to be powertools is now called "CRB".
# We need it for some of the packages installed below.
# https://docs.fedoraproject.org/en-US/epel/
RUN dnf config-manager --set-enabled crb
RUN dnf -y install \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
# The --nobest flag is hopefully temporary. Without it we currently hit
# package versioning conflicts around OpenSSL.
RUN dnf -y --nobest install \
bison \
ccache \
cmake \
cppzmq-devel \
diffutils \
flex \
gcc \
gcc-c++ \
git \
jq \
libpcap-devel \
make \
openssl \
openssl-devel \
procps-ng \
python3 \
python3-devel \
python3-pip\
sqlite \
swig \
tar \
which \
zlib-devel \
&& dnf clean all && rm -rf /var/cache/dnf
# Set the crypto policy to allow SHA-1 certificates - which we have in our tests
RUN dnf -y --nobest install crypto-policies-scripts && update-crypto-policies --set LEGACY
RUN pip3 install websockets junit2html

View file

@ -2,7 +2,7 @@ FROM quay.io/centos/centos:stream9
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241024
# dnf config-manager isn't available at first, and # dnf config-manager isn't available at first, and
# we need it to install the CRB repo below. # we need it to install the CRB repo below.
@ -34,9 +34,9 @@ RUN dnf -y --nobest install \
openssl \ openssl \
openssl-devel \ openssl-devel \
procps-ng \ procps-ng \
python3.13 \ python3 \
python3.13-devel \ python3-devel \
python3.13-pip\ python3-pip\
sqlite \ sqlite \
swig \ swig \
tar \ tar \
@ -47,8 +47,4 @@ RUN dnf -y --nobest install \
# Set the crypto policy to allow SHA-1 certificates - which we have in our tests # Set the crypto policy to allow SHA-1 certificates - which we have in our tests
RUN dnf -y --nobest install crypto-policies-scripts && update-crypto-policies --set LEGACY RUN dnf -y --nobest install crypto-policies-scripts && update-crypto-policies --set LEGACY
# Override the default python3.9 installation paths with 3.13
RUN alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 10
RUN alternatives --install /usr/bin/pip3 pip3 /usr/bin/pip3.13 10
RUN pip3 install websockets junit2html RUN pip3 install websockets junit2html

View file

@ -1,36 +1,32 @@
FROM debian:13 FROM debian:11
ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles"
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241024
RUN apt-get update && apt-get -y install \ RUN apt-get update && apt-get -y install \
bison \ bison \
bsdmainutils \ bsdmainutils \
ccache \ ccache \
cmake \ cmake \
cppzmq-dev \
curl \ curl \
dnsmasq \
flex \ flex \
g++ \ g++ \
gcc \ gcc \
git \ git \
jq \ jq \
libkrb5-dev \ libkrb5-dev \
libnats-dev \
libnode-dev \ libnode-dev \
libpcap-dev \ libpcap-dev \
librdkafka-dev \
libssl-dev \ libssl-dev \
libuv1-dev \ libuv1-dev \
libzmq3-dev \
make \ make \
python3 \ python3 \
python3-dev \ python3-dev \
python3-pip\ python3-pip\
python3-websockets \
sqlite3 \ sqlite3 \
swig \ swig \
wget \ wget \
@ -39,6 +35,4 @@ RUN apt-get update && apt-get -y install \
&& apt autoclean \ && apt autoclean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Debian trixie really doesn't like using pip to install system wide stuff, but RUN pip3 install websockets junit2html
# doesn't seem there's a python3-junit2html package, so not sure what we'd break.
RUN pip3 install --break-system-packages junit2html

View file

@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles"
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241024
RUN apt-get update && apt-get -y install \ RUN apt-get update && apt-get -y install \
bison \ bison \

View file

@ -2,7 +2,7 @@ FROM fedora:41
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250203
RUN dnf -y install \ RUN dnf -y install \
bison \ bison \

View file

@ -2,7 +2,7 @@ FROM fedora:42
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250508
RUN dnf -y install \ RUN dnf -y install \
bison \ bison \

View file

@ -2,7 +2,7 @@ FROM opensuse/leap:15.6
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241024
RUN zypper addrepo https://download.opensuse.org/repositories/openSUSE:Leap:15.6:Update/standard/openSUSE:Leap:15.6:Update.repo \ RUN zypper addrepo https://download.opensuse.org/repositories/openSUSE:Leap:15.6:Update/standard/openSUSE:Leap:15.6:Update.repo \
&& zypper refresh \ && zypper refresh \

View file

@ -2,7 +2,7 @@ FROM opensuse/tumbleweed
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250502
# Remove the repo-openh264 repository, it caused intermittent issues # Remove the repo-openh264 repository, it caused intermittent issues
# and we should not be needing any packages from it. # and we should not be needing any packages from it.

View file

@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles"
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241024
RUN apt-get update && apt-get -y install \ RUN apt-get update && apt-get -y install \
bc \ bc \

View file

@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles"
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250522
RUN apt-get update && apt-get -y install \ RUN apt-get update && apt-get -y install \
bc \ bc \
@ -32,9 +32,7 @@ RUN apt-get update && apt-get -y install \
make \ make \
python3 \ python3 \
python3-dev \ python3-dev \
python3-git \
python3-pip \ python3-pip \
python3-semantic-version \
redis-server \ redis-server \
ruby \ ruby \
sqlite3 \ sqlite3 \

View file

@ -1,10 +1,10 @@
FROM ubuntu:25.04 FROM ubuntu:24.10
ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles"
# A version field to invalidate Cirrus's build cache when needed, as suggested in # A version field to invalidate Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20241115
RUN apt-get update && apt-get -y install \ RUN apt-get update && apt-get -y install \
bc \ bc \

View file

@ -5,7 +5,7 @@ SHELL [ "powershell" ]
# A version field to invalidatea Cirrus's build cache when needed, as suggested in # A version field to invalidatea Cirrus's build cache when needed, as suggested in
# https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822
ENV DOCKERFILE_VERSION=20250905 ENV DOCKERFILE_VERSION 20250528
RUN Set-ExecutionPolicy Unrestricted -Force RUN Set-ExecutionPolicy Unrestricted -Force

View file

@ -7,5 +7,5 @@ call "c:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliar
mkdir build mkdir build
cd build cd build
cmake.exe .. -DCMAKE_BUILD_TYPE=release -DVCPKG_TARGET_TRIPLET="x64-windows-static" -DENABLE_ZEEK_UNIT_TESTS=yes -G Ninja cmake.exe .. -DCMAKE_BUILD_TYPE=release -DVCPKG_TARGET_TRIPLET="x64-windows-static" -DENABLE_ZEEK_UNIT_TESTS=yes -DENABLE_CLUSTER_BACKEND_ZEROMQ=no -G Ninja
cmake.exe --build . cmake.exe --build .

2
cmake

@ -1 +1 @@
Subproject commit d51c6990446cf70cb9c01bca17dad171a1db05d3 Subproject commit 913c8a1a9cdece3461a39a07c330b89baa09be99

View file

@ -3,6 +3,8 @@
#pragma once #pragma once
constexpr char ZEEK_SCRIPT_INSTALL_PATH[] = "@ZEEK_SCRIPT_INSTALL_PATH@"; constexpr char ZEEK_SCRIPT_INSTALL_PATH[] = "@ZEEK_SCRIPT_INSTALL_PATH@";
[[deprecated("Remove in v8.1. Use ZEEK_PLUGIN_INSTALL_PATH")]] constexpr char BRO_PLUGIN_INSTALL_PATH[] =
"@ZEEK_PLUGIN_DIR@";
constexpr char ZEEK_PLUGIN_INSTALL_PATH[] = "@ZEEK_PLUGIN_DIR@"; constexpr char ZEEK_PLUGIN_INSTALL_PATH[] = "@ZEEK_PLUGIN_DIR@";
constexpr char DEFAULT_ZEEKPATH[] = "@DEFAULT_ZEEKPATH@"; constexpr char DEFAULT_ZEEKPATH[] = "@DEFAULT_ZEEKPATH@";
constexpr char ZEEK_SPICY_MODULE_PATH[] = "@ZEEK_SPICY_MODULE_PATH@"; constexpr char ZEEK_SPICY_MODULE_PATH[] = "@ZEEK_SPICY_MODULE_PATH@";

29
configure vendored
View file

@ -90,9 +90,15 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--disable-zkg don't install zkg --disable-zkg don't install zkg
Required Packages in Non-Standard Locations: Required Packages in Non-Standard Locations:
--with-bifcl=PATH path to Zeek BIF compiler executable
(useful for cross-compiling)
--with-binpac=PATH path to BinPAC executable
(useful for cross-compiling)
--with-bison=PATH path to bison executable --with-bison=PATH path to bison executable
--with-broker=PATH path to Broker install root --with-broker=PATH path to Broker install root
(Zeek uses an embedded version by default) (Zeek uses an embedded version by default)
--with-gen-zam=PATH path to Gen-ZAM code generator
(Zeek uses an embedded version by default)
--with-flex=PATH path to flex executable --with-flex=PATH path to flex executable
--with-libkqueue=PATH path to libkqueue install root --with-libkqueue=PATH path to libkqueue install root
(Zeek uses an embedded version by default) (Zeek uses an embedded version by default)
@ -178,6 +184,8 @@ builddir=build
CMakeCacheEntries="" CMakeCacheEntries=""
display_cmake=0 display_cmake=0
has_disable_archiver=0 has_disable_archiver=0
has_with_binpac=0
has_with_bifcl=0
# parse arguments # parse arguments
while [ $# -ne 0 ]; do while [ $# -ne 0 ]; do
@ -361,9 +369,15 @@ while [ $# -ne 0 ]; do
--disable-zkg) --disable-zkg)
append_cache_entry INSTALL_ZKG BOOL false append_cache_entry INSTALL_ZKG BOOL false
;; ;;
--with-bifcl=*)
has_with_bifcl=1
;;
--with-bind=*) --with-bind=*)
append_cache_entry BIND_ROOT_DIR PATH $optarg append_cache_entry BIND_ROOT_DIR PATH $optarg
;; ;;
--with-binpac=*)
has_with_binpac=1
;;
--with-bison=*) --with-bison=*)
append_cache_entry BISON_EXECUTABLE PATH $optarg append_cache_entry BISON_EXECUTABLE PATH $optarg
;; ;;
@ -376,6 +390,9 @@ while [ $# -ne 0 ]; do
--with-flex=*) --with-flex=*)
append_cache_entry FLEX_EXECUTABLE PATH $optarg append_cache_entry FLEX_EXECUTABLE PATH $optarg
;; ;;
--with-gen-zam=*)
append_cache_entry GEN_ZAM_EXE_PATH PATH $optarg
;;
--with-geoip=*) --with-geoip=*)
append_cache_entry LibMMDB_ROOT_DIR PATH $optarg append_cache_entry LibMMDB_ROOT_DIR PATH $optarg
;; ;;
@ -491,3 +508,15 @@ eval ${cmake} 2>&1
echo "# This is the command used to configure this build" >config.status echo "# This is the command used to configure this build" >config.status
echo $command >>config.status echo $command >>config.status
chmod u+x config.status chmod u+x config.status
if [ $has_with_bifcl -eq 1 ]; then
echo
echo "The --with-bifcl option has been deprecated and will be removed in v8.1."
echo "The bundled version of bifcl will always be used."
fi
if [ $has_with_binpac -eq 1 ]; then
echo
echo "The --with-binpac option has been deprecated and will be removed in v8.1."
echo "The bundled version of BinPAC will always be used.\n"
fi

2
doc

@ -1 +1 @@
Subproject commit 8f38ae2fd563314393eb1ca58c827d26e9966520 Subproject commit 1ce37d96e268134100fbc6793c0c64d48e162337

View file

@ -1,7 +1,7 @@
# See the file "COPYING" in the main distribution directory for copyright. # See the file "COPYING" in the main distribution directory for copyright.
# Layer to build Zeek. # Layer to build Zeek.
FROM debian:13-slim FROM debian:bookworm-slim
# Make the shell split commands in the log so we can determine reasons for # Make the shell split commands in the log so we can determine reasons for
# failures more easily. # failures more easily.
@ -16,7 +16,6 @@ RUN echo 'Acquire::https::timeout "180";' >> /etc/apt/apt.conf.d/99-timeouts
# Configure system for build. # Configure system for build.
RUN apt-get -q update \ RUN apt-get -q update \
&& apt-get upgrade -q -y \
&& apt-get install -q -y --no-install-recommends \ && apt-get install -q -y --no-install-recommends \
bind9 \ bind9 \
bison \ bison \
@ -37,7 +36,7 @@ RUN apt-get -q update \
libz-dev \ libz-dev \
make \ make \
python3-minimal \ python3-minimal \
python3-dev \ python3.11-dev \
swig \ swig \
ninja-build \ ninja-build \
python3-pip \ python3-pip \

View file

@ -1,7 +1,7 @@
# See the file "COPYING" in the main distribution directory for copyright. # See the file "COPYING" in the main distribution directory for copyright.
# Final layer containing all artifacts. # Final layer containing all artifacts.
FROM debian:13-slim FROM debian:bookworm-slim
# Make the shell split commands in the log so we can determine reasons for # Make the shell split commands in the log so we can determine reasons for
# failures more easily. # failures more easily.
@ -15,15 +15,14 @@ RUN echo 'Acquire::http::timeout "180";' > /etc/apt/apt.conf.d/99-timeouts
RUN echo 'Acquire::https::timeout "180";' >> /etc/apt/apt.conf.d/99-timeouts RUN echo 'Acquire::https::timeout "180";' >> /etc/apt/apt.conf.d/99-timeouts
RUN apt-get -q update \ RUN apt-get -q update \
&& apt-get upgrade -q -y \
&& apt-get install -q -y --no-install-recommends \ && apt-get install -q -y --no-install-recommends \
ca-certificates \ ca-certificates \
git \ git \
jq \ jq \
libmaxminddb0 \ libmaxminddb0 \
libnode115 \ libnode108 \
libpcap0.8 \ libpcap0.8 \
libpython3.13 \ libpython3.11 \
libssl3 \ libssl3 \
libuv1 \ libuv1 \
libz1 \ libz1 \

View file

@ -105,29 +105,6 @@ export {
## Event for accessing logged records. ## Event for accessing logged records.
global log_x509: event(rec: Info); global log_x509: event(rec: Info);
## The maximum number of bytes that a single string field can contain when
## logging. If a string reaches this limit, the log output for the field will be
## truncated. Setting this to zero disables the limiting.
##
## .. zeek:see:: Log::default_max_field_string_bytes
const default_max_field_string_bytes = Log::default_max_field_string_bytes &redef;
## The maximum number of elements a single container field can contain when
## logging. If a container reaches this limit, the log output for the field will
## be truncated. Setting this to zero disables the limiting.
##
## .. zeek:see:: Log::default_max_field_container_elements
const default_max_field_container_elements = 500 &redef;
## The maximum total number of container elements a record may log. This is the
## sum of all container elements logged for the record. If this limit is reached,
## all further containers will be logged as empty containers. If the limit is
## reached while processing a container, the container will be truncated in the
## output. Setting this to zero disables the limiting.
##
## .. zeek:see:: Log::default_max_total_container_elements
const default_max_total_container_elements = 1500 &redef;
} }
global known_log_certs_with_broker: set[LogCertHash] &create_expire=relog_known_certificates_after &backend=Broker::MEMORY; global known_log_certs_with_broker: set[LogCertHash] &create_expire=relog_known_certificates_after &backend=Broker::MEMORY;
@ -140,12 +117,7 @@ redef record Files::Info += {
event zeek_init() &priority=5 event zeek_init() &priority=5
{ {
# x509 can have some very large certificates and very large sets of URIs. Expand the log size filters Log::create_stream(X509::LOG, Log::Stream($columns=Info, $ev=log_x509, $path="x509", $policy=log_policy));
# so that we're not truncating those.
Log::create_stream(X509::LOG, Log::Stream($columns=Info, $ev=log_x509, $path="x509", $policy=log_policy,
$max_field_string_bytes=X509::default_max_field_string_bytes,
$max_field_container_elements=X509::default_max_field_container_elements,
$max_total_container_elements=X509::default_max_total_container_elements));
# We use MIME types internally to distinguish between user and CA certificates. # We use MIME types internally to distinguish between user and CA certificates.
# The first certificate in a connection always gets tagged as user-cert, all # The first certificate in a connection always gets tagged as user-cert, all
@ -253,3 +225,4 @@ event file_state_remove(f: fa_file) &priority=5
Log::write(LOG, f$info$x509); Log::write(LOG, f$info$x509);
} }

View file

@ -6,6 +6,9 @@
module DPD; module DPD;
export { export {
## Deprecated, please see https://github.com/zeek/zeek/pull/4200 for details
option max_violations: table[Analyzer::Tag] of count = table() &deprecated="Remove in v8.1: This has become non-functional in Zeek 7.2, see PR #4200" &default = 5;
## Analyzers which you don't want to remove on violations. ## Analyzers which you don't want to remove on violations.
option ignore_violations: set[Analyzer::Tag] = set(); option ignore_violations: set[Analyzer::Tag] = set();
@ -107,3 +110,4 @@ event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationI
if ( disabled ) if ( disabled )
event analyzer_failed(network_time(), atype, info); event analyzer_failed(network_time(), atype, info);
} }

View file

@ -23,10 +23,8 @@ export {
uid: string &log &optional; uid: string &log &optional;
## File UID if available. ## File UID if available.
fuid: string &log &optional; fuid: string &log &optional;
## Connection identifier if available. ## Connection identifier if available
id: conn_id &log &optional; id: conn_id &log &optional;
## Transport protocol for the violation, if available.
proto: transport_proto &log &optional;
## Failure or violation reason, if available. ## Failure or violation reason, if available.
failure_reason: string &log; failure_reason: string &log;
## Data causing failure or violation if available. Truncated ## Data causing failure or violation if available. Truncated
@ -64,7 +62,6 @@ function log_analyzer_failure(ts: time, atype: AllAnalyzers::Tag, info: Analyzer
{ {
rec$id = info$c$id; rec$id = info$c$id;
rec$uid = info$c$uid; rec$uid = info$c$uid;
rec$proto = get_port_transport_proto(info$c$id$orig_p);
} }
if ( info?$f ) if ( info?$f )

View file

@ -28,7 +28,7 @@ export {
## Default address on which to listen for WebSocket connections. ## Default address on which to listen for WebSocket connections.
## ##
## .. zeek:see:: Cluster::listen_websocket ## .. zeek:see:: Broker::listen_websocket
const default_listen_address_websocket = getenv("ZEEK_DEFAULT_LISTEN_ADDRESS") &redef; const default_listen_address_websocket = getenv("ZEEK_DEFAULT_LISTEN_ADDRESS") &redef;
## Default interval to retry connecting to a peer if it cannot be made to ## Default interval to retry connecting to a peer if it cannot be made to
@ -69,6 +69,11 @@ export {
## all peers. ## all peers.
const ssl_keyfile = "" &redef; const ssl_keyfile = "" &redef;
## The number of buffered messages at the Broker/CAF layer after which
## a subscriber considers themselves congested (i.e. tune the congestion
## control mechanisms).
const congestion_queue_size = 200 &redef &deprecated="Remove in v8.1. Non-functional since v5.0";
## The max number of log entries per log stream to batch together when ## The max number of log entries per log stream to batch together when
## sending log messages to a remote logger. ## sending log messages to a remote logger.
const log_batch_size = 400 &redef; const log_batch_size = 400 &redef;
@ -314,6 +319,27 @@ export {
p: port &default = default_port, p: port &default = default_port,
retry: interval &default = default_listen_retry): port; retry: interval &default = default_listen_retry): port;
## Listen for remote connections using WebSocket.
##
## a: an address string on which to accept connections, e.g.
## "127.0.0.1". An empty string refers to INADDR_ANY.
##
## p: the TCP port to listen on. The value 0 means that the OS should choose
## the next available free port.
##
## retry: If non-zero, retries listening in regular intervals if the port cannot be
## acquired immediately. 0 disables retries. If the
## ZEEK_DEFAULT_LISTEN_RETRY environment variable is set (as number
## of seconds), it overrides any value given here.
##
## Returns: the bound port or 0/? on failure.
##
## .. zeek:see:: Broker::status
global listen_websocket: function(a: string &default = default_listen_address_websocket,
p: port &default = default_port_websocket,
retry: interval &default = default_listen_retry): port
&deprecated="Remove in v8.1. Switch to Cluster::listen_websocket() instead.";
## Initiate a remote connection. ## Initiate a remote connection.
## ##
## a: an address to connect to, e.g. "localhost" or "127.0.0.1". ## a: an address to connect to, e.g. "localhost" or "127.0.0.1".
@ -424,6 +450,29 @@ export {
## ##
## Returns: true if a new event forwarding/subscription is now registered. ## Returns: true if a new event forwarding/subscription is now registered.
global forward: function(topic_prefix: string): bool; global forward: function(topic_prefix: string): bool;
## Automatically send an event to any interested peers whenever it is
## locally dispatched. (For example, using "event my_event(...);" in a
## script.)
##
## topic: a topic string associated with the event message.
## Peers advertise interest by registering a subscription to some
## prefix of this topic name.
##
## ev: a Zeek event value.
##
## Returns: true if automatic event sending is now enabled.
global auto_publish: function(topic: string, ev: any): bool &deprecated="Remove in v8.1. Switch to explicit Cluster::publish() calls. Auto-publish won't work with all cluster backends.";
## Stop automatically sending an event to peers upon local dispatch.
##
## topic: a topic originally given to :zeek:see:`Broker::auto_publish`.
##
## ev: an event originally given to :zeek:see:`Broker::auto_publish`.
##
## Returns: true if automatic events will not occur for the topic/event
## pair.
global auto_unpublish: function(topic: string, ev: any): bool &deprecated="Remove in v8.1. See Broker::auto_publish()";
} }
@load base/bif/comm.bif @load base/bif/comm.bif
@ -465,6 +514,31 @@ function listen(a: string, p: port, retry: interval): port
return bound; return bound;
} }
event retry_listen_websocket(a: string, p: port, retry: interval)
{
@pragma push ignore-deprecations
listen_websocket(a, p, retry);
@pragma pop ignore-deprecations
}
function listen_websocket(a: string, p: port, retry: interval): port
{
local bound = __listen(a, p, Broker::WEBSOCKET);
if ( bound == 0/tcp )
{
local e = getenv("ZEEK_DEFAULT_LISTEN_RETRY");
if ( e != "" )
retry = double_to_interval(to_double(e));
if ( retry != 0secs )
schedule retry { retry_listen_websocket(a, p, retry) };
}
return bound;
}
function peer(a: string, p: port, retry: interval): bool function peer(a: string, p: port, retry: interval): bool
{ {
return __peer(a, p, retry); return __peer(a, p, retry);
@ -519,3 +593,13 @@ function unsubscribe(topic_prefix: string): bool
{ {
return __unsubscribe(topic_prefix); return __unsubscribe(topic_prefix);
} }
function auto_publish(topic: string, ev: any): bool
{
return __auto_publish(topic, ev);
}
function auto_unpublish(topic: string, ev: any): bool
{
return __auto_unpublish(topic, ev);
}

View file

@ -362,6 +362,8 @@ export {
## WebSocket server options to pass to :zeek:see:`Cluster::listen_websocket`. ## WebSocket server options to pass to :zeek:see:`Cluster::listen_websocket`.
type WebSocketServerOptions: record { type WebSocketServerOptions: record {
## The host address to listen on.
listen_host: string &optional &deprecated="Remove in v8.1: Use $listen_addr instead.";
## The address to listen on, cannot be used together with ``listen_host``. ## The address to listen on, cannot be used together with ``listen_host``.
listen_addr: addr &optional; listen_addr: addr &optional;
## The port the WebSocket server is supposed to listen on. ## The port the WebSocket server is supposed to listen on.
@ -399,20 +401,6 @@ export {
## The value of the X-Application-Name HTTP header, if any. ## The value of the X-Application-Name HTTP header, if any.
application_name: string &optional; application_name: string &optional;
}; };
## A hook invoked for every :zeek:see:`Cluster::subscribe` call.
##
## Breaking from this hook has no effect.
##
## topic: The topic string as given to :zeek:see:`Cluster::subscribe`.
global on_subscribe: hook(topic: string);
## A hook invoked for every :zeek:see:`Cluster::subscribe` call.
##
## Breaking from this hook has no effect.
##
## topic: The topic string as given to :zeek:see:`Cluster::subscribe`.
global on_unsubscribe: hook(topic: string);
} }
# Needs declaration of Cluster::Event type. # Needs declaration of Cluster::Event type.

View file

@ -422,26 +422,6 @@ export {
## .. :zeek:see:`Log::default_max_delay_queue_size` ## .. :zeek:see:`Log::default_max_delay_queue_size`
## .. :zeek:see:`Log::set_max_delay_queue_size` ## .. :zeek:see:`Log::set_max_delay_queue_size`
max_delay_queue_size: count &default=default_max_delay_queue_size; max_delay_queue_size: count &default=default_max_delay_queue_size;
## Maximum string size for field in a log record from this stream.
##
## .. :zeek:see:`Log::default_max_field_string_bytes`
max_field_string_bytes: count &default=Log::default_max_field_string_bytes;
## Maximum total string size in a log record from this stream.
##
## .. :zeek:see:`Log::default_max_total_string_bytes`
max_total_string_bytes: count &default=Log::default_max_total_string_bytes;
## Maximum container elements for field in a log record from this stream.
##
## .. :zeek:see:`Log::default_max_field_container_elements`
max_field_container_elements: count &default=Log::default_max_field_container_elements;
## Maximum total container elements in a log record from this stream.
##
## .. :zeek:see:`Log::default_max_total_container_elements`
max_total_container_elements: count &default=Log::default_max_total_container_elements;
}; };
## Sentinel value for indicating that a filter was not found when looked up. ## Sentinel value for indicating that a filter was not found when looked up.

View file

@ -245,6 +245,16 @@ export {
label_values: labels_vector, label_values: labels_vector,
measurement: double): bool; measurement: double): bool;
## Interval at which the :zeek:see:`Telemetry::sync` hook is invoked.
##
## By default, the hook is invoked on demand, setting this option to
## a positive interval allows to invoke it regularly, too. Regular
## invocations are relative to Zeek's network time.
##
## Note that on-demand hook invocation will happen even if this
## is set.
option sync_interval = 0sec &deprecated="Remove in 8.1. If you require regular sync invocation, do so explicitly in a scheduled event.";
## Collect all counter and gauge metrics matching the given *name* and *prefix*. ## Collect all counter and gauge metrics matching the given *name* and *prefix*.
## ##
## For histogram metrics, use the :zeek:see:`Telemetry::collect_histogram_metrics`. ## For histogram metrics, use the :zeek:see:`Telemetry::collect_histogram_metrics`.
@ -455,6 +465,14 @@ function collect_histogram_metrics(prefix: string, name: string): vector of Hist
return Telemetry::__collect_histogram_metrics(prefix, name); return Telemetry::__collect_histogram_metrics(prefix, name);
} }
event run_sync_hook()
{
hook Telemetry::sync();
@pragma push ignore-deprecations
schedule sync_interval { run_sync_hook() };
@pragma pop ignore-deprecations
}
# Expose the Zeek version as Prometheus style info metric # Expose the Zeek version as Prometheus style info metric
global version_gauge_family = Telemetry::register_gauge_family(Telemetry::MetricOpts( global version_gauge_family = Telemetry::register_gauge_family(Telemetry::MetricOpts(
$prefix="zeek", $prefix="zeek",
@ -467,6 +485,11 @@ global version_gauge_family = Telemetry::register_gauge_family(Telemetry::Metric
event zeek_init() event zeek_init()
{ {
@pragma push ignore-deprecations
if ( sync_interval > 0sec )
schedule sync_interval { run_sync_hook() };
@pragma pop ignore-deprecations
local v = Version::info; local v = Version::info;
local labels = vector(cat(v$version_number), local labels = vector(cat(v$version_number),
cat(v$major), cat(v$minor), cat (v$patch), cat(v$major), cat(v$minor), cat (v$patch),

View file

@ -1726,6 +1726,18 @@ const tcp_excessive_data_without_further_acks = 10 * 1024 * 1024 &redef;
## buffering. ## buffering.
const tcp_max_old_segments = 0 &redef; const tcp_max_old_segments = 0 &redef;
## For services without a handler, these sets define originator-side ports
## that still trigger reassembly.
##
## .. zeek:see:: tcp_reassembler_ports_resp
const tcp_reassembler_ports_orig: set[port] = {} &redef &deprecated="Remove in v8.1. Non-functional since v4.1";
## For services without a handler, these sets define responder-side ports
## that still trigger reassembly.
##
## .. zeek:see:: tcp_reassembler_ports_orig
const tcp_reassembler_ports_resp: set[port] = {} &redef &deprecated="Remove in v8.1. Non-functional since v4.1";
## Defines destination TCP ports for which the contents of the originator stream ## Defines destination TCP ports for which the contents of the originator stream
## should be delivered via :zeek:see:`tcp_contents`. ## should be delivered via :zeek:see:`tcp_contents`.
## ##
@ -3051,8 +3063,9 @@ type dns_binds_rr: record {
algorithm: count; ##< Algorithm for Public Key. algorithm: count; ##< Algorithm for Public Key.
key_id: count; ##< key tag. key_id: count; ##< key tag.
removal_flag: count; ##< rm flag. removal_flag: count; ##< rm flag.
complete_flag: count; ##< complete flag. complte_flag: string &deprecated="Remove in v8.1: Use complete_flag instead."; ##< complete flag.
is_query: count; ##< The RR is a query/Response. is_query: count; ##< The RR is a query/Response.
complete_flag: count; ##< complete flag.
}; };
## A Private RR type LOC record. ## A Private RR type LOC record.
@ -3071,30 +3084,12 @@ type dns_loc_rr: record {
is_query: count; ##< The RR is a query/Response. is_query: count; ##< The RR is a query/Response.
}; };
## A SvcParamKey with an optional SvcParamValue. ## DNS SVCB and HTTPS RRs
#
## .. zeek:see:: dns_svcb_rr
type dns_svcb_param: record {
key: count; ##< SvcParamKey
mandatory: vector of count &optional; ##< "mandatory" SvcParamKey values
alpn: vector of string &optional; ##< "alpn" IDs
p: count &optional; ##< "port" number, TCP or UDP
hint: vector of addr &optional; ##< "ipv4hint" or "ipv6hint" IP addresses
ech: string &optional; ##< "ech" base64 encoded ECHConfigList blob
raw: string &optional; ##< reserved key's or malformed value
};
type dns_svcb_param_vec: vector of dns_svcb_param;
## A SVCB or HTTPS record.
##
## See also RFC 9460 - Service Binding and Parameter Specification via the DNS (SVCB and HTTPS Resource Records).
## ##
## .. zeek:see:: dns_SVCB dns_HTTPS ## .. zeek:see:: dns_SVCB dns_HTTPS
type dns_svcb_rr: record { type dns_svcb_rr: record {
svc_priority: count; ##< Service priority. If zero, the record is in AliasMode and has no SvcParam. svc_priority: count; ##< Service priority for the current record, 0 indicates that this record is in AliasMode and cannot carry svc_params; otherwise this is in ServiceMode, and may include svc_params
target_name: string; ##< Target name, the hostname of the service endpoint. target_name: string; ##< Target name, the hostname of the service endpoint.
svc_params: dns_svcb_param_vec &optional; ##< Service parameters, if any.
}; };
## A NAPTR record. ## A NAPTR record.
@ -3761,31 +3756,6 @@ export {
## higher than this limit, but it prevents runaway-sized log entries from causing ## higher than this limit, but it prevents runaway-sized log entries from causing
## problems. ## problems.
const max_log_record_size = 1024*1024*64 &redef; const max_log_record_size = 1024*1024*64 &redef;
## The maximum number of bytes that a single string field can contain when
## logging. If a string reaches this limit, the log output for the field will be
## truncated. Setting this to zero disables the limiting.
const default_max_field_string_bytes = 4096 &redef;
## The maximum number of elements a single container field can contain when
## logging. If a container reaches this limit, the log output for the field will
## be truncated. Setting this to zero disables the limiting.
const default_max_field_container_elements = 100 &redef;
## The maximum total bytes a record may log for string fields. This is the sum of
## all bytes in string fields logged for the record. If this limit is reached, all
## further string fields will be logged as empty strings. Any containers holding
## string fields will be logged as empty containers. If the limit is reached while
## processing a container holding string fields, the container will be truncated
## in the log output. Setting this to zero disables the limiting.
const default_max_total_string_bytes = 256000 &redef;
## The maximum total number of container elements a record may log. This is the
## sum of all container elements logged for the record. If this limit is reached,
## all further containers will be logged as empty containers. If the limit is
## reached while processing a container, the container will be truncated in the
## output. Setting this to zero disables the limiting.
const default_max_total_container_elements = 500 &redef;
} }
module POP3; module POP3;
@ -5709,31 +5679,6 @@ export {
}; };
} }
module AF_Packet;
export {
## Size of the ring-buffer.
const buffer_size = 128 * 1024 * 1024 &redef;
## Size of an individual block. Needs to be a multiple of page size.
const block_size = 4096 * 8 &redef;
## Retire timeout for a single block.
const block_timeout = 10msec &redef;
## Toggle whether to use hardware timestamps.
const enable_hw_timestamping = F &redef;
## Toggle whether to use PACKET_FANOUT.
const enable_fanout = T &redef;
## Toggle defragmentation of IP packets using PACKET_FANOUT_FLAG_DEFRAG.
const enable_defrag = F &redef;
## Fanout mode.
const fanout_mode = FANOUT_HASH &redef;
## Fanout ID.
const fanout_id = 23 &redef;
## Link type (default Ethernet).
const link_type = 1 &redef;
## Checksum validation mode.
const checksum_validation_mode: ChecksumMode = CHECKSUM_ON &redef;
}
module DCE_RPC; module DCE_RPC;
export { export {

View file

@ -182,9 +182,8 @@ export {
[4] = "SHA384", [4] = "SHA384",
} &default = function(n: count): string { return fmt("digest-%d", n); }; } &default = function(n: count): string { return fmt("digest-%d", n); };
## SVCB/HTTPS SvcParam keys as defined in ## SVCB/HTTPS SvcParam keys, as defined in
## https://datatracker.ietf.org/doc/html/rfc9460#name-initial-contents ## https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.txt, sec 14.3.2
## Keep in sync with src/analyzer/protocol/dns/DNS.h SVCPARAM_Key.
const svcparam_keys = { const svcparam_keys = {
[0] = "mandatory", [0] = "mandatory",
[1] = "alpn", [1] = "alpn",

View file

@ -139,14 +139,6 @@ export {
## out and request/response tracking reset to prevent unbounded ## out and request/response tracking reset to prevent unbounded
## state growth. ## state growth.
option max_pending_requests = 100; option max_pending_requests = 100;
## The maximum number of bytes that a single string field can contain when
## logging. If a string reaches this limit, the log output for the field will be
## truncated. Setting this to zero disables the limiting. HTTP has no maximum
## length for various fields such as the URI, so this is set to zero by default.
##
## .. zeek:see:: Log::default_max_field_string_bytes
const default_max_field_string_bytes = 0 &redef;
} }
# Add the http state tracking fields to the connection record. # Add the http state tracking fields to the connection record.
@ -164,8 +156,7 @@ redef likely_server_ports += { ports };
# Initialize the HTTP logging stream and ports. # Initialize the HTTP logging stream and ports.
event zeek_init() &priority=5 event zeek_init() &priority=5
{ {
Log::create_stream(HTTP::LOG, Log::Stream($columns=Info, $ev=log_http, $path="http", $policy=log_policy, Log::create_stream(HTTP::LOG, Log::Stream($columns=Info, $ev=log_http, $path="http", $policy=log_policy));
$max_field_string_bytes=HTTP::default_max_field_string_bytes));
Analyzer::register_for_ports(Analyzer::ANALYZER_HTTP, ports); Analyzer::register_for_ports(Analyzer::ANALYZER_HTTP, ports);
} }
@ -403,3 +394,4 @@ hook finalize_http(c: connection)
} }
} }
} }

View file

@ -53,7 +53,7 @@ export {
user: string &optional; user: string &optional;
database: string &optional; database: string &optional;
application_name: string &optional; application_name: string &optional;
rows: count &optional; rows: count &default=0;
errors: vector of string; errors: vector of string;
}; };
@ -197,6 +197,8 @@ event PostgreSQL::authentication_ok(c: connection) {
c$postgresql$backend = "auth_ok"; c$postgresql$backend = "auth_ok";
c$postgresql$success = T; c$postgresql$success = T;
emit_log(c);
} }
event PostgreSQL::terminate(c: connection) { event PostgreSQL::terminate(c: connection) {
@ -222,9 +224,6 @@ event PostgreSQL::simple_query(c: connection, query: string) {
event PostgreSQL::data_row(c: connection, column_values: count) { event PostgreSQL::data_row(c: connection, column_values: count) {
hook set_session(c); hook set_session(c);
if ( ! c$postgresql_state?$rows )
c$postgresql_state$rows = 0;
++c$postgresql_state$rows; ++c$postgresql_state$rows;
} }
@ -237,11 +236,7 @@ event PostgreSQL::ready_for_query(c: connection, transaction_status: string) {
if ( ! c$postgresql?$success ) if ( ! c$postgresql?$success )
c$postgresql$success = transaction_status == "I" || transaction_status == "T"; c$postgresql$success = transaction_status == "I" || transaction_status == "T";
if ( c$postgresql_state?$rows ) { c$postgresql$rows = c$postgresql_state$rows;
c$postgresql$rows = c$postgresql_state$rows;
delete c$postgresql_state$rows;
}
emit_log(c); emit_log(c);
} }

View file

@ -117,14 +117,15 @@ function decompose_uri(uri: string): URI
} }
} }
if ( /:[0-9]*$/ in s ) if ( /:/ in s )
{ {
# Input ends with a numeric port or just colon: Strip it # Parse location and port.
# for netlocation and convert any port digits into portnum. parts = split_string1(s, /:/);
u$netlocation = gsub(s, /:[0-9]*$/, ""); u$netlocation = parts[0];
local portstr = s[|u$netlocation| + 1:]; if ( parts[1] != "" )
if ( portstr != "" ) {
u$portnum = to_count(portstr); u$portnum = to_count(parts[1]);
}
} }
else else
{ {

View file

@ -0,0 +1,96 @@
##! Creates the now deprecated dpd.logfile.
# Remove in v8.1
module DPD;
export {
## Add the DPD logging stream identifier.
redef enum Log::ID += { LOG };
## A default logging policy hook for the stream.
global log_policy: Log::PolicyHook;
## The record type defining the columns to log in the DPD logging stream.
type Info: record {
## Timestamp for when protocol analysis failed.
ts: time &log;
## Connection unique ID.
uid: string &log;
## Connection ID containing the 4-tuple which identifies endpoints.
id: conn_id &log;
## Transport protocol for the violation.
proto: transport_proto &log;
## The analyzer that generated the violation.
analyzer: string &log;
## The textual reason for the analysis failure.
failure_reason: string &log;
};
}
redef record connection += {
dpd: Info &optional;
## The set of services (analyzers) for which Zeek has observed a
## violation after the same service had previously been confirmed.
service_violation: set[string] &default=set() &ordered &deprecated="Remove in v8.1. Consider using failed_analyzers instead";
};
event zeek_init() &priority=5
{
Log::create_stream(DPD::LOG, Log::Stream($columns=Info, $path="dpd", $policy=log_policy));
}
# before the same event in dpd.zeek
event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) &priority=15
{
if ( ! is_protocol_analyzer(atype) && ! is_packet_analyzer(atype) )
return;
if ( ! info?$c )
return;
local c = info$c;
local analyzer = Analyzer::name(atype);
# If the service hasn't been confirmed yet, or already failed,
# don't generate a log message for the protocol violation.
if ( analyzer !in c$service || analyzer in c$service_violation )
return;
add c$service_violation[analyzer];
local dpd: Info;
dpd$ts = network_time();
dpd$uid = c$uid;
dpd$id = c$id;
dpd$proto = get_port_transport_proto(c$id$orig_p);
dpd$analyzer = analyzer;
# Encode data into the reason if there's any as done for the old
# analyzer_violation event, previously.
local reason = info$reason;
if ( info?$data )
{
local ellipsis = |info$data| > 40 ? "..." : "";
local data = info$data[0:40];
reason = fmt("%s [%s%s]", reason, data, ellipsis);
}
dpd$failure_reason = reason;
c$dpd = dpd;
}
event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo ) &priority=-5
{
if ( ! is_protocol_analyzer(atype) && ! is_packet_analyzer(atype) )
return;
if ( ! info?$c )
return;
if ( info$c?$dpd )
{
Log::write(DPD::LOG, info$c$dpd);
delete info$c$dpd;
}
}

View file

@ -0,0 +1,3 @@
@deprecated("frameworks/dpd/detect-protocols.zeek moved to frameworks/analyzer/detect-protocols.zeek. Please switch to frameworks/analyzer/detect-protocols.zeek. Remove in 8.1")
@load frameworks/analyzer/detect-protocols.zeek

View file

@ -0,0 +1,34 @@
@deprecated("Please switch to frameworks/analyzer/packet-segment-logging, which logs to analyzer.log. Remove in 8.1")
##! This script enables logging of packet segment data when a protocol
##! parsing violation is encountered. The amount of data from the
##! packet logged is set by the :zeek:see:`DPD::packet_segment_size` variable.
##! A caveat to logging packet data is that in some cases, the packet may
##! not be the packet that actually caused the protocol violation.
@load frameworks/analyzer/deprecated-dpd-log
module DPD;
export {
redef record Info += {
## A chunk of the payload that most likely resulted in the
## analyzer violation.
packet_segment: string &optional &log;
};
## Size of the packet segment to display in the DPD log.
option packet_segment_size: int = 255;
}
event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) &priority=4
{
if ( ! is_protocol_analyzer(atype) && ! is_packet_analyzer(atype) )
return;
if ( ! info?$c || ! info$c?$dpd )
return;
info$c$dpd$packet_segment = fmt("%s", sub_bytes(get_current_packet()$data, 0, packet_segment_size));
}

View file

@ -61,14 +61,6 @@ export {
## for websocket clients. ## for websocket clients.
const default_port_websocket = 2149/tcp &redef; const default_port_websocket = 2149/tcp &redef;
## TLS options for the controller's WebSocket server. The default is
## to operate unencrypted. To replicate Broker's default encryption
## without endpoint validation, set the
## :zeek:field:`Cluster::WebSocketTLSOptions$ca_file` field to
## "NONE" and :zeek:field:`Cluster::WebSocketTLSOptions$ciphers` to
## "AECDH-AES256-SHA@SECLEVEL=0:AECDH-AES256-SHA:P-384".
const tls_options_websocket = Cluster::WebSocketTLSOptions() &redef;
## Whether the controller should auto-assign Broker listening ports to ## Whether the controller should auto-assign Broker listening ports to
## cluster nodes that need them and don't have them explicitly specified ## cluster nodes that need them and don't have them explicitly specified
## in cluster configurations. ## in cluster configurations.

View file

@ -4,7 +4,6 @@
##! by the supervisor. ##! by the supervisor.
@load base/frameworks/broker @load base/frameworks/broker
@load base/frameworks/cluster
@load policy/frameworks/management @load policy/frameworks/management
@load policy/frameworks/management/agent/config # For the agent topic prefix @load policy/frameworks/management/agent/config # For the agent topic prefix
@ -1645,10 +1644,9 @@ event zeek_init()
if ( cni$bound_port != 0/unknown ) if ( cni$bound_port != 0/unknown )
{ {
local ws_opts = Cluster::WebSocketServerOptions($listen_addr=to_addr(cni$address), @pragma push ignore-deprecations
$listen_port=cni$bound_port, Broker::listen_websocket(cat(cni$address), cni$bound_port);
$tls_options=Management::Controller::tls_options_websocket); @pragma pop ignore-deprecations
Cluster::listen_websocket(ws_opts);
websocket_info = fmt("websocket port %s:%s", cni$address, cni$bound_port); websocket_info = fmt("websocket port %s:%s", cni$address, cni$bound_port);
} }

View file

@ -0,0 +1,142 @@
##! SQL injection attack detection in HTTP.
## This package is deprecated in favor of detect-sql-injection.zeek.
##
## The replacement script annotates the notices it generates with
## an associated $uid connection identifier; always provides an attacker
## IP address in the $src field; and always provides a victim IP address
## in the $dst field. The notices generated by this script, on the other
## hand, lack a $uid identifier, and do not provide $dst information.
## In addition, for SQL_Injection_Victim notices, this script provides the
## victim's IP address in the $src field, which some find counter-intuitive.
##
## In addition, the replacement script removes support for generating
## Notice emails.
@deprecated "Remove in v8.1: Switch to the improved detect-sql-injection script"
@load base/frameworks/notice
@load base/frameworks/sumstats
@load base/protocols/http
module HTTP;
export {
redef enum Notice::Type += {
## Indicates that a host performing SQL injection attacks was
## detected.
SQL_Injection_Attacker,
## Indicates that a host was seen to have SQL injection attacks
## against it. This is tracked by IP address as opposed to
## hostname.
SQL_Injection_Victim,
};
redef enum Tags += {
## Indicator of a URI based SQL injection attack.
URI_SQLI,
## Indicator of client body based SQL injection attack. This is
## typically the body content of a POST request. Not implemented
## yet.
POST_SQLI,
## Indicator of a cookie based SQL injection attack. Not
## implemented yet.
COOKIE_SQLI,
};
## Defines the threshold that determines if an SQL injection attack
## is ongoing based on the number of requests that appear to be SQL
## injection attacks.
const sqli_requests_threshold: double = 50.0 &redef;
## Interval at which to watch for the
## :zeek:id:`HTTP::sqli_requests_threshold` variable to be crossed.
## At the end of each interval the counter is reset.
const sqli_requests_interval = 5min &redef;
## Collecting samples will add extra data to notice emails
## by collecting some sample SQL injection url paths. Disable
## sample collection by setting this value to 0.
const collect_SQLi_samples = 5 &redef;
## Regular expression is used to match URI based SQL injections.
const match_sql_injection_uri =
/[\?&][^[:blank:]\x00-\x1f\|\+]+?=[\-[:alnum:]%]+([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|\)?;)+.*?([hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)+/
| /[\?&][^[:blank:]\x00-\x1f\|\+]+?=[\-0-9%]+([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|\)?;)+([xX]?[oO][rR]|[nN]?[aA][nN][dD])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)+['"]?(([^a-zA-Z&]+)?=|[eE][xX][iI][sS][tT][sS])/
| /[\?&][^[:blank:]\x00-\x1f\+]+?=[\-0-9%]*([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*(-|=|\+|\|\|)([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*([0-9]|\(?[cC][oO][nN][vV][eE][rR][tT]|[cC][aA][sS][tT])/
| /[\?&][^[:blank:]\x00-\x1f\|\+]+?=([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|;)*([xX]?[oO][rR]|[nN]?[aA][nN][dD]|[hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[rR][eE][gG][eE][xX][pP]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|[\[(])+[a-zA-Z&]{2,}/
| /[\?&][^[:blank:]\x00-\x1f\+]+?=[^\.]*?([cC][hH][aA][rR]|[aA][sS][cC][iI][iI]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][uU][nN][cC][aA][tT][eE]|[vV][eE][rR][sS][iI][oO][nN]|[lL][eE][nN][gG][tT][hH])\(/
| /\/\*![[:digit:]]{5}.*?\*\// &redef;
## A hook that can be used to prevent specific requests from being counted
## as an injection attempt. Use a 'break' statement to exit the hook
## early and ignore the request.
global HTTP::sqli_policy: hook(c: connection, method: string, unescaped_URI: string);
}
function format_sqli_samples(samples: vector of SumStats::Observation): string
{
local ret = "SQL Injection samples\n---------------------";
for ( i in samples )
ret += "\n" + samples[i]$str;
return ret;
}
event zeek_init() &priority=3
{
# Add filters to the metrics so that the metrics framework knows how to
# determine when it looks like an actual attack and how to respond when
# thresholds are crossed.
local r1 = SumStats::Reducer($stream="http.sqli.attacker", $apply=set(SumStats::SUM, SumStats::SAMPLE), $num_samples=collect_SQLi_samples);
SumStats::create(SumStats::SumStat($name="detect-sqli-attackers",
$epoch=sqli_requests_interval,
$reducers=set(r1),
$threshold_val(key: SumStats::Key, result: SumStats::Result) =
{
return result["http.sqli.attacker"]$sum;
},
$threshold=sqli_requests_threshold,
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) =
{
local r = result["http.sqli.attacker"];
NOTICE(Notice::Info($note=SQL_Injection_Attacker,
$msg="An SQL injection attacker was discovered!",
$email_body_sections=vector(format_sqli_samples(r$samples)),
$src=key$host,
$identifier=cat(key$host)));
}));
local r2 = SumStats::Reducer($stream="http.sqli.victim", $apply=set(SumStats::SUM, SumStats::SAMPLE), $num_samples=collect_SQLi_samples);
SumStats::create(SumStats::SumStat($name="detect-sqli-victims",
$epoch=sqli_requests_interval,
$reducers=set(r2),
$threshold_val(key: SumStats::Key, result: SumStats::Result) =
{
return result["http.sqli.victim"]$sum;
},
$threshold=sqli_requests_threshold,
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) =
{
local r = result["http.sqli.victim"];
NOTICE(Notice::Info($note=SQL_Injection_Victim,
$msg="An SQL injection victim was discovered!",
$email_body_sections=vector(format_sqli_samples(r$samples)),
$src=key$host,
$identifier=cat(key$host)));
}));
}
event http_request(c: connection, method: string, original_URI: string,
unescaped_URI: string, version: string) &priority=3
{
if ( ! hook HTTP::sqli_policy(c, method, unescaped_URI) )
return;
if ( match_sql_injection_uri in unescaped_URI )
{
add c$http$tags[URI_SQLI];
SumStats::observe("http.sqli.attacker", SumStats::Key($host=c$id$orig_h), SumStats::Observation($str=original_URI));
SumStats::observe("http.sqli.victim", SumStats::Key($host=c$id$resp_h), SumStats::Observation($str=original_URI));
}
}

View file

@ -13,9 +13,5 @@ redef record Info += {
event http_request(c: connection, method: string, original_URI: string, event http_request(c: connection, method: string, original_URI: string,
unescaped_URI: string, version: string) &priority=2 unescaped_URI: string, version: string) &priority=2
{ {
local param_parts = split_string1(original_URI, /\?/); c$http$uri_vars = extract_keys(original_URI, /&/);
if ( |param_parts| > 1 )
{
c$http$uri_vars = extract_keys(param_parts[1], /&/);
}
} }

View file

@ -10,9 +10,6 @@ redef record X509::Info += {
cert: string &log &optional; cert: string &log &optional;
}; };
## Certificates can be large and we don't want to risk truncating the output.
redef X509::default_max_field_string_bytes = 0;
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=1 event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=1
{ {
if ( ! f$info?$x509 ) if ( ! f$info?$x509 )

View file

@ -11,6 +11,7 @@
@load frameworks/analyzer/debug-logging.zeek @load frameworks/analyzer/debug-logging.zeek
@load frameworks/analyzer/detect-protocols.zeek @load frameworks/analyzer/detect-protocols.zeek
# @load frameworks/analyzer/deprecated-dpd-log.zeek
@load frameworks/analyzer/packet-segment-logging.zeek @load frameworks/analyzer/packet-segment-logging.zeek
# @load frameworks/control/controllee.zeek # @load frameworks/control/controllee.zeek
# @load frameworks/control/controller.zeek # @load frameworks/control/controller.zeek
@ -49,6 +50,8 @@
@load frameworks/management/request.zeek @load frameworks/management/request.zeek
@load frameworks/management/types.zeek @load frameworks/management/types.zeek
@load frameworks/management/util.zeek @load frameworks/management/util.zeek
# @load frameworks/dpd/detect-protocols.zeek
# @load frameworks/dpd/packet-segment-logging.zeek
@load frameworks/intel/do_notice.zeek @load frameworks/intel/do_notice.zeek
@load frameworks/intel/do_expire.zeek @load frameworks/intel/do_expire.zeek
@load frameworks/intel/whitelist.zeek @load frameworks/intel/whitelist.zeek
@ -123,6 +126,7 @@
@load protocols/ftp/detect-bruteforcing.zeek @load protocols/ftp/detect-bruteforcing.zeek
@load protocols/ftp/detect.zeek @load protocols/ftp/detect.zeek
@load protocols/ftp/software.zeek @load protocols/ftp/software.zeek
# @load protocols/http/detect-sqli.zeek
@load protocols/http/detect-sql-injection.zeek @load protocols/http/detect-sql-injection.zeek
@load protocols/http/detect-webapps.zeek @load protocols/http/detect-webapps.zeek
@load protocols/http/header-names.zeek @load protocols/http/header-names.zeek

View file

@ -1,8 +1,14 @@
@load test-all-policy.zeek @load test-all-policy.zeek
# Scripts which are commented out in test-all-policy.zeek. # Scripts which are commented out in test-all-policy.zeek.
@load frameworks/analyzer/deprecated-dpd-log.zeek
@load frameworks/conn_key/vlan_fivetuple.zeek @load frameworks/conn_key/vlan_fivetuple.zeek
# Remove in v8.1: replaced by frameworks/analyzer/detect-protocols.zeek
@pragma push ignore-deprecations
@load frameworks/dpd/detect-protocols.zeek
@pragma pop ignore-deprecations
@load protocols/ssl/decryption.zeek @load protocols/ssl/decryption.zeek
@ifdef ( Cluster::CLUSTER_BACKEND_ZEROMQ ) @ifdef ( Cluster::CLUSTER_BACKEND_ZEROMQ )
@load frameworks/cluster/backend/zeromq/connect.zeek @load frameworks/cluster/backend/zeromq/connect.zeek
@ -11,6 +17,11 @@
@load frameworks/control/controllee.zeek @load frameworks/control/controllee.zeek
@load frameworks/control/controller.zeek @load frameworks/control/controller.zeek
# Remove in v8.1: replaced by frameworks/analyzer/packet-segment-logging.zeek
@pragma push ignore-deprecations
@load frameworks/dpd/packet-segment-logging.zeek
@pragma pop ignore-deprecations
@load frameworks/management/agent/main.zeek @load frameworks/management/agent/main.zeek
@load frameworks/management/controller/main.zeek @load frameworks/management/controller/main.zeek
@load frameworks/management/node/__load__.zeek @load frameworks/management/node/__load__.zeek
@ -20,6 +31,9 @@
@load policy/misc/dump-events.zeek @load policy/misc/dump-events.zeek
@load policy/protocols/conn/speculative-service.zeek @load policy/protocols/conn/speculative-service.zeek
# Remove in v8.1: This script is deprecated and conflicts with detect-sql-injection.zeek
# @load policy/protocols/http/detect-sqli.zeek
@if ( have_spicy() ) @if ( have_spicy() )
# Loading this messes up documentation of some elements defined elsewhere. # Loading this messes up documentation of some elements defined elsewhere.
# @load frameworks/spicy/record-spicy-batch.zeek # @load frameworks/spicy/record-spicy-batch.zeek

1
src/3rdparty Submodule

@ -0,0 +1 @@
Subproject commit 22b2618417bfb587aa9183e1d7774d7fb5023ccf

View file

@ -1,771 +0,0 @@
/*===--- ConvertUTF.c - Universal Character Names conversions ---------------===
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License:
*
* University of Illinois/NCSA
* Open Source License
*
* Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
* All rights reserved.
*
* Developed by:
*
* LLVM Team
*
* University of Illinois at Urbana-Champaign
*
* http://llvm.org
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal with the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimers.
*
* * Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimers in the documentation and/or
* other materials provided with the distribution.
*
* * Neither the names of the LLVM Team, University of
* Illinois at Urbana-Champaign, nor the names of its
* contributors may be used to endorse or promote
* products derived from this Software without specific
* prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS WITH THE SOFTWARE.
*
*===------------------------------------------------------------------------=*/
/*
* Copyright © 1991-2015 Unicode, Inc. All rights reserved.
* Distributed under the Terms of Use in
* http://www.unicode.org/copyright.html.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of the Unicode data files and any associated documentation
* (the "Data Files") or Unicode software and any associated documentation
* (the "Software") to deal in the Data Files or Software
* without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, and/or sell copies of
* the Data Files or Software, and to permit persons to whom the Data Files
* or Software are furnished to do so, provided that
* (a) this copyright and permission notice appear with all copies
* of the Data Files or Software,
* (b) this copyright and permission notice appear in associated
* documentation, and
* (c) there is clear notice in each modified Data File or in the Software
* as well as in the documentation associated with the Data File(s) or
* Software that the data or software has been modified.
*
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in these Data Files or Software without prior
* written authorization of the copyright holder.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Sept 2001: fixed const & error conditions per
mods suggested by S. Parent & A. Lillich.
June 2002: Tim Dodd added detection and handling of incomplete
source sequences, enhanced error detection, added casts
to eliminate compiler warnings.
July 2003: slight mods to back out aggressive FFFE detection.
Jan 2004: updated switches in from-UTF8 conversions.
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
See the header file "ConvertUTF.h" for complete documentation.
------------------------------------------------------------------------ */
#include "ConvertUTF.h"
#ifdef CVTUTF_DEBUG
#include <stdio.h>
#endif
#include <assert.h>
static const int halfShift = 10; /* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
static const UTF32 halfMask = 0x3FFUL;
#define UNI_SUR_HIGH_START (UTF32)0xD800
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
#define false 0
#define true 1
/* --------------------------------------------------------------------- */
/*
* Index into the table below with the first byte of a UTF-8 sequence to
* get the number of trailing bytes that are supposed to follow it.
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
* left as-is for anyone who may want to do such conversion, which was
* allowed in earlier algorithms.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/*
* Magic values subtracted from a buffer value during UTF8 conversion.
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
* into the first byte, depending on how many bytes follow. There are
* as many entries in this table as there are UTF-8 sequence types.
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
* for *legal* UTF-8 will be 4 or fewer bytes total.
*/
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/* --------------------------------------------------------------------- */
/* The interface converts a whole buffer to avoid function-call overhead.
* Constants have been gathered. Loops & conditionals have been removed as
* much as possible for efficiency, in favor of drop-through switches.
* (See "Note A" at the bottom of the file for equivalent code.)
* If your compiler supports it, the "isLegalUTF8" call can be turned
* into an inline function.
*/
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
if (target >= targetEnd) {
result = targetExhausted; break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /* normal case */
}
} else if (ch > UNI_MAX_LEGAL_UTF32) {
if (flags == strictConversion) {
result = sourceIllegal;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
--source; /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF32* target = *targetStart;
UTF32 ch, ch2;
while (source < sourceEnd) {
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd) {
source = oldSource; /* Back up source pointer! */
result = targetExhausted; break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
fflush(stderr);
}
#endif
return result;
}
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
UTF32 ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/* Figure out how many bytes the result will require */
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
}
target += bytesToWrite;
if (target > targetEnd) {
source = oldSource; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
ch = *source++;
if (flags == strictConversion ) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd) {
--source; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
/*
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
* This must be called with the length pre-determined by the first byte.
* If not calling this from ConvertUTF8to*, then the length can be set by:
* length = trailingBytesForUTF8[*source]+1;
* and the sequence is illegal right away if there aren't that many bytes
* available.
* If presented with a length > 4, this returns false. The Unicode
* definition of UTF-8 goes up to 4-byte sequences.
*/
static Boolean isLegalUTF8(const UTF8 *source, int length) {
UTF8 a;
const UTF8 *srcptr = source+length;
switch (length) {
default: return false;
/* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
switch (*source) {
/* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return false; break;
case 0xED: if (a > 0x9F) return false; break;
case 0xF0: if (a < 0x90) return false; break;
case 0xF4: if (a > 0x8F) return false; break;
default: if (a < 0x80) return false;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
if (*source > 0xF4) return false;
return true;
}
/* --------------------------------------------------------------------- */
/*
* Exported function to return whether a UTF-8 sequence is legal or not.
* This is not used here; it's just exported.
*/
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
if (length > sourceEnd - source) {
return false;
}
return isLegalUTF8(source, length);
}
/* --------------------------------------------------------------------- */
static unsigned
findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source,
const UTF8 *sourceEnd) {
UTF8 b1, b2, b3;
assert(!isLegalUTF8Sequence(source, sourceEnd));
/*
* Unicode 6.3.0, D93b:
*
* Maximal subpart of an ill-formed subsequence: The longest code unit
* subsequence starting at an unconvertible offset that is either:
* a. the initial subsequence of a well-formed code unit sequence, or
* b. a subsequence of length one.
*/
if (source == sourceEnd)
return 0;
/*
* Perform case analysis. See Unicode 6.3.0, Table 3-7. Well-Formed UTF-8
* Byte Sequences.
*/
b1 = *source;
++source;
if (b1 >= 0xC2 && b1 <= 0xDF) {
/*
* First byte is valid, but we know that this code unit sequence is
* invalid, so the maximal subpart has to end after the first byte.
*/
return 1;
}
if (source == sourceEnd)
return 1;
b2 = *source;
++source;
if (b1 == 0xE0) {
return (b2 >= 0xA0 && b2 <= 0xBF) ? 2 : 1;
}
if (b1 >= 0xE1 && b1 <= 0xEC) {
return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1;
}
if (b1 == 0xED) {
return (b2 >= 0x80 && b2 <= 0x9F) ? 2 : 1;
}
if (b1 >= 0xEE && b1 <= 0xEF) {
return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1;
}
if (b1 == 0xF0) {
if (b2 >= 0x90 && b2 <= 0xBF) {
if (source == sourceEnd)
return 2;
b3 = *source;
return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
}
return 1;
}
if (b1 >= 0xF1 && b1 <= 0xF3) {
if (b2 >= 0x80 && b2 <= 0xBF) {
if (source == sourceEnd)
return 2;
b3 = *source;
return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
}
return 1;
}
if (b1 == 0xF4) {
if (b2 >= 0x80 && b2 <= 0x8F) {
if (source == sourceEnd)
return 2;
b3 = *source;
return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2;
}
return 1;
}
assert((b1 >= 0x80 && b1 <= 0xC1) || b1 >= 0xF5);
/*
* There are no valid sequences that start with these bytes. Maximal subpart
* is defined to have length 1 in these cases.
*/
return 1;
}
/* --------------------------------------------------------------------- */
/*
* Exported function to return the total number of bytes in a codepoint
* represented in UTF-8, given the value of the first byte.
*/
unsigned getNumBytesForUTF8(UTF8 first) {
return trailingBytesForUTF8[first] + 1;
}
/* --------------------------------------------------------------------- */
/*
* Exported function to return whether a UTF-8 string is legal or not.
* This is not used here; it's just exported.
*/
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd) {
while (*source != sourceEnd) {
int length = trailingBytesForUTF8[**source] + 1;
if (length > sourceEnd - *source || !isLegalUTF8(*source, length))
return false;
*source += length;
}
return true;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (extraBytesToRead >= sourceEnd - source) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (!isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /* normal case */
}
} else if (ch > UNI_MAX_UTF16) {
if (flags == strictConversion) {
result = sourceIllegal;
source -= (extraBytesToRead+1); /* return to the start */
break; /* Bail out; shouldn't continue */
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
static ConversionResult ConvertUTF8toUTF32Impl(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags,
Boolean InputIsPartial) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF32* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (extraBytesToRead >= sourceEnd - source) {
if (flags == strictConversion || InputIsPartial) {
result = sourceExhausted;
break;
} else {
result = sourceIllegal;
/*
* Replace the maximal subpart of ill-formed sequence with
* replacement character.
*/
source += findMaximalSubpartOfIllFormedUTF8Sequence(source,
sourceEnd);
*target++ = UNI_REPLACEMENT_CHAR;
continue;
}
}
if (target >= targetEnd) {
result = targetExhausted; break;
}
/* Do this check whether lenient or strict */
if (!isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
if (flags == strictConversion) {
/* Abort conversion. */
break;
} else {
/*
* Replace the maximal subpart of ill-formed sequence with
* replacement character.
*/
source += findMaximalSubpartOfIllFormedUTF8Sequence(source,
sourceEnd);
*target++ = UNI_REPLACEMENT_CHAR;
continue;
}
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6;
case 4: ch += *source++; ch <<= 6;
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (ch <= UNI_MAX_LEGAL_UTF32) {
/*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = ch;
}
} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
ConversionResult ConvertUTF8toUTF32Partial(const UTF8 **sourceStart,
const UTF8 *sourceEnd,
UTF32 **targetStart,
UTF32 *targetEnd,
ConversionFlags flags) {
return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd,
flags, /*InputIsPartial=*/true);
}
ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
const UTF8 *sourceEnd, UTF32 **targetStart,
UTF32 *targetEnd, ConversionFlags flags) {
return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd,
flags, /*InputIsPartial=*/false);
}
/* ---------------------------------------------------------------------
Note A.
The fall-through switches in UTF-8 reading code save a
temp variable, some decrements & conditionals. The switches
are equivalent to the following loop:
{
int tmpBytesToRead = extraBytesToRead+1;
do {
ch += *source++;
--tmpBytesToRead;
if (tmpBytesToRead) ch <<= 6;
} while (tmpBytesToRead > 0);
}
In UTF-8 writing code, the switches on "bytesToWrite" are
similarly unrolled loops.
--------------------------------------------------------------------- */

View file

@ -1,249 +0,0 @@
/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License:
*
* University of Illinois/NCSA
* Open Source License
*
* Copyright (c) 2003-2014 University of Illinois at Urbana-Champaign.
* All rights reserved.
*
* Developed by:
*
* LLVM Team
*
* University of Illinois at Urbana-Champaign
*
* http://llvm.org
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal with the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimers.
*
* * Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimers in the documentation and/or
* other materials provided with the distribution.
*
* * Neither the names of the LLVM Team, University of
* Illinois at Urbana-Champaign, nor the names of its
* contributors may be used to endorse or promote
* products derived from this Software without specific
* prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS WITH THE SOFTWARE.
*
*==------------------------------------------------------------------------==*/
/*
* Copyright © 1991-2015 Unicode, Inc. All rights reserved.
* Distributed under the Terms of Use in
* http://www.unicode.org/copyright.html.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of the Unicode data files and any associated documentation
* (the "Data Files") or Unicode software and any associated documentation
* (the "Software") to deal in the Data Files or Software
* without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, and/or sell copies of
* the Data Files or Software, and to permit persons to whom the Data Files
* or Software are furnished to do so, provided that
* (a) this copyright and permission notice appear with all copies
* of the Data Files or Software,
* (b) this copyright and permission notice appear in associated
* documentation, and
* (c) there is clear notice in each modified Data File or in the Software
* as well as in the documentation associated with the Data File(s) or
* Software that the data or software has been modified.
*
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in these Data Files or Software without prior
* written authorization of the copyright holder.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Header file.
Several funtions are included here, forming a complete set of
conversions between the three formats. UTF-7 is not included
here, but is handled in a separate source file.
Each of these routines takes pointers to input buffers and output
buffers. The input buffers are const.
Each routine converts the text between *sourceStart and sourceEnd,
putting the result into the buffer between *targetStart and
targetEnd. Note: the end pointers are *after* the last item: e.g.
*(sourceEnd - 1) is the last item.
!!! NOTE: The source and end pointers must be aligned properly !!!
The return result indicates whether the conversion was successful,
and if not, whether the problem was in the source or target buffers.
(Only the first encountered problem is indicated.)
After the conversion, *sourceStart and *targetStart are both
updated to point to the end of last text successfully converted in
the respective buffers.
Input parameters:
sourceStart - pointer to a pointer to the source buffer.
The contents of this are modified on return so that
it points at the next thing to be converted.
targetStart - similarly, pointer to pointer to the target buffer.
sourceEnd, targetEnd - respectively pointers to the ends of the
two buffers, for overflow checking only.
These conversion functions take a ConversionFlags argument. When this
flag is set to strict, both irregular sequences and isolated surrogates
will cause an error. When the flag is set to lenient, both irregular
sequences and isolated surrogates are converted.
Whether the flag is strict or lenient, all illegal sequences will cause
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
must check for illegal sequences.
When the flag is set to lenient, characters over 0x10FFFF are converted
to the replacement character; otherwise (when the flag is set to strict)
they constitute an error.
Output parameters:
The value "sourceIllegal" is returned from some routines if the input
sequence is malformed. When "sourceIllegal" is returned, the source
value will point to the illegal value that caused the problem. E.g.,
in UTF-8 when a sequence is malformed, it points to the start of the
malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Fixes & updates, Sept 2001.
------------------------------------------------------------------------ */
#pragma once
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
16 bits, so wchar_t is no less portable than unsigned short!
All should be unsigned values to avoid sign extension during
bit mask & shift operations.
------------------------------------------------------------------------ */
typedef unsigned int UTF32; /* at least 32 bits */
typedef unsigned short UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
typedef unsigned char Boolean; /* 0 or 1 */
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
#define UNI_MAX_BMP (UTF32)0x0000FFFF
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF
#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
typedef enum {
conversionOK, /* conversion successful */
sourceExhausted, /* partial character in source, but hit end */
targetExhausted, /* insuff. room in target for conversion */
sourceIllegal /* source sequence is illegal/malformed */
} ConversionResult;
typedef enum {
strictConversion = 0,
lenientConversion
} ConversionFlags;
/* This is for C++ and does no harm in C */
#ifdef __cplusplus
extern "C" {
#endif
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
/**
* Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
* incomplete code unit sequence, returns \c sourceExhausted.
*/
ConversionResult ConvertUTF8toUTF32Partial(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
/**
* Convert a partial UTF8 sequence to UTF32. If the sequence ends in an
* incomplete code unit sequence, returns \c sourceIllegal.
*/
ConversionResult ConvertUTF8toUTF32(
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
/* NOTE: The source and end pointers must be aligned properly. */
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
/* NOTE: The source and end pointers must be aligned properly. */
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
/* NOTE: The source and end pointers must be aligned properly. */
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
/* NOTE: The source and end pointers must be aligned properly. */
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
unsigned getNumBytesForUTF8(UTF8 firstByte);
#ifdef __cplusplus
}
#endif
/* --------------------------------------------------------------------- */

View file

@ -1,524 +0,0 @@
/* $OpenBSD: getopt_long.c,v 1.17 2004/06/03 18:46:52 millert Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define IN_GETOPT_LONG_C 1
#include <zeek/zeek-config.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#ifndef HAVE_GETOPT_LONG
# include "bsd-getopt-long.h"
# ifdef WITH_DMALLOC
# include <dmalloc.h>
# endif
int pure_opterr = 1; /* if error message should be printed */
int pure_optind = 1; /* index into parent argv vector */
int pure_optopt = '?'; /* character checked for validity */
int pure_optreset; /* reset getopt */
const char *pure_optarg; /* argument associated with option */
# define PRINT_ERROR ((pure_opterr) && (*options != ':'))
# define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
# define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
# define FLAG_LONGONLY 0x04 /* operate as pure_getopt_long_only */
/* return values */
# define BADCH (int)'?'
# define BADARG ((*options == ':') ? (int)':' : (int)'?')
# define INORDER (int)1
# define EMSG ""
static int pure_getopt_internal(int, char * const *, const char *,
const struct pure_option *, int *, int);
static int pure_parse_long_options(char * const *, const char *,
const struct pure_option *, int *, int);
static int pure_gcd(int, int);
static void pure_permute_args(int, int, int, char * const *);
static const char *pure_place = EMSG; /* option letter processing */
/* XXX: set pure_optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char *recargchar = "option requires an argument -- %c\n";
static const char *recargstring = "option requires an argument -- %s\n";
static const char *ambig = "ambiguous option -- %.*s\n";
static const char *noarg = "option doesn't take an argument -- %.*s\n";
static const char *illoptchar = "unknown option -- %c\n";
static const char *illoptstring = "unknown option -- %s\n";
/*
* Compute the greatest common divisor of a and b.
*/
static int pure_gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return b;
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void pure_permute_args(int panonopt_start, int panonopt_end,
int opt_end, char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = pure_gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* pure_parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int pure_parse_long_options(char * const *nargv, const char *options,
const struct pure_option *long_options,
int *idx, int short_too)
{
const char *current_argv, *has_equal;
size_t current_argv_len;
int i, match;
current_argv = pure_place;
match = -1;
pure_optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else {
/* ambiguous abbreviation */
if (PRINT_ERROR)
fprintf(stderr, ambig, (int)current_argv_len,
current_argv);
pure_optopt = 0;
return BADCH;
}
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
fprintf(stderr, noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets pure_optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
pure_optopt = long_options[match].val;
else
pure_optopt = 0;
return BADARG;
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
pure_optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
pure_optarg = nargv[pure_optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (pure_optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
fprintf(stderr, recargstring,
current_argv);
/*
* XXX: GNU sets pure_optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
pure_optopt = long_options[match].val;
else
pure_optopt = 0;
--pure_optind;
return BADARG;
}
} else { /* unknown option */
if (short_too) {
--pure_optind;
return -1;
}
if (PRINT_ERROR)
fprintf(stderr, illoptstring, current_argv);
pure_optopt = 0;
return BADCH;
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return 0;
} else
return long_options[match].val;
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int pure_getopt_internal(int nargc, char * const *nargv,
const char *options,
const struct pure_option *long_options,
int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return -1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
if (posixly_correct == -1)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
else if (*options == '-')
flags |= FLAG_ALLARGS;
if (*options == '+' || *options == '-')
options++;
/*
* XXX Some GNU programs (like cvs) set pure_optind to 0 instead of
* XXX using pure_optreset. Work around this braindamage.
*/
if (pure_optind == 0)
pure_optind = pure_optreset = 1;
pure_optarg = NULL;
if (pure_optreset)
nonopt_start = nonopt_end = -1;
start:
if (pure_optreset || !*pure_place) { /* update scanning pointer */
pure_optreset = 0;
if (pure_optind >= nargc) { /* end of argument vector */
pure_place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
pure_permute_args(nonopt_start, nonopt_end,
pure_optind, nargv);
pure_optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set pure_optind
* to the first of them.
*/
pure_optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return -1;
}
if (*(pure_place = nargv[pure_optind]) != '-' ||
(pure_place[1] == '\0' && strchr(options, '-') == NULL)) {
pure_place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
pure_optarg = nargv[pure_optind++];
return INORDER;
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return -1;
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = pure_optind;
else if (nonopt_end != -1) {
pure_permute_args(nonopt_start, nonopt_end,
pure_optind, nargv);
nonopt_start = pure_optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
pure_optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = pure_optind;
/*
* Check for "--" or "--foo" with no long options
* but if pure_place is simply "-" leave it unmolested.
*/
if (pure_place[1] != '\0' && *++pure_place == '-' &&
(pure_place[1] == '\0' || long_options == NULL)) {
pure_optind++;
pure_place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
pure_permute_args(nonopt_start, nonopt_end,
pure_optind, nargv);
pure_optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return -1;
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are pure_getopt_long_only()
*/
if (long_options != NULL && pure_place != nargv[pure_optind] &&
(*pure_place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*pure_place == '-')
pure_place++; /* --foo long option */
else if (*pure_place != ':' && strchr(options, *pure_place) != NULL)
short_too = 1; /* could be short option too */
optchar = pure_parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
pure_place = EMSG;
return optchar;
}
}
if ((optchar = (int) *pure_place++) == ':' ||
(optchar == '-' && *pure_place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or :').
*/
if (optchar == '-' && *pure_place == '\0')
return -1;
if (!*pure_place)
++pure_optind;
if (PRINT_ERROR)
fprintf(stderr, illoptchar, optchar);
pure_optopt = optchar;
return BADCH;
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*pure_place) /* no space */
/* NOTHING */;
else if (++pure_optind >= nargc) { /* no arg */
pure_place = EMSG;
if (PRINT_ERROR)
fprintf(stderr, recargchar, optchar);
pure_optopt = optchar;
return BADARG;
} else /* white space */
pure_place = nargv[pure_optind];
optchar = pure_parse_long_options(nargv, options, long_options,
idx, 0);
pure_place = EMSG;
return optchar;
}
if (*++oli != ':') { /* doesn't take argument */
if (!*pure_place)
++pure_optind;
} else { /* takes (optional) argument */
pure_optarg = NULL;
if (*pure_place) /* no white space */
pure_optarg = pure_place;
/* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++pure_optind >= nargc) { /* no arg */
pure_place = EMSG;
if (PRINT_ERROR)
fprintf(stderr, recargchar, optchar);
pure_optopt = optchar;
return BADARG;
} else {
pure_optarg = nargv[pure_optind];
}
}
pure_place = EMSG;
++pure_optind;
}
/* dump back option letter */
return optchar;
}
/*
* getopt --
* Parse argc/argv argument vector.
*/
int pure_getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We dont' pass FLAG_PERMUTE to pure_getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return pure_getopt_internal(nargc, nargv, options, NULL, NULL, 0);
}
/*
* pure_getopt_long --
* Parse argc/argv argument vector.
*/
int pure_getopt_long(int nargc, char * const *nargv, const char *options,
const struct pure_option *long_options, int *idx)
{
return pure_getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE);
}
/*
* pure_getopt_long_only --
* Parse argc/argv argument vector.
*/
int pure_getopt_long_only(int nargc, char * const *nargv,
const char *options,
const struct pure_option *long_options,
int *idx)
{
return pure_getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY);
}
#endif

View file

@ -1,133 +0,0 @@
/* $OpenBSD: getopt_long.c,v 1.13 2003/06/03 01:52:40 millert Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HAVE_GETOPT_LONG
/*
* GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
*/
# ifndef no_argument
# define no_argument 0
# endif
# ifndef required_argument
# define required_argument 1
# endif
# ifndef optional_argument
# define optional_argument 2
# endif
struct pure_option {
/* name of long option */
const char *name;
/*
* one of no_argument, required_argument, and optional_argument:
* whether option takes an argument
*/
int has_arg;
/* if not NULL, set *flag to val when option found */
int *flag;
/* if flag not NULL, value to set *flag to; else return value */
int val;
};
#ifdef __cplusplus
extern "C" {
#endif
int pure_getopt_long(int nargc, char * const *nargv, const char *options,
const struct pure_option *long_options, int *idx);
int pure_getopt_long_only(int nargc, char * const *nargv,
const char *options,
const struct pure_option *long_options,
int *idx);
int pure_getopt(int nargc, char * const *nargv, const char *options);
extern const char *pure_optarg; /* getopt(3) external variables */
extern int pure_opterr;
extern int pure_optind;
extern int pure_optopt;
extern int pure_optreset;
#ifdef __cplusplus
}
#endif
/* prefix+macros just to avoid clashes with existing getopt() implementations */
# ifndef IN_GETOPT_LONG_C
# undef option
# define option pure_option
# undef getopt_long
# define getopt_long(A, B, C, D, E) pure_getopt_long(A, B, C, D, E)
# undef getopt_long_only
# define getopt_long_only(A, B, C, D, E) pure_getopt_long_only(A, B, C, D, E)
# undef getopt
# define getopt(A, B, C) pure_getopt(A, B, C)
# undef optarg
# define optarg pure_optarg
# undef opterr
# define opterr pure_opterr
# undef optind
# define optind pure_optind
# undef optopt
# define optopt pure_optopt
# undef optreset
# define optreset pure_optreset
# endif
#endif

7138
src/3rdparty/doctest.h vendored

File diff suppressed because it is too large Load diff

View file

@ -1,141 +0,0 @@
// Modified from tcpdump v4.9.3's in_cksum.c (which itself was a modified
// version of FreeBSD's in_cksum.c).
/* in_cksum.c
* 4.4-Lite-2 Internet checksum routine, modified to take a vector of
* pointers/lengths giving the pieces to be checksummed. Also using
* Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version.
*/
/*
* Copyright (c) 1988, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
*/
#include "zeek/net_util.h"
namespace zeek::detail {
#define ADDCARRY(x) {if ((x) > 65535) (x) -= 65535;}
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
uint16_t in_cksum(const struct checksum_block *vec, int veclen)
{
const uint16_t *w;
int sum = 0;
int mlen = 0;
int byte_swapped = 0;
union {
uint8_t c[2];
uint16_t s;
} s_util;
union {
uint16_t s[2];
uint32_t l;
} l_util;
for (; veclen != 0; vec++, veclen--) {
if (vec->len == 0)
continue;
w = reinterpret_cast<const uint16_t *>(vec->block);
if (mlen == -1) {
/*
* The first byte of this chunk is the continuation
* of a word spanning between this chunk and the
* last chunk.
*
* s_util.c[0] is already saved when scanning previous
* chunk.
*/
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
w = reinterpret_cast<const uint16_t *>((const uint8_t *)w + 1);
mlen = vec->len - 1;
} else
mlen = vec->len;
/*
* Force to even boundary.
*/
if ((1 & (uintptr_t) w) && (mlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(const uint8_t *)w;
w = reinterpret_cast<const uint16_t *>((const uint8_t *)w + 1);
mlen--;
byte_swapped = 1;
}
/*
* Unroll the loop to make overhead from
* branches &c small.
*/
while ((mlen -= 32) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
w += 16;
}
mlen += 32;
while ((mlen -= 8) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
w += 4;
}
mlen += 8;
if (mlen == 0 && byte_swapped == 0)
continue;
REDUCE;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
REDUCE;
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(const uint8_t *)w;
}
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
or not as determined by endian-ness of the machine) */
s_util.c[1] = 0;
sum += s_util.s;
}
REDUCE;
return sum;
}
} // namespace zeek

View file

@ -1,153 +0,0 @@
// Copied from https://github.com/josuttis/jthread,
// used under CC-BY-4.0.
// -----------------------------------------------------
// cooperative interruptable and joining thread:
// -----------------------------------------------------
#ifndef JTHREAD_HPP
#define JTHREAD_HPP
#include <functional> // for invoke()
#include <future>
#include <iostream> // for debugging output
#include <thread>
#include <type_traits>
#include "stop_token.hpp"
namespace nonstd {
//*****************************************
//* class jthread
//* - joining std::thread with signaling stop/end support
//*****************************************
class jthread {
public:
//*****************************************
//* standardized API:
//*****************************************
// - cover full API of std::thread
// to be able to switch from std::thread to std::jthread
// types are those from std::thread:
using id = ::std::thread::id;
using native_handle_type = ::std::thread::native_handle_type;
// construct/copy/destroy:
jthread() noexcept;
// template <typename F, typename... Args> explicit jthread(F&& f, Args&&... args);
// THE constructor that starts the thread:
// - NOTE: does SFINAE out copy constructor semantics
template<typename Callable, typename... Args,
typename = ::std::enable_if_t<! ::std::is_same_v<::std::decay_t<Callable>, jthread>>>
explicit jthread(Callable&& cb, Args&&... args);
~jthread();
jthread(const jthread&) = delete;
jthread(jthread&&) noexcept = default;
jthread& operator=(const jthread&) = delete;
jthread& operator=(jthread&&) noexcept;
// members:
void swap(jthread&) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
native_handle_type native_handle();
// static members:
static unsigned hardware_concurrency() noexcept { return ::std::thread::hardware_concurrency(); };
//*****************************************
// - supplementary API:
// - for the calling thread:
[[nodiscard]] stop_source get_stop_source() noexcept;
[[nodiscard]] stop_token get_stop_token() const noexcept;
bool request_stop() noexcept { return get_stop_source().request_stop(); }
//*****************************************
//* implementation:
//*****************************************
private:
//*** API for the starting thread:
stop_source _stopSource; // stop_source for started thread
::std::thread _thread{}; // started thread (if any)
};
//**********************************************************************
//*****************************************
//* implementation of class jthread
//*****************************************
// default constructor:
inline jthread::jthread() noexcept : _stopSource{nostopstate} {}
// THE constructor that starts the thread:
// - NOTE: declaration does SFINAE out copy constructor semantics
template<typename Callable, typename... Args, typename>
inline jthread::jthread(Callable&& cb, Args&&... args)
: _stopSource{}, // initialize stop_source
_thread{
[](stop_token st, auto&& cb, auto&&... args) { // called lambda in the thread
// perform tasks of the thread:
if constexpr ( std::is_invocable_v<Callable, stop_token, Args...> ) {
// pass the stop_token as first argument to the started thread:
::std::invoke(::std::forward<decltype(cb)>(cb), std::move(st),
::std::forward<decltype(args)>(args)...);
}
else {
// started thread does not expect a stop token:
::std::invoke(::std::forward<decltype(cb)>(cb), ::std::forward<decltype(args)>(args)...);
}
},
_stopSource.get_token(), // not captured due to possible races if immediately set
::std::forward<Callable>(cb), // pass callable
::std::forward<Args>(args)... // pass arguments for callable
} {}
// move assignment operator:
inline jthread& jthread::operator=(jthread&& t) noexcept {
if ( joinable() ) { // if not joined/detached, signal stop and wait for end:
request_stop();
join();
}
_thread = std::move(t._thread);
_stopSource = std::move(t._stopSource);
return *this;
}
// destructor:
inline jthread::~jthread() {
if ( joinable() ) { // if not joined/detached, signal stop and wait for end:
request_stop();
join();
}
}
// others:
inline bool jthread::joinable() const noexcept { return _thread.joinable(); }
inline void jthread::join() { _thread.join(); }
inline void jthread::detach() { _thread.detach(); }
inline typename jthread::id jthread::get_id() const noexcept { return _thread.get_id(); }
inline typename jthread::native_handle_type jthread::native_handle() { return _thread.native_handle(); }
inline stop_source jthread::get_stop_source() noexcept { return _stopSource; }
inline stop_token jthread::get_stop_token() const noexcept { return _stopSource.get_token(); }
inline void jthread::swap(jthread& t) noexcept {
std::swap(_stopSource, t._stopSource);
std::swap(_thread, t._thread);
}
} // namespace nonstd
#endif // JTHREAD_HPP

View file

@ -1,527 +0,0 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */
#include "modp_numtoa.h"
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <float.h>
// other interesting references on num to string convesion
// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
// and http://www.ddj.com/dept/cpp/184401596?pgno=6
// Version 19-Nov-2007
// Fixed round-to-even rules to match printf
// thanks to Johannes Otepka
/**
* Powers of 10
* 10^0 to 10^9
*/
static const double _pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000};
static const double _pow10r[] = {1, .1, .01, .001, .0001, .00001, .000001,
.0000001, .00000001, .000000001};
static void strreverse(char* begin, char* end)
{
char aux;
while (end > begin)
aux = *end, *end-- = *begin, *begin++ = aux;
}
// Expects 'str' to have been made using "%e" scientific notation format string
// Returns the number of characters removed
static size_t sn_strip_trailing_zeros(char* str)
{
char* frac = 0;
for ( ; ; )
{
if ( *str == '.' )
{
frac = str + 1;
break;
}
if ( *str == 0 )
break;
++str;
}
if ( ! frac )
return 0;
char* start_dec = frac;
char* exp = 0;
char* trailing_zeros = 0;
for ( ; ; )
{
if ( *frac == 0 )
break;
if ( *frac == 'e' )
{
exp = frac;
break;
}
if ( *frac == '0' )
{
if ( ! trailing_zeros )
trailing_zeros = frac;
}
else
trailing_zeros = 0;
++frac;
}
if ( trailing_zeros == start_dec )
--trailing_zeros;
if ( ! trailing_zeros || ! exp )
return 0;
char* start_exp = exp;
for ( ; ; )
{
*trailing_zeros = *exp;
if ( *exp == 0 )
break;
++trailing_zeros;
++exp;
}
return exp - start_exp;
}
size_t modp_itoa10(int32_t value, char* str)
{
char* wstr=str;
// Take care of sign
unsigned int uvalue = (value < 0) ? -value : value;
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
if (value < 0) *wstr++ = '-';
*wstr='\0';
// Reverse string
strreverse(str,wstr-1);
return wstr - str;
}
size_t modp_uitoa10(uint32_t value, char* str)
{
char* wstr=str;
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (value % 10)); while (value /= 10);
*wstr='\0';
// Reverse string
strreverse(str, wstr-1);
return wstr - str;
}
size_t modp_litoa10(int64_t value, char* str)
{
char* wstr=str;
uint64_t uvalue = (value < 0) ? (value == INT64_MIN ? (uint64_t)(INT64_MAX) + 1 : -value) : value;
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
if (value < 0) *wstr++ = '-';
*wstr='\0';
// Reverse string
strreverse(str,wstr-1);
return wstr - str;
}
size_t modp_ulitoa10(uint64_t value, char* str)
{
char* wstr=str;
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (value % 10)); while (value /= 10);
*wstr='\0';
// Reverse string
strreverse(str, wstr-1);
return wstr - str;
}
size_t modp_dtoa(double value, char* str, int prec)
{
/* Hacky test for NaN
* under -fast-math this won't work, but then you also won't
* have correct nan values anyways. The alternative is
* to link with libmath (bad) or hack IEEE double bits (bad)
*/
if (! (value == value)) {
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
return 3;
}
/* we'll work in positive values and deal with the
negative sign issue later */
int neg = 0;
if (value < 0) {
neg = 1;
value = -value;
}
/* if input is larger than thres_max, revert to exponential */
const double thres_max = (double)(INT_MAX);
/* for very large numbers switch back to native sprintf for exponentials.
anyone want to write code to replace this? */
/*
normal printf behavior is to print EVERY whole number digit
which can be 100s of characters overflowing your buffers == bad
*/
if (value >= thres_max) {
#pragma GCC diagnostic push
// Ignore the diagnostic warning about sprintf being deprecated here. We
// have to assume that the size of the string is long enough here
// because we'd have to change the function definition to support
// passing a length.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
#pragma GCC diagnostic pop
n -= sn_strip_trailing_zeros(str);
return n;
}
double diff = 0.0;
char* wstr = str;
if (prec < 0) {
prec = 0;
} else if (prec > 9) {
/* precision of >= 10 can lead to overflow errors */
prec = 9;
}
int whole = (int) value;
double tmp = (value - whole) * _pow10[prec];
uint32_t frac = (uint32_t)(tmp);
diff = tmp - frac;
if (diff > 0.5) {
++frac;
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
if (frac >= _pow10[prec]) {
frac = 0;
++whole;
}
} else if (diff == 0.5 && ((frac == 0) || (frac & 1))) {
/* if halfway, round up if odd, OR
if last digit is 0. That last part is strange */
++frac;
}
if (prec == 0) {
diff = value - whole;
if (diff > 0.5) {
/* greater than 0.5, round up, e.g. 1.6 -> 2 */
++whole;
} else if (diff == 0.5 && (whole & 1)) {
/* exactly 0.5 and ODD, then round up */
/* 1.5 -> 2, but 2.5 -> 2 */
++whole;
}
} else {
int count = prec;
// now do fractional part, as an unsigned number
do {
--count;
*wstr++ = (char)(48 + (frac % 10));
} while (frac /= 10);
// add extra 0s
while (count-- > 0) *wstr++ = '0';
// add decimal
*wstr++ = '.';
}
// do whole part
// Take care of sign
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10);
if (neg) {
*wstr++ = '-';
}
*wstr='\0';
strreverse(str, wstr-1);
return wstr - str;
}
// This is near identical to modp_dtoa above
// The differnce is noted below
size_t modp_dtoa2(double value, char* str, int prec)
{
/* Hacky test for NaN
* under -fast-math this won't work, but then you also won't
* have correct nan values anyways. The alternative is
* to link with libmath (bad) or hack IEEE double bits (bad)
*/
if (! (value == value)) {
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
return 3;
}
/* we'll work in positive values and deal with the
negative sign issue later */
int neg = 0;
if (value < 0) {
neg = 1;
value = -value;
}
/* if input is larger than thres_max, revert to exponential */
const double thres_max = (double)(INT_MAX);
/* for very large numbers switch back to native sprintf for exponentials.
anyone want to write code to replace this? */
/*
normal printf behavior is to print EVERY whole number digit
which can be 100s of characters overflowing your buffers == bad
*/
if (value >= thres_max) {
#pragma GCC diagnostic push
// Ignore the diagnostic warning about sprintf being deprecated here. We
// have to assume that the size of the string is long enough here
// because we'd have to change the function definition to support
// passing a length.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
#pragma GCC diagnostic pop
n -= sn_strip_trailing_zeros(str);
return n;
}
int count;
double diff = 0.0;
char* wstr = str;
if (prec < 0) {
prec = 0;
} else if (prec > 9) {
/* precision of >= 10 can lead to overflow errors */
prec = 9;
}
double smallest = _pow10r[prec];
if (value != 0.0 && value < smallest) {
#pragma GCC diagnostic push
// Ignore the diagnostic warning about sprintf being deprecated here. We
// have to assume that the size of the string is long enough here
// because we'd have to change the function definition to support
// passing a length.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int n = sprintf(str, "%.*e", DBL_DECIMAL_DIG - 1, neg ? -value : value);
#pragma GCC diagnostic pop
n -= sn_strip_trailing_zeros(str);
return n;
}
int whole = (int) value;
double tmp = (value - whole) * _pow10[prec];
uint32_t frac = (uint32_t)(tmp);
diff = tmp - frac;
if (diff > 0.5) {
++frac;
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
if (frac >= _pow10[prec]) {
frac = 0;
++whole;
}
} else if (diff == 0.5 && ((frac == 0) || (frac & 1))) {
/* if halfway, round up if odd, OR
if last digit is 0. That last part is strange */
++frac;
}
if (prec == 0) {
diff = value - whole;
if (diff > 0.5) {
/* greater than 0.5, round up, e.g. 1.6 -> 2 */
++whole;
} else if (diff == 0.5 && (whole & 1)) {
/* exactly 0.5 and ODD, then round up */
/* 1.5 -> 2, but 2.5 -> 2 */
++whole;
}
//vvvvvvvvvvvvvvvvvvv Diff from modp_dto2
} else if (frac) {
count = prec;
// now do fractional part, as an unsigned number
// we know it is not 0 but we can have leading zeros, these
// should be removed
while (!(frac % 10)) {
--count;
frac /= 10;
}
//^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2
// now do fractional part, as an unsigned number
do {
--count;
*wstr++ = (char)(48 + (frac % 10));
} while (frac /= 10);
// add extra 0s
while (count-- > 0) *wstr++ = '0';
// add decimal
*wstr++ = '.';
}
// do whole part
// Take care of sign
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10);
if (neg) {
*wstr++ = '-';
}
*wstr='\0';
strreverse(str, wstr-1);
return wstr - str;
}
// This is near identical to modp_dtoa2 above, excep that it never uses
// exponential notation and requires a buffer length.
size_t modp_dtoa3(double value, char* str, int n, int prec)
{
/* Hacky test for NaN
* under -fast-math this won't work, but then you also won't
* have correct nan values anyways. The alternative is
* to link with libmath (bad) or hack IEEE double bits (bad)
*/
if (! (value == value)) {
str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
return 3;
}
/* we'll work in positive values and deal with the
negative sign issue later */
int neg = 0;
if (value < 0) {
neg = 1;
value = -value;
}
if (prec < 0) {
prec = 0;
} else if (prec > 9) {
/* precision of >= 10 can lead to overflow errors */
prec = 9;
}
/* if input is larger than thres_max, revert to exponential */
const double thres_max = (double)(INT_MAX);
/* for very large numbers switch back to native sprintf for exponentials.
anyone want to write code to replace this? */
/*
normal printf behavior is to print EVERY whole number digit
which can be 100s of characters overflowing your buffers == bad
*/
if (value >= thres_max) {
/* ---- Modified part, compared to modp_dtoa3. */
int i = snprintf(str, n, "%.*f", prec, neg ? -value : value);
if ( i < 0 || i >= n ) {
// Error or truncated output.
snprintf(str, n, "NAN");
return 3;
}
/* Remove trailing zeros. */
char* p;
for ( p = str + i - 1; p >= str && *p == '0'; --p );
if ( p >= str && *p == '.' )
--p;
*++p = '\0';
return p - str - 1;
/* ---- End of modified part.. */
}
int count;
double diff = 0.0;
char* wstr = str;
int whole = (int) value;
double tmp = (value - whole) * _pow10[prec];
uint32_t frac = (uint32_t)(tmp);
diff = tmp - frac;
if (diff > 0.5) {
++frac;
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
if (frac >= _pow10[prec]) {
frac = 0;
++whole;
}
} else if (diff == 0.5 && ((frac == 0) || (frac & 1))) {
/* if halfway, round up if odd, OR
if last digit is 0. That last part is strange */
++frac;
}
if (prec == 0) {
diff = value - whole;
if (diff > 0.5) {
/* greater than 0.5, round up, e.g. 1.6 -> 2 */
++whole;
} else if (diff == 0.5 && (whole & 1)) {
/* exactly 0.5 and ODD, then round up */
/* 1.5 -> 2, but 2.5 -> 2 */
++whole;
}
//vvvvvvvvvvvvvvvvvvv Diff from modp_dto2
} else if (frac) {
count = prec;
// now do fractional part, as an unsigned number
// we know it is not 0 but we can have leading zeros, these
// should be removed
while (!(frac % 10)) {
--count;
frac /= 10;
}
//^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2
// now do fractional part, as an unsigned number
do {
--count;
*wstr++ = (char)(48 + (frac % 10));
} while (frac /= 10);
// add extra 0s
while (count-- > 0) *wstr++ = '0';
// add decimal
*wstr++ = '.';
}
// do whole part
// Take care of sign
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10);
if (neg) {
*wstr++ = '-';
}
*wstr='\0';
strreverse(str, wstr-1);
return wstr - str;
}

View file

@ -1,116 +0,0 @@
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */
/**
* \file
*
* <pre>
* Copyright &copy; 2007, Nick Galbreath -- nickg [at] modp [dot] com
* All rights reserved.
* http://code.google.com/p/stringencoders/
* Released under the bsd license.
* </pre>
*
* This defines signed/unsigned integer, and 'double' to char buffer
* converters. The standard way of doing this is with "sprintf", however
* these functions are
* * guarenteed maximum size output
* * 5-20x faster!
* * core-dump safe
*
*
*/
#pragma once
#ifdef __cplusplus
#define BEGIN_C extern "C" {
#define END_C }
#else
#define BEGIN_C
#define END_C
#endif
BEGIN_C
#include <stdint.h>
#include <stddef.h>
/** \brief convert an signed integer to char buffer, return # characters added
*
* \param[in] value
* \param[out] buf the output buffer. Should be 16 chars or more.
*/
size_t modp_itoa10(int32_t value, char* buf);
/** \brief convert an unsigned integer to char buffer, return # characters added
*
* \param[in] value
* \param[out] buf The output buffer, should be 16 chars or more.
*/
size_t modp_uitoa10(uint32_t value, char* buf);
/** \brief convert an signed long integer to char buffer, return # characters added
*
* \param[in] value
* \param[out] buf the output buffer. Should be 24 chars or more.
*/
size_t modp_litoa10(int64_t value, char* buf);
/** \brief convert an unsigned long integer to char buffer, return # characters added
*
* \param[in] value
* \param[out] buf The output buffer, should be 24 chars or more.
*/
size_t modp_ulitoa10(uint64_t value, char* buf);
/** \brief convert a floating point number to char buffer with
* fixed-precision format, return # characters added
*
* This is similar to "%.[0-9]f" in the printf style. It will include
* trailing zeros
*
* If the input value is greater than 1<<31, then the output format
* will be switched exponential format and include as many precision digits
* as needed to preserve information.
*
* \param[in] value
* \param[out] buf The allocated output buffer. Should be 32 chars or more.
* \param[in] precision Number of digits to the right of the decimal point.
* Can only be 0-9.
*/
size_t modp_dtoa(double value, char* buf, int precision);
/** \brief convert a floating point number to char buffer with a
* variable-precision format, and no trailing zero, return
* number of characters added
*
* This is similar to "%.[0-9]f" in the printf style, except it will
* NOT include trailing zeros after the decimal point. This type
* of format oddly does not exists with printf.
*
* If the input value is greater than 1<<31, then the output format
* will be switched exponential format and include as many precision digits
* as needed to preserve information.
*
* If a non-zero input value is less than 10^(-precision), the output format
* will be switched exponential format and include as many precision digits
* as needed to preserve information.
*
* \param[in] value
* \param[out] buf The allocated output buffer. Should be 32 chars or more.
* \param[in] precision Number of digits to the right of the decimal point.
* Can only be 0-9.
*/
size_t modp_dtoa2(double value, char* buf, int precision);
/** \brief convert a floating point number to char buffer with a
* variable-precision format, no trailing zeros, and no
* scientific notation, return number of characters added
*
* Other than avoiding scientific notation, this is the same as mop_dtoa2. It does however
* require the max buffer length. The buffer will always be null-terminated.
*/
size_t modp_dtoa3(double value, char* buf, int n, int precision);
END_C

1103
src/3rdparty/patricia.c vendored

File diff suppressed because it is too large Load diff

View file

@ -1,209 +0,0 @@
/*
* $Id: patricia.h,v 1.6 2005/12/07 20:53:01 dplonka Exp $
* Dave Plonka <plonka@doit.wisc.edu>
*
* This product includes software developed by the University of Michigan,
* Merit Network, Inc., and their contributors.
*
* This file had been called "radix.h" in the MRT sources.
*
* I renamed it to "patricia.h" since it's not an implementation of a general
* radix trie. Also, pulled in various requirements from "mrt.h" and added
* some other things it could be used as a standalone API.
*/
/*
* This code originates from Dave Plonka's Net::Security perl module. An
* adaptation of it in C is kept at
* https://github.com/CAIDA/cc-common/tree/master/libpatricia. That repository
* is considered the upstream version for Zeek's fork. We make some custom
* changes to this upstream:
* - Replace void_fn_t with data_fn_t and prefix_data_fn_t
* - Add patricia_search_all method
*
* The current version is based on commit
* fd262ab5ac5bae8b0d4a8b5e2e723115b1846376 from that repo.
*/
/* From copyright.txt:
*
* Copyright (c) 1997, 1998, 1999
*
*
* The Regents of the University of Michigan ("The Regents") and Merit Network,
* Inc. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* 3. All advertising materials mentioning features or use of
* this software must display the following acknowledgement:
* This product includes software developed by the University of Michigan, Merit
* Network, Inc., and their contributors.
* 4. Neither the name of the University, Merit Network, nor the
* names of their contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PATRICIA_H
#define _PATRICIA_H
#define HAVE_IPV6
/* typedef unsigned int u_int; */
typedef void (*void_fn_t)();
/* { from defs.h */
#define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin)
#define MAXLINE 1024
#define BIT_TEST(f, b) ((f) & (b))
/* } */
#define addroute make_and_lookup
#include <sys/types.h> /* for u_* definitions (on FreeBSD 5) */
#include <errno.h> /* for EAFNOSUPPORT */
#ifndef EAFNOSUPPORT
#defined EAFNOSUPPORT WSAEAFNOSUPPORT
#include <winsock.h>
#else
#include <netinet/in.h> /* for struct in_addr */
#endif
#include <sys/socket.h> /* for AF_INET */
/* { from mrt.h */
typedef struct _prefix4_t {
u_short family; /* AF_INET | AF_INET6 */
u_short bitlen; /* same as mask? */
int ref_count; /* reference count */
struct in_addr sin;
} prefix4_t;
typedef struct _prefix_t {
u_short family; /* AF_INET | AF_INET6 */
u_short bitlen; /* same as mask? */
int ref_count; /* reference count */
union {
struct in_addr sin;
#ifdef HAVE_IPV6
struct in6_addr sin6;
#endif /* IPV6 */
} add;
} prefix_t;
typedef void (*data_fn_t)(void *);
typedef void (*prefix_data_fn_t)(prefix_t *, void *);
/* } */
typedef struct _patricia_node_t {
u_int bit; /* flag if this node used */
prefix_t *prefix; /* who we are in patricia tree */
struct _patricia_node_t *l, *r; /* left and right children */
struct _patricia_node_t *parent; /* may be used */
void *data; /* pointer to data */
void *user1; /* pointer to usr data (ex. route flap info) */
} patricia_node_t;
typedef struct _patricia_tree_t {
patricia_node_t *head;
u_int maxbits; /* for IP, 32 bit addresses */
int num_active_node; /* for debug purpose */
} patricia_tree_t;
patricia_node_t *patricia_search_exact(patricia_tree_t *patricia,
prefix_t *prefix);
int patricia_search_all(patricia_tree_t *patricia, prefix_t *prefix,
patricia_node_t ***list, int *n);
patricia_node_t *patricia_search_best(patricia_tree_t *patricia,
prefix_t *prefix);
patricia_node_t *patricia_search_best2(patricia_tree_t *patricia,
prefix_t *prefix, int inclusive);
patricia_node_t *patricia_lookup(patricia_tree_t *patricia, prefix_t *prefix);
void patricia_remove(patricia_tree_t *patricia, patricia_node_t *node);
patricia_tree_t *New_Patricia(int maxbits);
void Clear_Patricia(patricia_tree_t *patricia, data_fn_t func);
void Destroy_Patricia(patricia_tree_t *patricia, data_fn_t func);
void patricia_process(patricia_tree_t *patricia, prefix_data_fn_t func);
void Deref_Prefix(prefix_t *prefix);
char *prefix_toa(prefix_t *prefix);
/* { from demo.c */
prefix_t *ascii2prefix(int family, char *string);
patricia_node_t *make_and_lookup(patricia_tree_t *tree, char *string);
/* } */
#define PATRICIA_MAXBITS (sizeof(struct in6_addr) * 8)
#define PATRICIA_NBIT(x) (0x80 >> ((x)&0x7f))
#define PATRICIA_NBYTE(x) ((x) >> 3)
#define PATRICIA_DATA_GET(node, type) (type *)((node)->data)
#define PATRICIA_DATA_SET(node, value) ((node)->data = (void *)(value))
#define PATRICIA_WALK(Xhead, Xnode) \
do { \
patricia_node_t *Xstack[PATRICIA_MAXBITS + 1]; \
patricia_node_t **Xsp = Xstack; \
patricia_node_t *Xrn = (Xhead); \
while ((Xnode = Xrn)) { \
if (Xnode->prefix)
#define PATRICIA_WALK_ALL(Xhead, Xnode) \
do { \
patricia_node_t *Xstack[PATRICIA_MAXBITS + 1]; \
patricia_node_t **Xsp = Xstack; \
patricia_node_t *Xrn = (Xhead); \
while ((Xnode = Xrn)) { \
if (1)
#define PATRICIA_WALK_BREAK \
{ \
if (Xsp != Xstack) { \
Xrn = *(--Xsp); \
} else { \
Xrn = (patricia_node_t *)0; \
} \
continue; \
}
#define PATRICIA_WALK_END \
if (Xrn->l) { \
if (Xrn->r) { \
*Xsp++ = Xrn->r; \
} \
Xrn = Xrn->l; \
} else if (Xrn->r) { \
Xrn = Xrn->r; \
} else if (Xsp != Xstack) { \
Xrn = *(--Xsp); \
} else { \
Xrn = (patricia_node_t *)0; \
} \
} \
} \
while (0)
#endif /* _PATRICIA_H */

View file

@ -1,52 +0,0 @@
/*
* See the file "COPYING" in the main distribution directory for copyright.
*/
#include "zeek/zeek-config.h" /* must appear before first ifdef */
#include <sys/types.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <signal.h>
#ifdef HAVE_SIGACTION
#include <string.h>
#endif
#include "setsignal.h"
/*
* An os independent signal() with BSD semantics, e.g. the signal
* catcher is restored following service of the signal.
*
* When sigset() is available, signal() has SYSV semantics and sigset()
* has BSD semantics and call interface. Unfortunately, Linux does not
* have sigset() so we use the more complicated sigaction() interface
* there.
*
* Did I mention that signals suck?
*/
RETSIGTYPE
(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
{
#ifdef HAVE_SIGACTION
struct sigaction old, new;
memset(&new, 0, sizeof(new));
new.sa_handler = func;
#ifdef SA_RESTART
new.sa_flags |= SA_RESTART;
#endif
if (sigaction(sig, &new, &old) < 0)
return (SIG_ERR);
return (old.sa_handler);
#else
#ifdef HAVE_SIGSET
return (sigset(sig, func));
#else
return (signal(sig, func));
#endif
#endif
}

View file

@ -1,7 +0,0 @@
/*
* See the file "COPYING" in the main distribution directory for copyright.
*
*/
#pragma once
RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int);

260488
src/3rdparty/sqlite3.c vendored

File diff suppressed because it is too large Load diff

13583
src/3rdparty/sqlite3.h vendored

File diff suppressed because it is too large Load diff

View file

@ -1,510 +0,0 @@
// Copied from https://github.com/josuttis/jthread,
// used under CC-BY-4.0.
#pragma once
// <stop_token> header
#include <atomic>
#include <thread>
#include <type_traits>
#include <utility>
#ifdef SAFE
#include <iostream>
#endif
#if defined(__x86_64__) || defined(_M_X64)
#include <immintrin.h>
#endif
namespace nonstd {
inline void __spin_yield() noexcept {
// TODO: Platform-specific code here
#if defined(__x86_64__) || defined(_M_X64)
_mm_pause();
#endif
}
//-----------------------------------------------
// internal types for shared stop state
//-----------------------------------------------
struct __stop_callback_base {
void (*__callback_)(__stop_callback_base*) = nullptr;
__stop_callback_base* __next_ = nullptr;
__stop_callback_base** __prev_ = nullptr;
bool* __isRemoved_ = nullptr;
std::atomic<bool> __callbackFinishedExecuting_{false};
void __execute() noexcept { __callback_(this); }
protected:
// it shall only by us who deletes this
// (workaround for virtual __execute() and destructor)
~__stop_callback_base() = default;
};
struct __stop_state {
public:
void __add_token_reference() noexcept { __state_.fetch_add(__token_ref_increment, std::memory_order_relaxed); }
void __remove_token_reference() noexcept {
auto __oldState = __state_.fetch_sub(__token_ref_increment, std::memory_order_acq_rel);
if ( __oldState < (__token_ref_increment + __source_ref_increment) ) {
delete this;
}
}
void __add_source_reference() noexcept { __state_.fetch_add(__source_ref_increment, std::memory_order_relaxed); }
void __remove_source_reference() noexcept {
auto __oldState = __state_.fetch_sub(__source_ref_increment, std::memory_order_acq_rel);
if ( __oldState < (__token_ref_increment + __source_ref_increment) ) {
delete this;
}
}
bool __request_stop() noexcept {
if ( ! __try_lock_and_signal_until_signalled() ) {
// Stop has already been requested.
return false;
}
// Set the 'stop_requested' signal and acquired the lock.
__signallingThread_ = std::this_thread::get_id();
while ( __head_ != nullptr ) {
// Dequeue the head of the queue
auto* __cb = __head_;
__head_ = __cb->__next_;
const bool anyMore = __head_ != nullptr;
if ( anyMore ) {
__head_->__prev_ = &__head_;
}
// Mark this item as removed from the list.
__cb->__prev_ = nullptr;
// Don't hold lock while executing callback
// so we don't block other threads from deregistering callbacks.
__unlock();
// TRICKY: Need to store a flag on the stack here that the callback
// can use to signal that the destructor was executed inline
// during the call. If the destructor was executed inline then
// it's not safe to dereference __cb after __execute() returns.
// If the destructor runs on some other thread then the other
// thread will block waiting for this thread to signal that the
// callback has finished executing.
bool __isRemoved = false;
__cb->__isRemoved_ = &__isRemoved;
__cb->__execute();
if ( ! __isRemoved ) {
__cb->__isRemoved_ = nullptr;
__cb->__callbackFinishedExecuting_.store(true, std::memory_order_release);
}
if ( ! anyMore ) {
// This was the last item in the queue when we dequeued it.
// No more items should be added to the queue after we have
// marked the state as interrupted, only removed from the queue.
// Avoid acquring/releasing the lock in this case.
return true;
}
__lock();
}
__unlock();
return true;
}
bool __is_stop_requested() noexcept { return __is_stop_requested(__state_.load(std::memory_order_acquire)); }
bool __is_stop_requestable() noexcept { return __is_stop_requestable(__state_.load(std::memory_order_acquire)); }
bool __try_add_callback(__stop_callback_base* __cb, bool __incrementRefCountIfSuccessful) noexcept {
std::uint64_t __oldState;
goto __load_state;
do {
goto __check_state;
do {
__spin_yield();
__load_state:
__oldState = __state_.load(std::memory_order_acquire);
__check_state:
if ( __is_stop_requested(__oldState) ) {
__cb->__execute();
return false;
}
else if ( ! __is_stop_requestable(__oldState) ) {
return false;
}
} while ( __is_locked(__oldState) );
} while ( ! __state_.compare_exchange_weak(__oldState, __oldState | __locked_flag, std::memory_order_acquire) );
// Push callback onto callback list.
__cb->__next_ = __head_;
if ( __cb->__next_ != nullptr ) {
__cb->__next_->__prev_ = &__cb->__next_;
}
__cb->__prev_ = &__head_;
__head_ = __cb;
if ( __incrementRefCountIfSuccessful ) {
__unlock_and_increment_token_ref_count();
}
else {
__unlock();
}
// Successfully added the callback.
return true;
}
void __remove_callback(__stop_callback_base* __cb) noexcept {
__lock();
if ( __cb->__prev_ != nullptr ) {
// Still registered, not yet executed
// Just remove from the list.
*__cb->__prev_ = __cb->__next_;
if ( __cb->__next_ != nullptr ) {
__cb->__next_->__prev_ = __cb->__prev_;
}
__unlock_and_decrement_token_ref_count();
return;
}
__unlock();
// Callback has either already executed or is executing
// concurrently on another thread.
if ( __signallingThread_ == std::this_thread::get_id() ) {
// Callback executed on this thread or is still currently executing
// and is deregistering itself from within the callback.
if ( __cb->__isRemoved_ != nullptr ) {
// Currently inside the callback, let the __request_stop() method
// know the object is about to be destructed and that it should
// not try to access the object when the callback returns.
*__cb->__isRemoved_ = true;
}
}
else {
// Callback is currently executing on another thread,
// block until it finishes executing.
while ( ! __cb->__callbackFinishedExecuting_.load(std::memory_order_acquire) ) {
__spin_yield();
}
}
__remove_token_reference();
}
private:
static bool __is_locked(std::uint64_t __state) noexcept { return (__state & __locked_flag) != 0; }
static bool __is_stop_requested(std::uint64_t __state) noexcept { return (__state & __stop_requested_flag) != 0; }
static bool __is_stop_requestable(std::uint64_t __state) noexcept {
// Interruptible if it has already been interrupted or if there are
// still interrupt_source instances in existence.
return __is_stop_requested(__state) || (__state >= __source_ref_increment);
}
bool __try_lock_and_signal_until_signalled() noexcept {
std::uint64_t __oldState = __state_.load(std::memory_order_acquire);
do {
if ( __is_stop_requested(__oldState) )
return false;
while ( __is_locked(__oldState) ) {
__spin_yield();
__oldState = __state_.load(std::memory_order_acquire);
if ( __is_stop_requested(__oldState) )
return false;
}
} while ( ! __state_.compare_exchange_weak(__oldState, __oldState | __stop_requested_flag | __locked_flag,
std::memory_order_acq_rel, std::memory_order_acquire) );
return true;
}
void __lock() noexcept {
auto __oldState = __state_.load(std::memory_order_relaxed);
do {
while ( __is_locked(__oldState) ) {
__spin_yield();
__oldState = __state_.load(std::memory_order_relaxed);
}
} while ( ! __state_.compare_exchange_weak(__oldState, __oldState | __locked_flag, std::memory_order_acquire,
std::memory_order_relaxed) );
}
void __unlock() noexcept { __state_.fetch_sub(__locked_flag, std::memory_order_release); }
void __unlock_and_increment_token_ref_count() noexcept {
__state_.fetch_sub(__locked_flag - __token_ref_increment, std::memory_order_release);
}
void __unlock_and_decrement_token_ref_count() noexcept {
auto __oldState = __state_.fetch_sub(__locked_flag + __token_ref_increment, std::memory_order_acq_rel);
// Check if new state is less than __token_ref_increment which would
// indicate that this was the last reference.
if ( __oldState < (__locked_flag + __token_ref_increment + __token_ref_increment) ) {
delete this;
}
}
static constexpr std::uint64_t __stop_requested_flag = 1u;
static constexpr std::uint64_t __locked_flag = 2u;
static constexpr std::uint64_t __token_ref_increment = 4u;
static constexpr std::uint64_t __source_ref_increment = static_cast<std::uint64_t>(1u) << 33u;
// bit 0 - stop-requested
// bit 1 - locked
// bits 2-32 - token ref count (31 bits)
// bits 33-63 - source ref count (31 bits)
std::atomic<std::uint64_t> __state_{__source_ref_increment};
__stop_callback_base* __head_ = nullptr;
std::thread::id __signallingThread_{};
};
//-----------------------------------------------
// forward declarations
//-----------------------------------------------
class stop_source;
template<typename _Callback>
class stop_callback;
// std::nostopstate
// - to initialize a stop_source without shared stop state
struct nostopstate_t {
explicit nostopstate_t() = default;
};
inline constexpr nostopstate_t nostopstate{};
//-----------------------------------------------
// stop_token
//-----------------------------------------------
class stop_token {
public:
// construct:
// - TODO: explicit?
stop_token() noexcept : __state_(nullptr) {}
// copy/move/assign/destroy:
stop_token(const stop_token& __it) noexcept : __state_(__it.__state_) {
if ( __state_ != nullptr ) {
__state_->__add_token_reference();
}
}
stop_token(stop_token&& __it) noexcept : __state_(std::exchange(__it.__state_, nullptr)) {}
~stop_token() {
if ( __state_ != nullptr ) {
__state_->__remove_token_reference();
}
}
stop_token& operator=(const stop_token& __it) noexcept {
if ( __state_ != __it.__state_ ) {
stop_token __tmp{__it};
swap(__tmp);
}
return *this;
}
stop_token& operator=(stop_token&& __it) noexcept {
stop_token __tmp{std::move(__it)};
swap(__tmp);
return *this;
}
void swap(stop_token& __it) noexcept { std::swap(__state_, __it.__state_); }
// stop handling:
[[nodiscard]] bool stop_requested() const noexcept {
return __state_ != nullptr && __state_->__is_stop_requested();
}
[[nodiscard]] bool stop_possible() const noexcept {
return __state_ != nullptr && __state_->__is_stop_requestable();
}
[[nodiscard]] friend bool operator==(const stop_token& __a, const stop_token& __b) noexcept {
return __a.__state_ == __b.__state_;
}
[[nodiscard]] friend bool operator!=(const stop_token& __a, const stop_token& __b) noexcept {
return __a.__state_ != __b.__state_;
}
private:
friend class stop_source;
template<typename _Callback>
friend class stop_callback;
explicit stop_token(__stop_state* __state) noexcept : __state_(__state) {
if ( __state_ != nullptr ) {
__state_->__add_token_reference();
}
}
__stop_state* __state_;
};
//-----------------------------------------------
// stop_source
//-----------------------------------------------
class stop_source {
public:
stop_source() : __state_(new __stop_state()) {}
explicit stop_source(nostopstate_t) noexcept : __state_(nullptr) {}
~stop_source() {
if ( __state_ != nullptr ) {
__state_->__remove_source_reference();
}
}
stop_source(const stop_source& __other) noexcept : __state_(__other.__state_) {
if ( __state_ != nullptr ) {
__state_->__add_source_reference();
}
}
stop_source(stop_source&& __other) noexcept : __state_(std::exchange(__other.__state_, nullptr)) {}
stop_source& operator=(stop_source&& __other) noexcept {
stop_source __tmp{std::move(__other)};
swap(__tmp);
return *this;
}
stop_source& operator=(const stop_source& __other) noexcept {
if ( __state_ != __other.__state_ ) {
stop_source __tmp{__other};
swap(__tmp);
}
return *this;
}
[[nodiscard]] bool stop_requested() const noexcept {
return __state_ != nullptr && __state_->__is_stop_requested();
}
[[nodiscard]] bool stop_possible() const noexcept { return __state_ != nullptr; }
bool request_stop() noexcept {
if ( __state_ != nullptr ) {
return __state_->__request_stop();
}
return false;
}
[[nodiscard]] stop_token get_token() const noexcept { return stop_token{__state_}; }
void swap(stop_source& __other) noexcept { std::swap(__state_, __other.__state_); }
[[nodiscard]] friend bool operator==(const stop_source& __a, const stop_source& __b) noexcept {
return __a.__state_ == __b.__state_;
}
[[nodiscard]] friend bool operator!=(const stop_source& __a, const stop_source& __b) noexcept {
return __a.__state_ != __b.__state_;
}
private:
__stop_state* __state_;
};
//-----------------------------------------------
// stop_callback
//-----------------------------------------------
template<typename _Callback>
// requires Destructible<_Callback> && Invocable<_Callback>
class [[nodiscard]] stop_callback : private __stop_callback_base {
public:
using callback_type = _Callback;
template<typename _CB, std::enable_if_t<std::is_constructible_v<_Callback, _CB>, int> = 0>
// requires Constructible<Callback, C>
explicit stop_callback(const stop_token& __token,
_CB&& __cb) noexcept(std::is_nothrow_constructible_v<_Callback, _CB>)
: __stop_callback_base{[](__stop_callback_base* __that) noexcept {
static_cast<stop_callback*>(__that)->__execute();
}},
__state_(nullptr),
__cb_(static_cast<_CB&&>(__cb)) {
if ( __token.__state_ != nullptr && __token.__state_->__try_add_callback(this, true) ) {
__state_ = __token.__state_;
}
}
template<typename _CB, std::enable_if_t<std::is_constructible_v<_Callback, _CB>, int> = 0>
// requires Constructible<Callback, C>
explicit stop_callback(stop_token&& __token, _CB&& __cb) noexcept(std::is_nothrow_constructible_v<_Callback, _CB>)
: __stop_callback_base{[](__stop_callback_base* __that) noexcept {
static_cast<stop_callback*>(__that)->__execute();
}},
__state_(nullptr),
__cb_(static_cast<_CB&&>(__cb)) {
if ( __token.__state_ != nullptr && __token.__state_->__try_add_callback(this, false) ) {
__state_ = std::exchange(__token.__state_, nullptr);
}
}
~stop_callback() {
#ifdef SAFE
if ( __inExecute_.load() ) {
std::cerr << "*** OOPS: ~stop_callback() while callback executed\n";
}
#endif
if ( __state_ != nullptr ) {
__state_->__remove_callback(this);
}
}
stop_callback& operator=(const stop_callback&) = delete;
stop_callback& operator=(stop_callback&&) = delete;
stop_callback(const stop_callback&) = delete;
stop_callback(stop_callback&&) = delete;
private:
void __execute() noexcept {
// Executed in a noexcept context
// If it throws then we call std::terminate().
#ifdef SAFE
__inExecute_.store(true);
__cb_();
__inExecute_.store(false);
#else
__cb_();
#endif
}
__stop_state* __state_;
_Callback __cb_;
#ifdef SAFE
std::atomic<bool> __inExecute_{false};
#endif
};
template<typename _Callback>
stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
} // namespace nonstd

93
src/3rdparty/strsep.c vendored
View file

@ -1,93 +0,0 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "zeek/zeek-config.h"
#ifndef HAVE_STRSEP
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
char *strsep(char **, const char *);
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#ifndef lint
static const char rcsid[] =
"$FreeBSD: src/lib/libc/string/strsep.c,v 1.2.12.1 2001/07/09 23:30:07 obrien Exp $";
#endif
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
char *
strsep(stringp, delim)
register char **stringp;
register const char *delim;
{
register char *s;
register const char *spanp;
register int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
#endif

View file

@ -1,217 +0,0 @@
/* Taken/adapted from FreeBSD 9.0.0 inet_ntop.c (CVS revision 1.3.16.1.2.1) */
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "zeek_inet_ntop.h"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
/*%
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static const char *zeek_inet_ntop4(const u_char *src, char *dst, socklen_t size);
static const char *zeek_inet_ntop6(const u_char *src, char *dst, socklen_t size);
/* char *
* zeek_inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
const char *
zeek_inet_ntop(int af, const void * __restrict src, char * __restrict dst,
socklen_t size)
{
switch (af) {
case AF_INET:
return (zeek_inet_ntop4(src, dst, size));
case AF_INET6:
return (zeek_inet_ntop6(src, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* zeek_inet_ntop4(src, dst, size)
* format an IPv4 address
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a u_char* not an in_addr as input
* author:
* Paul Vixie, 1996. Modified by Jon Siwek, 2012, to replace strlcpy
*/
static const char *
zeek_inet_ntop4(const u_char *src, char *dst, socklen_t size)
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
int l;
l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
if (l <= 0 || (socklen_t) l >= size) {
errno = ENOSPC;
return (NULL);
}
strncpy(dst, tmp, size - 1);
dst[size - 1] = 0;
return (dst);
}
/* const char *
* zeek_inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996. Modified by Jon Siwek, 2012, for IPv4-translated format
*/
static const char *
zeek_inet_ntop6(const u_char *src, char *dst, socklen_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
struct { int base, len; } best, cur;
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for (i = 0; i < NS_IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
best.len = 0;
cur.base = -1;
cur.len = 0;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
int remaining = sizeof(tmp);
tp = tmp;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ) && remaining > 0; i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base)
{
*tp++ = ':';
remaining--;
}
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0)
{
*tp++ = ':';
remaining--;
}
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 && (best.len == 6 ||
(best.len == 7 && words[7] != 0x0001) ||
(best.len == 5 && words[5] == 0xffff) ||
(best.len == 4 && words[4] == 0xffff && words[5] == 0))) {
if (!zeek_inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
remaining -= strlen(tp);
break;
}
// snprintf() returns the number of characters that were written not
// including the null character. We can use that to increase the
// pointer as we're moving forward. Unfortunately, snprintf() can also
// return more than the value passed if it would have stepped off the
// end.
int ret = snprintf(tp, remaining, "%x" , words[i]);
if ( ret < remaining )
tp += ret;
// Even if we returned too much data, subtract from remaining so that
// the failure cases below get triggered.
remaining -= ret;
}
/* Was it a trailing run of 0x00's? */
if (remaining >= 2 &&
best.base != -1 &&
(best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) {
*tp++ = ':';
remaining--;
}
if ( remaining >= 1 ) {
*tp++ = '\0';
remaining--;
}
else if ( remaining <= 0 ) {
errno = ENOSPC;
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}

View file

@ -1,16 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/socket.h>
const char *
zeek_inet_ntop(int af, const void * __restrict src, char * __restrict dst,
socklen_t size);
#ifdef __cplusplus
}
#endif

View file

@ -41,8 +41,6 @@ const char* attr_name(AttrTag t) {
"&is_assigned", "&is_assigned",
"&is_used", "&is_used",
"&ordered", "&ordered",
"&no_ZAM_opt",
"&no_CPP_opt",
}; };
// clang-format on // clang-format on
@ -168,9 +166,13 @@ detail::TraversalCode Attr::Traverse(detail::TraversalCallback* cb) const {
HANDLE_TC_ATTR_POST(tc); HANDLE_TC_ATTR_POST(tc);
} }
Attributes::Attributes(std::vector<AttrPtr> a, TypePtr t, bool in_record, bool is_global, bool is_param) Attributes::Attributes(TypePtr t, bool arg_in_record, bool is_global)
: type(std::move(t)), in_record(in_record), global_var(is_global), is_param(is_param) { : Attributes(std::vector<AttrPtr>{}, std::move(t), arg_in_record, is_global) {}
Attributes::Attributes(std::vector<AttrPtr> a, TypePtr t, bool arg_in_record, bool is_global) : type(std::move(t)) {
attrs.reserve(a.size()); attrs.reserve(a.size());
in_record = arg_in_record;
global_var = is_global;
SetLocationInfo(&start_location, &end_location); SetLocationInfo(&start_location, &end_location);
@ -196,19 +198,9 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef) {
return true; return true;
} }
static const std::set<AttrTag> acceptable = { return new_tag == ATTR_LOG || new_tag == ATTR_OPTIONAL || new_tag == ATTR_REDEF ||
ATTR_BROKER_STORE_ALLOW_COMPLEX, new_tag == ATTR_BROKER_STORE_ALLOW_COMPLEX || new_tag == ATTR_RAW_OUTPUT ||
ATTR_ERROR_HANDLER, new_tag == ATTR_ERROR_HANDLER || new_tag == ATTR_IS_USED;
ATTR_IS_USED,
ATTR_LOG,
ATTR_NO_CPP_OPT,
ATTR_NO_ZAM_OPT,
ATTR_OPTIONAL,
ATTR_RAW_OUTPUT,
ATTR_REDEF,
};
return acceptable.contains(new_tag);
}; };
// A `redef` is allowed to overwrite an existing attribute instead of // A `redef` is allowed to overwrite an existing attribute instead of
@ -229,7 +221,7 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef) {
// that's a signal to skip the checking. If the type is error, // that's a signal to skip the checking. If the type is error,
// there's no point checking attributes either. // there's no point checking attributes either.
if ( type && ! IsErrorType(type->Tag()) ) { if ( type && ! IsErrorType(type->Tag()) ) {
if ( ! CheckAttr(attr.get(), type) ) { if ( ! CheckAttr(attr.get()) ) {
// Get rid of it, so we don't get error cascades down the line. // Get rid of it, so we don't get error cascades down the line.
RemoveAttr(attr->Tag()); RemoveAttr(attr->Tag());
return; return;
@ -297,7 +289,7 @@ void Attributes::DescribeReST(ODesc* d, bool shorten) const {
} }
} }
bool Attributes::CheckAttr(Attr* a, const TypePtr& attrs_t) { bool Attributes::CheckAttr(Attr* a) {
switch ( a->Tag() ) { switch ( a->Tag() ) {
case ATTR_DEPRECATED: case ATTR_DEPRECATED:
case ATTR_REDEF: case ATTR_REDEF:
@ -305,11 +297,13 @@ bool Attributes::CheckAttr(Attr* a, const TypePtr& attrs_t) {
case ATTR_IS_USED: break; case ATTR_IS_USED: break;
case ATTR_OPTIONAL: case ATTR_OPTIONAL:
if ( ! in_record ) if ( global_var )
return AttrError("&optional is only valid for record fields"); return AttrError("&optional is not valid for global variables");
if ( Find(ATTR_DEFAULT) ) // Remove in v8.1: Call AttrError()
return AttrError("Using &default and &optional together results in &default behavior"); if ( in_record && Find(ATTR_DEFAULT) )
zeek::reporter->Deprecation(
"Remove in v8.1: Using &default and &optional together results in &default behavior");
break; break;
@ -339,7 +333,7 @@ bool Attributes::CheckAttr(Attr* a, const TypePtr& attrs_t) {
return AttrError("&default and &default_insert cannot be used together"); return AttrError("&default and &default_insert cannot be used together");
std::string err_msg; std::string err_msg;
if ( ! check_default_attr(a, type, global_var, in_record || is_param, err_msg) && ! err_msg.empty() ) if ( ! check_default_attr(a, type, global_var, in_record, err_msg) && ! err_msg.empty() )
return AttrError(err_msg.c_str()); return AttrError(err_msg.c_str());
break; break;
} }
@ -348,11 +342,13 @@ bool Attributes::CheckAttr(Attr* a, const TypePtr& attrs_t) {
if ( Find(ATTR_DEFAULT_INSERT) ) if ( Find(ATTR_DEFAULT_INSERT) )
return AttrError("&default and &default_insert cannot be used together"); return AttrError("&default and &default_insert cannot be used together");
// Remove in v8.1: Call AttrError()
if ( in_record && Find(ATTR_OPTIONAL) ) if ( in_record && Find(ATTR_OPTIONAL) )
return AttrError("Using &default and &optional together results in &default behavior"); zeek::reporter->Deprecation(
"Remove in v8.1: Using &default and &optional together results in &default behavior");
std::string err_msg; std::string err_msg;
if ( ! check_default_attr(a, type, global_var, in_record || is_param, err_msg) && ! err_msg.empty() ) if ( ! check_default_attr(a, type, global_var, in_record, err_msg) && ! err_msg.empty() )
return AttrError(err_msg.c_str()); return AttrError(err_msg.c_str());
break; break;
} }
@ -553,15 +549,6 @@ bool Attributes::CheckAttr(Attr* a, const TypePtr& attrs_t) {
return AttrError("&ordered only applicable to tables"); return AttrError("&ordered only applicable to tables");
break; break;
case ATTR_NO_ZAM_OPT:
case ATTR_NO_CPP_OPT: {
if ( attrs_t->Tag() != TYPE_FUNC ) {
bool is_no_zam = a->Tag() == ATTR_NO_ZAM_OPT;
Error(util::fmt("&no_%s_opt must apply to a function", is_no_zam ? "ZAM" : "CPP"), attrs_t.get());
return false;
}
} break;
default: BadTag("Attributes::CheckAttr", attr_name(a->Tag())); default: BadTag("Attributes::CheckAttr", attr_name(a->Tag()));
} }
@ -603,7 +590,7 @@ bool Attributes::operator==(const Attributes& other) const {
return true; return true;
} }
bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool record_like, std::string& err_msg) { bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool in_record, std::string& err_msg) {
ASSERT(a->Tag() == ATTR_DEFAULT || a->Tag() == ATTR_DEFAULT_INSERT); ASSERT(a->Tag() == ATTR_DEFAULT || a->Tag() == ATTR_DEFAULT_INSERT);
std::string aname = attr_name(a->Tag()); std::string aname = attr_name(a->Tag());
// &default is allowed for global tables, since it's used in // &default is allowed for global tables, since it's used in
@ -615,7 +602,7 @@ bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool reco
const auto& atype = a->GetExpr()->GetType(); const auto& atype = a->GetExpr()->GetType();
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! record_like) ) { if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) {
if ( same_type(atype, type) ) if ( same_type(atype, type) )
// Ok. // Ok.
return true; return true;
@ -645,7 +632,7 @@ bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool reco
TableType* tt = type->AsTableType(); TableType* tt = type->AsTableType();
const auto& ytype = tt->Yield(); const auto& ytype = tt->Yield();
if ( ! record_like ) { // &default applies to the type itself. if ( ! in_record ) { // &default applies to the type itself.
if ( same_type(atype, ytype) ) if ( same_type(atype, ytype) )
return true; return true;

View file

@ -50,8 +50,6 @@ enum AttrTag : uint8_t {
ATTR_IS_ASSIGNED, // to suppress usage warnings ATTR_IS_ASSIGNED, // to suppress usage warnings
ATTR_IS_USED, // to suppress usage warnings ATTR_IS_USED, // to suppress usage warnings
ATTR_ORDERED, // used to store tables in ordered mode ATTR_ORDERED, // used to store tables in ordered mode
ATTR_NO_ZAM_OPT, // avoid ZAM optimization
ATTR_NO_CPP_OPT, // avoid -O gen-C++ optimization
NUM_ATTRS // this item should always be last NUM_ATTRS // this item should always be last
}; };
@ -110,14 +108,8 @@ protected:
// Manages a collection of attributes. // Manages a collection of attributes.
class Attributes final : public Obj { class Attributes final : public Obj {
public: public:
Attributes(std::vector<AttrPtr> a, TypePtr t, bool in_record, bool is_global, bool is_param); Attributes(std::vector<AttrPtr> a, TypePtr t, bool in_record, bool is_global);
Attributes(TypePtr t, bool in_record, bool is_global);
Attributes(TypePtr t, bool in_record, bool is_global)
: Attributes(std::vector<AttrPtr>{}, std::move(t), in_record, is_global, false) {}
Attributes(std::vector<AttrPtr> a, TypePtr t, bool in_record, bool is_global)
: Attributes(std::move(a), std::move(t), in_record, is_global, false) {}
~Attributes() override = default; ~Attributes() override = default;
@ -140,7 +132,7 @@ public:
protected: protected:
// Returns true if the attribute is okay, false if not. // Returns true if the attribute is okay, false if not.
bool CheckAttr(Attr* attr, const TypePtr& attrs_t); bool CheckAttr(Attr* attr);
// Reports an attribute error and returns false (handy for CheckAttr()). // Reports an attribute error and returns false (handy for CheckAttr()).
bool AttrError(const char* msg); bool AttrError(const char* msg);
@ -150,7 +142,6 @@ protected:
bool in_record; bool in_record;
bool global_var; bool global_var;
bool is_param;
}; };
// Checks whether default attribute "a" is compatible with the given type. // Checks whether default attribute "a" is compatible with the given type.

View file

@ -467,16 +467,8 @@ set(THIRD_PARTY_SRCS
3rdparty/strsep.c 3rdparty/strsep.c
3rdparty/zeek_inet_ntop.c) 3rdparty/zeek_inet_ntop.c)
if (USE_SQLITE) if (USE_SQLITE AND WNOERROR_FLAG)
if (WNOERROR_FLAG) set_source_files_properties(3rdparty/sqlite3.c PROPERTIES COMPILE_FLAGS ${WNOERROR_FLAG})
set_source_files_properties(3rdparty/sqlite3.c PROPERTIES COMPILE_FLAGS ${WNOERROR_FLAG})
endif ()
# Always force building SQLite in thread-safe mode. This lets us remove sqlite3_threadsafe()
# checks in various places, since the library will always be guaranteed to be in thread-safe
# mode. This value is the default, but it's set here to be explicit about it.
set_source_files_properties(3rdparty/sqlite3.c PROPERTIES COMPILE_DEFINITIONS
SQLITE_THREADSAFE=1)
endif () endif ()
set_source_files_properties(${THIRD_PARTY_SRCS} PROPERTIES SKIP_LINTING ON) set_source_files_properties(${THIRD_PARTY_SRCS} PROPERTIES SKIP_LINTING ON)

View file

@ -4,7 +4,6 @@
#include <binpac.h> #include <binpac.h>
#include <cctype> #include <cctype>
#include <memory>
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/ID.h" #include "zeek/ID.h"
@ -13,7 +12,6 @@
#include "zeek/RunState.h" #include "zeek/RunState.h"
#include "zeek/Timer.h" #include "zeek/Timer.h"
#include "zeek/TunnelEncapsulation.h" #include "zeek/TunnelEncapsulation.h"
#include "zeek/WeirdState.h"
#include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Analyzer.h"
#include "zeek/analyzer/Manager.h" #include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/pia/PIA.h" #include "zeek/analyzer/protocol/pia/PIA.h"
@ -41,10 +39,47 @@ Connection::Connection(zeek::IPBasedConnKeyPtr k, double t, uint32_t flow, const
resp_port = key->DstPort(); resp_port = key->DstPort();
proto = key->GetTransportProto(); proto = key->GetTransportProto();
Init(flow, pkt);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Connection::Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt)
: Session(t, connection_timeout, connection_status_update, detail::connection_status_update_interval) {
orig_addr = id->src_addr;
resp_addr = id->dst_addr;
orig_port = id->src_port;
resp_port = id->dst_port;
key = std::make_unique<zeek::IPConnKey>();
key->InitTuple(id->src_addr, id->src_port, id->dst_addr, id->dst_port, id->proto, id->is_one_way);
key->Init(*pkt);
proto = key->GetTransportProto();
Init(flow, pkt);
}
#pragma GCC diagnostic pop
Connection::~Connection() {
if ( ! finished )
reporter->InternalError("Done() not called before destruction of Connection");
CancelTimers();
if ( conn_val )
conn_val->SetOrigin(nullptr);
delete adapter;
--current_connections;
}
void Connection::Init(uint32_t flow, const Packet* pkt) {
orig_flow_label = flow; orig_flow_label = flow;
resp_flow_label = 0; resp_flow_label = 0;
saw_first_orig_packet = true; saw_first_orig_packet = 1;
saw_first_resp_packet = false; saw_first_resp_packet = 0;
if ( pkt->l2_src ) if ( pkt->l2_src )
memcpy(orig_l2_addr, pkt->l2_src, sizeof(orig_l2_addr)); memcpy(orig_l2_addr, pkt->l2_src, sizeof(orig_l2_addr));
@ -59,11 +94,11 @@ Connection::Connection(zeek::IPBasedConnKeyPtr k, double t, uint32_t flow, const
vlan = pkt->vlan; vlan = pkt->vlan;
inner_vlan = pkt->inner_vlan; inner_vlan = pkt->inner_vlan;
weird = false; weird = 0;
suppress_event = 0; suppress_event = 0;
finished = false; finished = 0;
adapter = nullptr; adapter = nullptr;
primary_PIA = nullptr; primary_PIA = nullptr;
@ -74,20 +109,6 @@ Connection::Connection(zeek::IPBasedConnKeyPtr k, double t, uint32_t flow, const
encapsulation = pkt->encap; encapsulation = pkt->encap;
} }
Connection::~Connection() {
if ( ! finished )
reporter->InternalError("Done() not called before destruction of Connection");
CancelTimers();
if ( conn_val )
conn_val->SetOrigin(nullptr);
delete adapter;
--current_connections;
}
void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& arg_encap) { void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& arg_encap) {
if ( encapsulation && arg_encap ) { if ( encapsulation && arg_encap ) {
if ( *encapsulation != *arg_encap ) { if ( *encapsulation != *arg_encap ) {
@ -119,7 +140,7 @@ void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& a
} }
void Connection::Done() { void Connection::Done() {
finished = true; finished = 1;
if ( adapter ) { if ( adapter ) {
if ( ConnTransport() == TRANSPORT_TCP ) { if ( ConnTransport() == TRANSPORT_TCP ) {
@ -273,7 +294,7 @@ void Connection::RemovalEvent() {
} }
void Connection::Weird(const char* name, const char* addl, const char* source) { void Connection::Weird(const char* name, const char* addl, const char* source) {
weird = true; weird = 1;
reporter->Weird(this, name, addl ? addl : "", source ? source : ""); reporter->Weird(this, name, addl ? addl : "", source ? source : "");
} }
@ -395,16 +416,13 @@ void Connection::CheckFlowLabel(bool is_orig, uint32_t flow_label) {
} }
if ( is_orig ) if ( is_orig )
saw_first_orig_packet = true; saw_first_orig_packet = 1;
else else
saw_first_resp_packet = true; saw_first_resp_packet = 1;
} }
bool Connection::PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration) { bool Connection::PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration) {
if ( ! weird_state ) return detail::PermitWeird(weird_state, name, threshold, rate, duration);
weird_state = std::make_unique<detail::WeirdStateMap>();
return detail::PermitWeird(*weird_state, name, threshold, rate, duration);
} }
} // namespace zeek } // namespace zeek

View file

@ -53,6 +53,21 @@ enum ConnEventToFlag : uint8_t {
NUM_EVENTS_TO_FLAG, NUM_EVENTS_TO_FLAG,
}; };
// Deprecated without replacement: remove in v8.1.
// XXX using [[deprecated]] for the whole struct leads to hard errors on FreeBSD/MacOS.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
struct ConnTuple {
#pragma GCC diagnostic pop
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] IPAddr src_addr;
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] IPAddr dst_addr;
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] uint32_t src_port = 0;
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] uint32_t dst_port = 0;
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] uint16_t proto = UNKNOWN_IP_PROTO;
[[deprecated("Remove in v8.1: Switch to new conn_key framework")]] bool is_one_way =
false; // if true, don't canonicalize order
};
static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, const IPAddr& addr2, uint32_t p2) { static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, const IPAddr& addr2, uint32_t p2) {
return addr1 < addr2 || (addr1 == addr2 && p1 < p2); return addr1 < addr2 || (addr1 == addr2 && p1 < p2);
} }
@ -61,6 +76,9 @@ class Connection final : public session::Session {
public: public:
Connection(zeek::IPBasedConnKeyPtr k, double t, uint32_t flow, const Packet* pkt); Connection(zeek::IPBasedConnKeyPtr k, double t, uint32_t flow, const Packet* pkt);
[[deprecated("Remove in v8.1. Switch to ConnKey factories and the new zeek::ConnKey tree.")]]
Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt);
~Connection() override; ~Connection() override;
/** /**
@ -147,7 +165,7 @@ public:
void RemovalEvent() override; void RemovalEvent() override;
void Weird(const char* name, const char* addl = "", const char* source = ""); void Weird(const char* name, const char* addl = "", const char* source = "");
bool DidWeird() const { return weird; } bool DidWeird() const { return weird != 0; }
inline bool FlagEvent(ConnEventToFlag e) { inline bool FlagEvent(ConnEventToFlag e) {
if ( e >= 0 && e < NUM_EVENTS_TO_FLAG ) { if ( e >= 0 && e < NUM_EVENTS_TO_FLAG ) {
@ -195,11 +213,16 @@ public:
static void InitPostScript(); static void InitPostScript();
private: private:
// Common initialization for the constructors. This can move back into the
// (sole) constructor when we remove the deprecated one in 8.1.
void Init(uint32_t flow, const Packet* pkt);
friend class session::detail::Timer; friend class session::detail::Timer;
IPAddr orig_addr; IPAddr orig_addr;
IPAddr resp_addr; IPAddr resp_addr;
uint32_t orig_port, resp_port; // in network order uint32_t orig_port, resp_port; // in network order
TransportProto proto;
uint32_t orig_flow_label, resp_flow_label; // most recent IPv6 flow labels uint32_t orig_flow_label, resp_flow_label; // most recent IPv6 flow labels
uint32_t vlan, inner_vlan; // VLAN this connection traverses, if available uint32_t vlan, inner_vlan; // VLAN this connection traverses, if available
u_char orig_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer originator address, if available u_char orig_l2_addr[Packet::L2_ADDR_LEN]; // Link-layer originator address, if available
@ -207,21 +230,19 @@ private:
int suppress_event; // suppress certain events to once per conn. int suppress_event; // suppress certain events to once per conn.
RecordValPtr conn_val; RecordValPtr conn_val;
std::shared_ptr<EncapsulationStack> encapsulation; // tunnels std::shared_ptr<EncapsulationStack> encapsulation; // tunnels
uint8_t tunnel_changes = 0;
IPBasedConnKeyPtr key; IPBasedConnKeyPtr key;
TransportProto proto; unsigned int weird : 1;
uint8_t tunnel_changes = 0; unsigned int finished : 1;
bool weird; unsigned int saw_first_orig_packet : 1, saw_first_resp_packet : 1;
bool finished;
bool saw_first_orig_packet;
bool saw_first_resp_packet;
packet_analysis::IP::SessionAdapter* adapter; packet_analysis::IP::SessionAdapter* adapter;
analyzer::pia::PIA* primary_PIA; analyzer::pia::PIA* primary_PIA;
UID uid; // Globally unique connection ID. UID uid; // Globally unique connection ID.
std::unique_ptr<detail::WeirdStateMap> weird_state; detail::WeirdStateMap weird_state;
// Count number of connections. // Count number of connections.
static uint64_t total_connections; static uint64_t total_connections;

View file

@ -473,20 +473,20 @@ void DNS_Mgr::Done() {
} }
void DNS_Mgr::RegisterSocket(int fd, bool read, bool write) { void DNS_Mgr::RegisterSocket(int fd, bool read, bool write) {
if ( read && ! socket_fds.contains(fd) ) { if ( read && socket_fds.count(fd) == 0 ) {
socket_fds.insert(fd); socket_fds.insert(fd);
iosource_mgr->RegisterFd(fd, this, IOSource::READ); iosource_mgr->RegisterFd(fd, this, IOSource::READ);
} }
else if ( ! read && socket_fds.contains(fd) ) { else if ( ! read && socket_fds.count(fd) != 0 ) {
socket_fds.erase(fd); socket_fds.erase(fd);
iosource_mgr->UnregisterFd(fd, this, IOSource::READ); iosource_mgr->UnregisterFd(fd, this, IOSource::READ);
} }
if ( write && ! write_socket_fds.contains(fd) ) { if ( write && write_socket_fds.count(fd) == 0 ) {
write_socket_fds.insert(fd); write_socket_fds.insert(fd);
iosource_mgr->RegisterFd(fd, this, IOSource::WRITE); iosource_mgr->RegisterFd(fd, this, IOSource::WRITE);
} }
else if ( ! write && write_socket_fds.contains(fd) ) { else if ( ! write && write_socket_fds.count(fd) != 0 ) {
write_socket_fds.erase(fd); write_socket_fds.erase(fd);
iosource_mgr->UnregisterFd(fd, this, IOSource::WRITE); iosource_mgr->UnregisterFd(fd, this, IOSource::WRITE);
} }
@ -1323,7 +1323,7 @@ double DNS_Mgr::GetNextTimeout() {
} }
void DNS_Mgr::ProcessFd(int fd, int flags) { void DNS_Mgr::ProcessFd(int fd, int flags) {
if ( socket_fds.contains(fd) ) { if ( socket_fds.count(fd) != 0 ) {
int read_fd = (flags & IOSource::ProcessFlags::READ) != 0 ? fd : ARES_SOCKET_BAD; int read_fd = (flags & IOSource::ProcessFlags::READ) != 0 ? fd : ARES_SOCKET_BAD;
int write_fd = (flags & IOSource::ProcessFlags::WRITE) != 0 ? fd : ARES_SOCKET_BAD; int write_fd = (flags & IOSource::ProcessFlags::WRITE) != 0 ? fd : ARES_SOCKET_BAD;
ares_process_fd(channel, read_fd, write_fd); ares_process_fd(channel, read_fd, write_fd);
@ -1410,7 +1410,7 @@ TableValPtr DNS_Mgr::empty_addr_set() {
auto addr_t = base_type(TYPE_ADDR); auto addr_t = base_type(TYPE_ADDR);
auto set_index = make_intrusive<TypeList>(addr_t); auto set_index = make_intrusive<TypeList>(addr_t);
set_index->Append(std::move(addr_t)); set_index->Append(std::move(addr_t));
auto s = make_intrusive<TableType>(std::move(set_index), nullptr); auto s = make_intrusive<SetType>(std::move(set_index), nullptr);
return make_intrusive<TableVal>(std::move(s)); return make_intrusive<TableVal>(std::move(s));
} }

View file

@ -148,7 +148,7 @@ bool DebugLogger::CheckStreams(const std::set<std::string>& plugin_names) {
if ( ! stream.starts_with("plugin-") ) if ( ! stream.starts_with("plugin-") )
continue; continue;
if ( ! available_plugin_streams.contains(stream) ) { if ( available_plugin_streams.count(stream) == 0 ) {
reporter->Error("No plugin debug stream '%s' found", stream.c_str()); reporter->Error("No plugin debug stream '%s' found", stream.c_str());
ok = false; ok = false;
} }
@ -180,7 +180,7 @@ void DebugLogger::Log(DebugStream stream, const char* fmt, ...) {
void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...) { void DebugLogger::Log(const plugin::Plugin& plugin, const char* fmt, ...) {
if ( ! all ) { if ( ! all ) {
std::string tok = PluginStreamName(plugin.Name()); std::string tok = PluginStreamName(plugin.Name());
if ( ! enabled_streams.contains(tok) ) if ( enabled_streams.find(tok) == enabled_streams.end() )
return; return;
} }

View file

@ -144,6 +144,10 @@ public:
return byte_vec(t); return byte_vec(t);
} }
[[deprecated("Remove in v8.1. Use Size() that returns size_t instead.")]]
int Len() const {
return static_cast<int>(offset);
}
size_t Size() const { return offset; } size_t Size() const { return offset; }
void Clear(); void Clear();

View file

@ -41,6 +41,16 @@ RecordValPtr detail::MetadataEntry::BuildVal() const {
return rv; return rv;
} }
Event::Event(const EventHandlerPtr& arg_handler, zeek::Args arg_args, util::detail::SourceID arg_src,
analyzer::ID arg_aid, Obj* arg_obj, double arg_ts)
: handler(arg_handler),
args(std::move(arg_args)),
meta(detail::MakeEventMetadataVector(arg_ts)),
src(arg_src),
aid(arg_aid),
obj(zeek::NewRef{}, arg_obj),
next_event(nullptr) {}
Event::Event(detail::EventMetadataVectorPtr arg_meta, const EventHandlerPtr& arg_handler, zeek::Args arg_args, Event::Event(detail::EventMetadataVectorPtr arg_meta, const EventHandlerPtr& arg_handler, zeek::Args arg_args,
util::detail::SourceID arg_src, analyzer::ID arg_aid, Obj* arg_obj) util::detail::SourceID arg_src, analyzer::ID arg_aid, Obj* arg_obj)
: handler(arg_handler), : handler(arg_handler),
@ -48,7 +58,8 @@ Event::Event(detail::EventMetadataVectorPtr arg_meta, const EventHandlerPtr& arg
meta(std::move(arg_meta)), meta(std::move(arg_meta)),
src(arg_src), src(arg_src),
aid(arg_aid), aid(arg_aid),
obj(zeek::NewRef{}, arg_obj) {} obj(zeek::NewRef{}, arg_obj),
next_event(nullptr) {}
zeek::VectorValPtr Event::MetadataValues(const EnumValPtr& id) const { zeek::VectorValPtr Event::MetadataValues(const EnumValPtr& id) const {
static const auto& any_vec_t = zeek::id::find_type<zeek::VectorType>("any_vec"); static const auto& any_vec_t = zeek::id::find_type<zeek::VectorType>("any_vec");
@ -124,8 +135,14 @@ void Event::Dispatch(bool no_remote) {
reporter->BeginErrorHandler(); reporter->BeginErrorHandler();
try { try {
handler->Call(&args); #pragma GCC diagnostic push
} catch ( InterpreterException& e ) { #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// Replace in v8.1 with handler->Call(&args).
handler->Call(&args, no_remote, Time());
#pragma GCC diagnostic pop
}
catch ( InterpreterException& e ) {
// Already reported. // Already reported.
} }
@ -144,12 +161,15 @@ EventMgr::~EventMgr() {
} }
} }
void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, util::detail::SourceID src, analyzer::ID aid, Obj* obj) { void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, util::detail::SourceID src, analyzer::ID aid, Obj* obj,
DeprecatedTimestamp deprecated_ts) {
detail::EventMetadataVectorPtr meta; detail::EventMetadataVectorPtr meta;
double ts = double(deprecated_ts);
// If this is a local event and EventMetadata::add_network_timestamp is // If this is a local event and EventMetadata::add_network_timestamp is
// enabled, automatically set the network timestamp for this event to the // enabled, automatically set the network timestamp for this event to the
// current network time. // current network time when it is < 0 (default of deprecated_ts is -1.0).
// //
// See the other Enqueue() implementation for the local vs broker/remote // See the other Enqueue() implementation for the local vs broker/remote
// motivation of want_network_timestamp. // motivation of want_network_timestamp.
@ -158,8 +178,19 @@ void EventMgr::Enqueue(const EventHandlerPtr& h, Args vl, util::detail::SourceID
((src == util::detail::SOURCE_LOCAL) || ((src == util::detail::SOURCE_LOCAL) ||
(src == util::detail::SOURCE_BROKER && BifConst::EventMetadata::add_missing_remote_network_timestamp)); (src == util::detail::SOURCE_BROKER && BifConst::EventMetadata::add_missing_remote_network_timestamp));
if ( want_network_timestamp ) if ( want_network_timestamp ) {
meta = detail::MakeEventMetadataVector(run_state::network_time); if ( ts < 0.0 )
ts = run_state::network_time;
// In v8.1 when the deprecated_ts parameters is gone: Just use run_state::network_time directly here.
meta = detail::MakeEventMetadataVector(ts);
}
else if ( ts >= 0.0 ) {
// EventMetadata::add_network_timestamp is false, but EventMgr::Enqueue()
// with an explicit (non-negative) timestamp is used. That's a deprecated
// API, but we continue to support it until v8.1.
meta = detail::MakeEventMetadataVector(ts);
}
QueueEvent(new Event(std::move(meta), h, std::move(vl), src, aid, obj)); QueueEvent(new Event(std::move(meta), h, std::move(vl), src, aid, obj));
} }
@ -230,6 +261,14 @@ void EventMgr::QueueEvent(Event* event) {
++event_mgr.num_events_queued; ++event_mgr.num_events_queued;
} }
void EventMgr::Dispatch(Event* event, bool no_remote) {
Event* old_current = current;
current = event;
event->Dispatch(no_remote);
current = old_current;
Unref(event);
}
void EventMgr::Dispatch(const EventHandlerPtr& h, zeek::Args vl) { void EventMgr::Dispatch(const EventHandlerPtr& h, zeek::Args vl) {
detail::EventMetadataVectorPtr meta; detail::EventMetadataVectorPtr meta;
@ -245,11 +284,11 @@ void EventMgr::Dispatch(const EventHandlerPtr& h, zeek::Args vl) {
if ( done ) if ( done )
return; return;
Event* old_current = current; #pragma GCC diagnostic push
current = ev; #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
ev->Dispatch(); // TODO: Open-code the old Dispatch() implementation here in v8.1.
current = old_current; Dispatch(ev);
Unref(ev); #pragma GCC diagnostic pop
} }
void EventMgr::Drain() { void EventMgr::Drain() {

View file

@ -55,6 +55,10 @@ constexpr double NO_TIMESTAMP = -1.0;
class Event final : public Obj { class Event final : public Obj {
public: public:
[[deprecated("Remove in v8.1: Do not instantiate raw events. Use EventMgr::Dispatch() or EventMgr::Enqueue().")]]
Event(const EventHandlerPtr& handler, zeek::Args args, util::detail::SourceID src = util::detail::SOURCE_LOCAL,
analyzer::ID aid = 0, Obj* obj = nullptr, double ts = run_state::network_time);
void SetNext(Event* n) { next_event = n; } void SetNext(Event* n) { next_event = n; }
Event* NextEvent() const { return next_event; } Event* NextEvent() const { return next_event; }
@ -95,10 +99,12 @@ private:
util::detail::SourceID src; util::detail::SourceID src;
analyzer::ID aid; analyzer::ID aid;
zeek::IntrusivePtr<Obj> obj; zeek::IntrusivePtr<Obj> obj;
Event* next_event = nullptr; Event* next_event;
}; };
class EventMgr final : public Obj, public iosource::IOSource { class EventMgr final : public Obj, public iosource::IOSource {
class DeprecatedTimestamp;
public: public:
~EventMgr() override; ~EventMgr() override;
@ -117,7 +123,7 @@ public:
* (defaults to current network time - deprecated). * (defaults to current network time - deprecated).
*/ */
void Enqueue(const EventHandlerPtr& h, zeek::Args vl, util::detail::SourceID src = util::detail::SOURCE_LOCAL, void Enqueue(const EventHandlerPtr& h, zeek::Args vl, util::detail::SourceID src = util::detail::SOURCE_LOCAL,
analyzer::ID aid = 0, Obj* obj = nullptr); analyzer::ID aid = 0, Obj* obj = nullptr, DeprecatedTimestamp ts = {});
/** /**
* A version of Enqueue() taking a variable number of arguments. * A version of Enqueue() taking a variable number of arguments.
@ -141,6 +147,9 @@ public:
void Enqueue(detail::EventMetadataVectorPtr meta, const EventHandlerPtr& h, zeek::Args vl, void Enqueue(detail::EventMetadataVectorPtr meta, const EventHandlerPtr& h, zeek::Args vl,
util::detail::SourceID src = util::detail::SOURCE_LOCAL, analyzer::ID aid = 0, Obj* obj = nullptr); util::detail::SourceID src = util::detail::SOURCE_LOCAL, analyzer::ID aid = 0, Obj* obj = nullptr);
[[deprecated("Remove in v8.1: Use Dispatch(handler, args) instead.")]]
void Dispatch(Event* event, bool no_remote = false);
// Dispatch an event with the given handler and arguments immediately. // Dispatch an event with the given handler and arguments immediately.
// //
// While the event is technically not queued, HookQueueEvent() is // While the event is technically not queued, HookQueueEvent() is
@ -187,6 +196,24 @@ public:
uint64_t num_events_dispatched = 0; uint64_t num_events_dispatched = 0;
private: private:
/**
* Helper class to produce a compile time warning if Enqueue() is called with an explicit timestamp.
*
* Remove in v8.1.
*/
class DeprecatedTimestamp {
public:
DeprecatedTimestamp() : d(-1.0) {}
[[deprecated("Use overload EventMgr::Enqueue(EventMetadataVectorPtr meta, ...) to pass timestamp metadata")]]
/*implicit*/ DeprecatedTimestamp(double d)
: d(d) {}
explicit operator double() const { return d; }
private:
double d;
};
void QueueEvent(Event* event); void QueueEvent(Event* event);
Event* current = nullptr; Event* current = nullptr;

View file

@ -22,7 +22,9 @@ EventHandler::EventHandler(std::string arg_name) {
generate_always = false; generate_always = false;
} }
EventHandler::operator bool() const { return enabled && ((local && local->HasEnabledBodies()) || generate_always); } EventHandler::operator bool() const {
return enabled && ((local && local->HasEnabledBodies()) || generate_always || ! auto_publish.empty());
}
const FuncTypePtr& EventHandler::GetType(bool check_export) { const FuncTypePtr& EventHandler::GetType(bool check_export) {
if ( type ) if ( type )
@ -42,7 +44,7 @@ const FuncTypePtr& EventHandler::GetType(bool check_export) {
void EventHandler::SetFunc(FuncPtr f) { local = std::move(f); } void EventHandler::SetFunc(FuncPtr f) { local = std::move(f); }
void EventHandler::Call(Args* vl) { void EventHandler::Call(Args* vl, bool no_remote, double ts) {
if ( ! call_count ) { if ( ! call_count ) {
static auto eh_invocations_family = static auto eh_invocations_family =
telemetry_mgr->CounterFamily("zeek", "event-handler-invocations", {"name"}, telemetry_mgr->CounterFamily("zeek", "event-handler-invocations", {"name"},
@ -56,6 +58,40 @@ void EventHandler::Call(Args* vl) {
if ( new_event ) if ( new_event )
NewEvent(vl); NewEvent(vl);
if ( ! no_remote ) {
if ( ! auto_publish.empty() ) {
// Send event in form [name, xs...] where xs represent the arguments.
BrokerListBuilder xs;
xs.Reserve(vl->size());
bool valid_args = true;
for ( const auto& v : *vl ) {
if ( ! xs.Add(v) ) {
valid_args = false;
auto_publish.clear();
reporter->Error("failed auto-remote event '%s', disabled", Name());
break;
}
}
if ( valid_args ) {
auto ev_args = std::move(xs).Build();
for ( auto it = auto_publish.begin();; ) {
const auto& topic = *it;
++it;
if ( it != auto_publish.end() )
broker_mgr->PublishEvent(topic, Name(), ev_args, ts);
else {
broker_mgr->PublishEvent(topic, Name(), std::move(ev_args), ts);
break;
}
}
}
}
}
if ( local ) if ( local )
// No try/catch here; we pass exceptions upstream. // No try/catch here; we pass exceptions upstream.
local->Invoke(vl); local->Invoke(vl);

View file

@ -35,8 +35,28 @@ public:
void SetFunc(FuncPtr f); void SetFunc(FuncPtr f);
[[deprecated("Remove in v8.1, use explicit Publish().")]]
void AutoPublish(std::string topic) {
auto_publish.insert(std::move(topic));
}
[[deprecated("Remove in v8.1.")]]
void AutoUnpublish(const std::string& topic) {
auto_publish.erase(topic);
}
[[deprecated(
"Remove in v8.1. The no_remote and ts parameters are AutoPublish() specific and won't have an effect "
"in the future. Use Call(args)")]]
void Call(zeek::Args* vl, bool no_remote = false, double ts = run_state::network_time);
// Call the function associated with this handler. // Call the function associated with this handler.
void Call(zeek::Args* vl); void Call(zeek::Args* vl) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Call(vl, false, run_state::network_time);
#pragma GCC diagnostic pop
}
// Returns true if there is at least one local or remote handler. // Returns true if there is at least one local or remote handler.
explicit operator bool() const; explicit operator bool() const;
@ -69,6 +89,8 @@ private:
// Initialize this lazy, so we don't expose metrics for 0 values. // Initialize this lazy, so we don't expose metrics for 0 values.
std::shared_ptr<zeek::telemetry::Counter> call_count; std::shared_ptr<zeek::telemetry::Counter> call_count;
std::unordered_set<std::string> auto_publish;
}; };
// Encapsulates a ptr to an event handler to overload the boolean operator. // Encapsulates a ptr to an event handler to overload the boolean operator.

View file

@ -55,7 +55,7 @@ EventHandler* EventRegistry::Lookup(std::string_view name) {
} }
bool EventRegistry::NotOnlyRegisteredFromScript(std::string_view name) { bool EventRegistry::NotOnlyRegisteredFromScript(std::string_view name) {
return not_only_from_script.contains(std::string(name)); return not_only_from_script.count(std::string(name)) > 0;
} }
EventRegistry::string_list EventRegistry::Match(RE_Matcher* pattern) { EventRegistry::string_list EventRegistry::Match(RE_Matcher* pattern) {
@ -174,12 +174,12 @@ namespace {
class EventMetadataTypeRejector : public detail::TraversalCallback { class EventMetadataTypeRejector : public detail::TraversalCallback {
public: public:
detail::TraversalCode PreType(const Type* t) override { detail::TraversalCode PreType(const Type* t) override {
if ( visited.contains(t) ) if ( visited.count(t) > 0 )
return detail::TC_ABORTSTMT; return detail::TC_ABORTSTMT;
visited.insert(t); visited.insert(t);
if ( reject.contains(t->Tag()) ) if ( reject.count(t->Tag()) )
rejected.push_back(t); rejected.push_back(t);
return detail::TC_CONTINUE; return detail::TC_CONTINUE;

View file

@ -216,16 +216,6 @@ public:
*/ */
void AddFunc(detail::ScriptFuncPtr f); void AddFunc(detail::ScriptFuncPtr f);
/**
* @return The name associated with the group.
*/
const auto& GetName() const { return name; }
/**
* @return The type of group.
*/
const auto& GetEventGroupKind() const { return kind; }
private: private:
void UpdateFuncBodies(); void UpdateFuncBodies();

View file

@ -732,7 +732,7 @@ void ValTraceMgr::TraceEventValues(std::shared_ptr<EventTrace> et, const zeek::A
// remember them so we can catch uses of them in future events. // remember them so we can catch uses of them in future events.
for ( auto i = num_vals; i < vals.size(); ++i ) { for ( auto i = num_vals; i < vals.size(); ++i ) {
processed_vals.insert(vals[i].get()); processed_vals.insert(vals[i].get());
ASSERT(val_names.contains(vals[i].get())); ASSERT(val_names.count(vals[i].get()) > 0);
} }
} }
@ -794,8 +794,8 @@ void ValTraceMgr::NewVal(ValPtr v) {
} }
void ValTraceMgr::ValUsed(const ValPtr& v) { void ValTraceMgr::ValUsed(const ValPtr& v) {
ASSERT(val_names.contains(v.get())); ASSERT(val_names.count(v.get()) > 0);
if ( processed_vals.contains(v.get()) ) if ( processed_vals.count(v.get()) > 0 )
// We saw this value when processing a previous event. // We saw this value when processing a previous event.
globals.insert(v.get()); globals.insert(v.get());
} }
@ -818,17 +818,17 @@ void ValTraceMgr::AssessChange(const ValTrace* vt, const ValTrace* prev_vt) {
bool needs_lhs = d->NeedsLHS(); bool needs_lhs = d->NeedsLHS();
bool is_first_def = false; bool is_first_def = false;
if ( needs_lhs && ! val_names.contains(v) ) { if ( needs_lhs && val_names.count(v) == 0 ) {
TrackVar(v); TrackVar(v);
is_first_def = true; is_first_def = true;
} }
ASSERT(val_names.contains(v)); ASSERT(val_names.count(v) > 0);
// The "/" in the following is just to have a delimiter // The "/" in the following is just to have a delimiter
// to make sure the string is unambiguous. // to make sure the string is unambiguous.
auto full_delta = val_names[v] + "/" + rhs; auto full_delta = val_names[v] + "/" + rhs;
if ( previous_deltas.contains(full_delta) ) if ( previous_deltas.count(full_delta) > 0 )
continue; continue;
previous_deltas.insert(std::move(full_delta)); previous_deltas.insert(std::move(full_delta));
@ -849,7 +849,7 @@ void ValTraceMgr::TrackVar(const Val* v) {
std::string ValTraceMgr::GenValName(const ValPtr& v) { std::string ValTraceMgr::GenValName(const ValPtr& v) {
if ( IsAggr(v->GetType()) && ! IsUnspecifiedAggregate(v) ) { // Aggregate shouldn't exist; create it if ( IsAggr(v->GetType()) && ! IsUnspecifiedAggregate(v) ) { // Aggregate shouldn't exist; create it
ASSERT(! val_map.contains(v.get())); ASSERT(val_map.count(v.get()) == 0);
NewVal(v); NewVal(v);
return val_names[v.get()]; return val_names[v.get()];
} }
@ -1012,7 +1012,7 @@ void EventTraceMgr::Generate() {
} }
void EventTraceMgr::StartEvent(const ScriptFunc* ev, const zeek::Args* args) { void EventTraceMgr::StartEvent(const ScriptFunc* ev, const zeek::Args* args) {
if ( script_events.contains(ev->GetName()) ) if ( script_events.count(ev->GetName()) > 0 )
return; return;
auto nt = run_state::network_time; auto nt = run_state::network_time;
@ -1029,7 +1029,7 @@ void EventTraceMgr::StartEvent(const ScriptFunc* ev, const zeek::Args* args) {
} }
void EventTraceMgr::EndEvent(const ScriptFunc* ev, const zeek::Args* args) { void EventTraceMgr::EndEvent(const ScriptFunc* ev, const zeek::Args* args) {
if ( script_events.contains(ev->GetName()) ) if ( script_events.count(ev->GetName()) > 0 )
return; return;
if ( run_state::network_time > 0.0 && ev->GetName() != "zeek_init" ) if ( run_state::network_time > 0.0 && ev->GetName() != "zeek_init" )

View file

@ -354,7 +354,7 @@ public:
// Returns true if the script variable associated with the given value // Returns true if the script variable associated with the given value
// needs to be global (because it's used across multiple events). // needs to be global (because it's used across multiple events).
bool IsGlobal(const ValPtr& v) const { return globals.contains(v.get()); } bool IsGlobal(const ValPtr& v) const { return globals.count(v.get()) > 0; }
// Returns or sets the "base time" from which eligible times are // Returns or sets the "base time" from which eligible times are
// transformed into offsets rather than maintained as absolute // transformed into offsets rather than maintained as absolute

View file

@ -2999,7 +2999,7 @@ RecordConstructorExpr::RecordConstructorExpr(RecordTypePtr known_rt, ListExprPtr
auto n = known_rt->NumFields(); auto n = known_rt->NumFields();
for ( i = 0; i < n; ++i ) for ( i = 0; i < n; ++i )
if ( ! fields_seen.contains(i) ) { if ( fields_seen.count(i) == 0 ) {
const auto td_i = known_rt->FieldDecl(i); const auto td_i = known_rt->FieldDecl(i);
if ( IsAggr(td_i->type) ) if ( IsAggr(td_i->type) )
// These are always initialized. // These are always initialized.
@ -3366,7 +3366,7 @@ SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list, std::unique
} }
else { else {
if ( op->AsListExpr()->Exprs().empty() ) if ( op->AsListExpr()->Exprs().empty() )
SetType(make_intrusive<TableType>(make_intrusive<TypeList>(base_type(TYPE_ANY)), nullptr)); SetType(make_intrusive<zeek::SetType>(make_intrusive<TypeList>(base_type(TYPE_ANY)), nullptr));
else else
SetType(init_type(op)); SetType(init_type(op));
} }
@ -4226,7 +4226,7 @@ LambdaExpr::LambdaExpr(FunctionIngredientsPtr arg_ing, IDPList arg_outer_ids, st
if ( captures ) { if ( captures ) {
outer_ids.clear(); outer_ids.clear();
for ( auto& c : *captures ) for ( auto& c : *captures )
outer_ids.emplace_back(c.Id()); outer_ids.append(c.Id().get());
} }
// Install a primary version of the function globally. This is used // Install a primary version of the function globally. This is used
@ -4270,8 +4270,8 @@ LambdaExpr::LambdaExpr(LambdaExpr* orig) : Expr(EXPR_LAMBDA) {
// We need to have our own copies of the outer IDs and captures so // We need to have our own copies of the outer IDs and captures so
// we can rename them when inlined. // we can rename them when inlined.
for ( auto& i : orig->outer_ids ) for ( auto i : orig->outer_ids )
outer_ids.emplace_back(i); outer_ids.append(i);
if ( orig->captures ) { if ( orig->captures ) {
captures = std::vector<FuncType::Capture>{}; captures = std::vector<FuncType::Capture>{};
@ -4295,11 +4295,11 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
return true; return true;
} }
std::unordered_set<IDPtr> outer_is_matched; std::set<const ID*> outer_is_matched;
std::unordered_set<IDPtr> capture_is_matched; std::set<const ID*> capture_is_matched;
for ( const auto& c : *captures ) { for ( const auto& c : *captures ) {
auto cid = c.Id(); auto cid = c.Id().get();
if ( ! cid ) if ( ! cid )
// This happens for undefined/inappropriate // This happens for undefined/inappropriate
@ -4307,7 +4307,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
// already been an error message. // already been an error message.
continue; continue;
if ( capture_is_matched.contains(cid) ) { if ( capture_is_matched.count(cid) > 0 ) {
auto msg = util::fmt("%s listed multiple times in capture", cid->Name()); auto msg = util::fmt("%s listed multiple times in capture", cid->Name());
if ( when_parent ) if ( when_parent )
when_parent->Error(msg); when_parent->Error(msg);
@ -4317,7 +4317,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
return false; return false;
} }
for ( const auto& id : outer_ids ) for ( auto id : outer_ids )
if ( cid == id ) { if ( cid == id ) {
outer_is_matched.insert(id); outer_is_matched.insert(id);
capture_is_matched.insert(cid); capture_is_matched.insert(cid);
@ -4325,8 +4325,8 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
} }
} }
for ( const auto& id : outer_ids ) for ( auto id : outer_ids )
if ( ! outer_is_matched.contains(id) ) { if ( outer_is_matched.count(id) == 0 ) {
auto msg = util::fmt("%s is used inside %s but not captured", id->Name(), desc); auto msg = util::fmt("%s is used inside %s but not captured", id->Name(), desc);
if ( when_parent ) if ( when_parent )
when_parent->Error(msg); when_parent->Error(msg);
@ -4337,8 +4337,8 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) {
} }
for ( const auto& c : *captures ) { for ( const auto& c : *captures ) {
const auto& cid = c.Id(); auto cid = c.Id().get();
if ( cid && ! capture_is_matched.contains(cid) ) { if ( cid && capture_is_matched.count(cid) == 0 ) {
auto msg = util::fmt("%s is captured but not used inside %s", cid->Name(), desc); auto msg = util::fmt("%s is captured but not used inside %s", cid->Name(), desc);
if ( when_parent ) if ( when_parent )
when_parent->Error(msg); when_parent->Error(msg);
@ -4626,7 +4626,7 @@ TypePtr ListExpr::InitType() const {
// Collapse any embedded sets or lists. // Collapse any embedded sets or lists.
if ( ti->IsSet() || ti->Tag() == TYPE_LIST ) { if ( ti->IsSet() || ti->Tag() == TYPE_LIST ) {
TypeList* til = ti->IsSet() ? ti->AsTableType()->GetIndices().get() : ti->AsTypeList(); TypeList* til = ti->IsSet() ? ti->AsSetType()->GetIndices().get() : ti->AsTypeList();
if ( ! til->IsPure() || ! til->AllMatch(til->GetPureType(), true) ) if ( ! til->IsPure() || ! til->AllMatch(til->GetPureType(), true) )
tl->Append({NewRef{}, til}); tl->Append({NewRef{}, til});

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