This document summarizes the most important changes in the current Zeek
release. For an exhaustive list of changes, see the ``CHANGES`` file
(note that submodules, such as Broker, come with their own ``CHANGES``.)

Zeek 9.0.0
==========

We'd like to thank Aaron J. Scantlin (@scantlina), @airshelley, Alexey Rubanik
(@Rubanik-Alexei), Azil (@achill06), Bauti Peirone (@bautipeirone), Blair
McCormick (@blairSmcc03), Craig Leres (@leres), Craig P (@detection-labs),
@Cxiyuan, Dragon Roar (@lczllx), @eb-anssi, Eduardo Kohn (@eagle-head), Eldon
Koyle (@ekoyle), @franky-m, Jan Grashöfer (@J-Gras), Javid Khan (@dxbjavid), Jie
(Link) Zheng (@chillancezen), @jmestwa-coder, Julio César Suástegui
(@juliosuas), Keith J. Jones (@keithjjones), Kevin Harrington (@ke5C2Fin), Maor
Hamami (@mamaorha), Mario D (@mari0d), Matthias Vallentin (@mavam), Mohan Dhawan
(@mdhawan, @Mohan-Dhawan), neil (@neilpang), Otto Fowler (@ottobackwards), Peter
Cullen (@pbcullen), Seth Grover (@mmguero), Shubham Kumar (@chmodshubham),
Simeon Miteff (@simeonmiteff), Smoot (@stevesmoot), Stefan Götz
(@stefangoetzcorelight), Steven (@malvidin), Sujala Vasanthasena Nelavai
(@sujalavnelavai), Swastik Bose (@VasuBhakt), @tim-cyb, Urval (@urvalkheni),
@uwezkhan and Yacin Nadji (@ynadji) for their contributions to this release.

In addition, we're grateful to Kara Zaffarano and Kyle Elliott of Trail of Bits
in collaboration with OpenAI, AdaLogics in collaboration with Anthropic, and the
Canadian Communications Security Establishment for their code-scanning efforts
and resulting bug reports.

Breaking Changes
----------------

- Expanding on the removal of ``Broker::listen_websocket()`` in Zeek 8.1, this
  release fully removes Broker's legacy embedded WebSocket server. The script
  layer no longer provides ``Broker::BrokerProtocol`` and the options
  ``Broker::default_port_websocket``, ``Broker::default_listen_address_websocket``,
  ``Broker::web_socket_buffer_size``, and ``Broker::web_socket_overflow_policy``
  have likewise been removed. Use :zeek:see:`Cluster::listen_websocket()` and the
  ``ZEEK_WEBSOCKET_*`` environment variables instead.

  In Zeek's core, the Broker manager's ``Listen()`` method now always uses
  Broker's native protocol and no longer accepts the optional ``BrokerProtocol``
  argument. The ``BrokerProtocol`` enum has been removed.

- Calling the `zeek::util::fmt()` helper function from non-main threads will now
  emit a warning of the following form once:

	zeek::util::fmt() called off the main thread; use threading::BasicThread::Fmt() or std::format()

  In a debug build, Zeek will also abort. If you see above message, it is likely that
  an installed plugin spawned a thread and uses the API wrongly (likely input or logging
  threads). When deploying custom plugins, you should optimally test Zeek and all plugins
  separately with the thread and address sanitizers enabled (./configure --sanitizers=thread
  or ./configure --sanitizers=address).

- The ZeekJS plugin now requires ``std::format`` from C++20 which is not available
  in older distributions using GCC 12.x like Debian 12. If you want to use JavaScript
  support in Zeek, please update to a more recent distribution.

- Beginning with Zeek 9.0, the Zeek team is sunsetting our official support of FreeBSD.
  This is primarily because of our move to a new CI provider and the lack of good support
  for FreeBSD. We are moving FreeBSD support to the same model as OpenBSD where we will
  accept patches from external contributors if we break something, but not build and run
  the test suite on FreeBSD ourselves. This will simplify our maintenance a bit, as well
  as reduce the amount of time spent on CI jobs.

New Functionality
-----------------

- The zeek-packet-source-udp (https://github.com/zeek/zeek-packet-source-udp)
  plugin is now included and enabled by default on Linux and FreeBSD.

  Instead of reading raw packets from a network interface, this packet source turns
  Zeek into a UDP server to process UDP-based VXLAN or GENEVE mirror traffic directly:

	zeek -i udp::0.0.0.0:4789:vxlan

  The listening UDP socket is opened using the SO_REUSEPORT socket option. When
  scaling the number of Zeek workers, the kernel will balance packets among the
  individual UDP sockets based on the hash of the outermost UDP headers.

  This packet source comes with a few ConnKey implementations to make connection
  tracking aware of VXLAN VNI and GENEVE VNI. This feature needs to be explicitly
  enabled by loading one of the corresponding policy scripts, for example:

	zeek -i udp::0.0.0.0:4789:vxlan policy/frameworks/conn_key/packet_source/udp/vxlan_vni

  To disable building the packet source, use:

	./configure -D ENABLE_PACKET_SOURCE_UDP=no

- The ``zeek.conf`` configuration file and ``zeek-systemd-generator`` have been extended
  to support multiple interfaces as well as support for multi-host deployments. For
  more details and examples, see Zeek's online documentation:

	https://docs.zeek.org/en/master/advanced/deployment/systemd.html

  While the ``zeek-systemd-generator`` is Linux and systemd specific, the ``zeek.conf``
  file (and the code reading the file) are meant to be operating system agnostic and
  we're open for suggestions and contributions for alternative generators.

- The LDAP analyzer now forwards the SASL payload from bindRequest and bindResponse
  units to GSSAPI and NTLM parsers to extract additional information into the
  the ``ntlm.log`` or ``kerberos.log`` logs.

- The Syslog analyzer has been extended to support TCP using Octet Counting and
  Non-Transparent-Framing, registered on port 514/tcp by default.

- Escaping of control characters and invalid UTF-8 sequences for JSON logging has
  been made configurable. See the updated ASCII writer's online documentation for
  more details:

	https://docs.zeek.org/en/master/frameworks/logging.html#json-and-binary-data-in-strings

  To change the escaping behavior globally, redefine the new ``LogAscii::json_string_escape_policy``:

	redef Log::json_string_escape_policy = JSON::STRING_ESCAPE_POLICY_TSV;

  The default behavior continues to be ``JSON::STRING_ESCAPE_POLICY_HEX`` which
  can result in non-reversible encodings. Discussion #5240 on GitHub has a lot
  more details on the topic: https://github.com/zeek/zeek/discussions/5240

- The Input Framework now supports reading pattern values containing case-insensitive
  and single-line modifiers (/foo/i, /bar/s or /foobar/is).

- Imported the zeek/spicy-zip file analyzer into the main tree. This analyzer outputs
  information about ZIP files found in other protocols, including information about the
  contents of such archives. It will recursive search zip files, so there is the
  possibility of long chains. The maximum depth can be controlled via the
  ``Spicy::max_file_depth`` variable.

  The analyzer is not registered for any MIME types by default due to the potential for
  ZIP analysis to take very long times. This may prevent Zeek from doing other work. A new
  policy script ``policy/files/zip/register.zeek`` can be loaded to map the ZIP analyzer
  to the ``application/zip`` MIME type.

- Added a policy script ``policy/protocols/conn/multicast-participants.zeek``. This script writes a
  new ``multicast_participants.log`` that contains information about multicast connections with data
  about the participating hosts collected from IGMP.

- The ``script_id`` records returned by the ``global_ids()`` BiF now include information
  about the attributes attached to identifiers in the ``$attributes`` field.

- The event ``ssl_extension_signature_algorithms_cert`` was added. It is raised for the
  signature_algorithms_cert TLS extension.

- The new ``?as`` operator evaluates to true if Zeek can safely convert its lefthand operand
  to its righthand type. This change accompanies expanded support for the ``as`` casting
  operator, see below.

- The event ``ssl_extension_encrypted_client_hello`` was added. It contains information about
  the encrypted_client_hello TLS extension.

- Added two new NTP logs: ``ntp_control.log`` and ``ntp_private.log``, corresponding
  to NTP modes 6 and 7. Since these modes differ from other NTP operations, they were
  added to separate logs. Previously, only NTP modes 5 and under were logged.

- Added DPD signatures for QUIC version 1 and QUIC version 2 to attach the QUIC
  analyzer on non port 443 UDP connections when there's a signature match.

- The ``kerberos.log`` log entries now contains ``AP`` entries with filled ``service``
  and ``cipher`` columns. Previously, the log entries had all columns unset.

- The ``krb_ap_request()`` event was extended with an ``in_kdc_padata`` parameter to
  recognize if the corresponding AP-REQ is contained within KDC/TGS pre-authentication data.

- A new event ``dce_rpc_auth()`` was added for script-level access to the selected
  security provider, per-message protection and authentication context contained
  in DCE-RPC PDUs.

- The ``OpaqueType`` class has been made non-final and extended with hooks for hashing,
  casting and default initialization. This allows adding new scripting types that may be
  stored in sets or tables and casted to existing Zeek types, something that wasn't
  previously possible without introducing BIF functions. While the ``OpaqueType`` class isn't
  in the ``zeek::detail`` namespace, deriving and implementing the new hooks is  considered
  experimental and not subject to the usual deprecation policies.

- A new ``Reporter::limit_reached_weird`` BIF was added for reporting cases where a size
  limit was reached. This is typically used in security patches to ensure that memory
  limits are not being exceeded. The BIF reports a named weird and adds a ``X`` to the
  connection's ``history`` field when the connection is available.

Changed Functionality
---------------------

- The ``known-certs``, ``known-hosts``, and ``known-services`` scripts had options added
  to support using the storage framework instead of broker stores, which are slated to be
  removed in v9.1. For example, a new option was added for the hosts script called
  ``enable_hosts_persistence`` for enabling the storage framework. Options for controlling
  the framework were also added: ``host_store_prefix``, ``host_store_backend_type``, and
  ``host_store_backend_options``. By default it uses an SQLite backend, with the file
  stored in a directory under ``Cluster::default_store_dir``. Similar options are
  available for certs and services as well.

- The ``extension_signature_algorithm`` event previously was incorrectly raised when a
  CertificateRequest message was encountered. It now is not raised for CertificateRequest messages.

- The proposed HTTP QUERY method from RFC 10008 does not produce a weird anymore.
  Zeek already parsed the QUERY method, but raised a weird.

- The HTTP analyzer was extended with a number of new weirds to detect unusual
  Content-Length, Transfer-Encoding and Expect header usage:

	HTTP_bad_chunk_size
	HTTP_chunked_multi
	HTTP_content_length_0_and_expect_100_cont
	HTTP_content_length_leading_zeros
	HTTP_bad_content_length
	HTTP_obsolete_line_folding
	HTTP_content_length_and_chunked
	HTTP_content_range_and_chunked
	HTTP_expect_not_100_continue

  If you observe an excessive number of these weirds, you may always
  filter these out or report as false positives to us.

- The options and redefinitions from ``zeromq/main.zeek`` were split into a separate
  file ``zeromq/options.zeek`` to enable standalone Zeek processes connect to the ZeroMQ
  layer, without partaking in cluster node events.

- The ``as`` operator now supports all of the type conversions currently available via
  explicit conversion BiFs (such as ``interval_to_double()`` and similars), plus some
  additional ones that are natural companions. See the type-casting section in the
  operator documentation for details. Zeek's own scripts now use ``as`` throughout.

- ``policy/protocols/ssl/ssl-log-ext.zeek`` now logs the HPKE KDF and AEAD identifiers from the
  encrypted client hello extension in the ``ech_kdf_id`` and ``ech_aead_id`` fields.

- The software framework features improved control over version findings. The existing
  parse cache, mapping unparsed versions to ``Software::Version`` records, now supports
  configurable expiration times via the ``Software::parse_cache_interval`` setting.

  A new deduplication cache filters versions on the workers, preventing repeated
  reporting of the same version. This cache's lifetime is configurable via
  ``Software::found_cache_interval``, defaulting to 10 minutes. To disable the
  cache and restore historical behavior, redefine this value to 0secs.

  On the proxy nodes, tracking of software versions now keeps a day-long history
  of versions encountered on a given host, further deduplicating log writes.
  The ``Software::max_software_cache_size`` tunable caps the size of this
  per-host, per-software history. Redefining this setting to 0 disables this
  cache.

- The buffering state of a logging stream set via ``Log::set_buf()`` is now inherited
  by writers created dynamically at runtime after the ``Log::set_buf()`` call.

- Setting ``Log::flush_interval`` to 0.0sec now disables the flushing timer
  for log streams. Previously, it would result in scheduling a new timer that
  would immediately expire, something that isn't very useful.

- Certain protocol fields in the RDP parser are capped to maximum values to
  prevent unbounded buffering. This also prevents signed integer overflow
  reports from the BinPAC-generated code when running under UBSAN.

- The ``local.zeek`` script no longer loads ``policy/frameworks/telemetry/log.zeek``
  by default.

- Previously, Zeek wouldn't log FTP sessions that only had USER/PASS/QUIT
  commands in ``ftp.log`` at all. This has been changed to log at least one
  command (the last one) when no other command was logged for the session,
  even if that command isn't part of ``FTP::logged_commands``. You can
  revert to the previous behavior by setting
  ``FTP::log_at_least_one_command=F``.

- Added a recursion limit to Zeek script function calls. This will trigger a runtime
  error if the number of nested function calls exceeds the limit. This also adds two
  new BiFs: ``set_max_recursion_depth`` to set the maximum number of function calls,
  and ``get_max_recursion_depth`` to get that limit. Should the limit be set to 0, the
  check is skipped, reverting to previous (unchecked) behavior.

- The RPC analyzer resets its internal tracking table for RPC calls when more
  than rpc_max_pending_calls (default 1000) calls are pending to prevent unbounded
  state growth. This includes freeing the RPC_CallInfo values. The RPC analyzer
  (used by the NFS and MOUNT analyzers) is not enabled in a default configuration.

- DNS messages sent to multicast destinations (i.e. mDNS and LLMNR) are
  no longer associated as query/response pairs, since replies for these
  protocols arrive on different connections than queries. Each multicast
  message now produces its own independent log entry. This may result in
  more dns.log entries for environments with multicast DNS traffic, but
  the previous paired entries contained data from unrelated messages and
  were not valid. To revert to the previous behavior:
  ``redef DNS::multicast_subnets = {};``

- The ``bifcl`` compiler can now split the generated functions into a shim with
  the traditional calling sequence, and a new native function that takes and
  returns C++ values. The shim does standard checking on the ``Args`` vector,
  converts its ``ValPtr`` objects to C++ values (as before), calls the native
  function, and converts its return value back to a ``ValPtr``. This simplifies
  writing BiFs and allows script optimization to directly call the native
  functions without going through the shim.

  This change is not backward-compatible, so ``bifcl`` only makes the split for
  source files that include a ``%gen-native`` directive. All ``.bif`` files in
  the Zeek tree do so and have been converted to the native format.

- Multiple weirds associated with configurable limits will now mark the
  connection history with 'X' if Zeek will stop processing traffic after
  the limit was hit. This is in line with other, similar weirds.

- The ``unknown_protocols.log`` previously included the IP next protocol field
  as a 16 bit value, with the first byte value set to the next protocol followed
  by a zero byte due to a spurious use of ``htons()``. This has been fixed to be
  just the next protocol byte.

- The ``kerberos.log`` was updated to set the ``client`` column to ``/<realm>``
  for AP requests that do not otherwise carry a client name.

- The ``success`` column of the ``kerberos.log`` is now updated to ``T``
  when an AP-REP is observed.

- AP-REQ contained with KDC/TGS pre-authentication are now ignored for purposes
  of logging to ``kerberos.log``.

- Fixed file descriptors of the WebSocket server and WebSocket client connections
  (Cluster::listen_websocket()) being inherited by child processes. E.g., when using
  ``system()`` in Zeek scripts or the Input Framework's raw reader functionality.

- The LDAP analyzer now limits the number of pending request and search messages
  for correlation to a configurable limit (default 10) to prevent unbounded
  state growth. When reached, all pending requests and messages will be flushed
  and logged and one of the new weirds ``LDAP_max_pending_messages_exceeded`` or
  ``LDAP_max_pending_searches_exceeded`` raised.

- The number of data channels per worker is now capped at a configurable
  maximum FTP::max_expected_data_channels (default 100000). When the limit
  is reached, FTP data connection correlation across a Zeek cluster is
  disabled to prevent unbounded state growth and cluster overload until
  expiration removes old entries.

- A UDP Spicy analyzer which replaces a Zeek analyzer will now error instead of
  crashing if it sees TCP traffic. This is possible for DNS, including the
  spicy-dns analyzer (which is an optional, separate component from Zeek).

Deprecated Functionality
------------------------

- The Broker messaging backend is now deprecated. ZeroMQ has been the default
  cluster messaging backend used by zeekctl since Zeek 8.1, and we encourage
  everyone to switch their clusters over to ZeroMQ at this time. We are not
  going to remove Broker with 9.1, but Broker will become a build-time opt-in
  feature over the course of the 9.x cycle and likely see removal in 10.1.

  Third-party applications should focus on Zeek's WebSocket stack for connecting
  into the Zeek cluster, while JavaScript offers support for reaching out to
  HTTP APIs from Zeek scripts.

- Development of the Management Framework has been discontinued and its scripting
  code will be moved into an external package with Zeek 9.1. If you've been deploying
  Zeek clusters using the Management Framework, you can continue to do so with Zeek 9.0,
  but should consider moving to ZeekControl, or preferably explore the newer
  ``zeek.conf`` and ``zeek-systemd-generator`` approach.

  More details and background on this decision are available on the Zeek blog:

	https://zeek.org/2026/08/beyond-zeekcontrol/

- The ``SSL::hash_algorithms`` and ``SSL::signature_algorithms`` tables have been deprecated.
  They are outdated with TLS 1.3, and not used in Zeek. If you currently use these tables,
  you should switch to your own copy of the IANA tables and consider also using the
  TLS SignatureScheme IANA table.

Zeek 8.2.0
==========

We'd like to thank Aaron J. Scantlin (@scantlina), Aashish Sharma (@initconf),
AbdolRashid Forghani (@soorooghadim), Anthony Alayo (@anthonyalayo), Bauti
Peirone (@bautipeirone), @Breppe, @cccs-graeme, @cccs-will, Connor
(@agent-connor), Craig Leres (@leres), @dagecko, Doğukan Çağatay
(@dogukancagatay), Fatema Bannat Wala (@fatemabw), François De Keersmaeker
(@fdekeers), Jan Grashöfer (@J-Gras), Klemens Nanni (@klemensn), Maor Hamami
(@mamaorha), Martin Camara (@martincmr), Michael Peters (@MP-Corelight), Mohan
Dhawan (@Mohan-Dhawan), Octave Charrin (@OctaveCharrin), Peter Cullen
(@pbcullen), @RageAgainstTheOrganic, @siavashta, Steve Smoot (@stevesmoot),
Stefan Götz (@stefangotz), @timo-mue and Zach Robinette (@zrobinette12) for
their contributions to this release.

Breaking Changes
----------------

- The minimum version requirement for ZeroMQ is now 4.3.0. This version has
  been released at the end of 2018 - a good 7 years ago.

- Enums are now nominally typed. Zeek will produce warnings of the following form
  if you have scripts where enum types are mixed.

	Remove in v9.1. Mixing incompatible enum types color and city will become an error.

  With version 9.1, these warnings will become errors. Previously, all enum types were
  compatible with each other, resulting in quirks and making certain optimizations more
  difficult than they should be.

- The ``BifEnum`` namespace was moved to be part of the ``zeek`` namespace for consistency
  with the other namespaces generated by bifcl (``BifType``, ``BifConst``, etc).

- The MetricsAddress option in zeekctl.cfg default was changed from 0.0.0.0 to
  127.0.0.1. If you've been using a remote Prometheus server for metrics scraping
  or run Zeek in a container environment, you'll now need to explicitly set MetricsAddress
  to 0.0.0.0 (or the appropriate listen address) in zeekctl.cfg.

- The packet captures in the btest Traces library have standardized on .pcap and .pcapng
  file suffixes. This may cause breakage in plugins that were using the old .trace suffix.

- The public ``vlan`` and ``inner_vlan`` members within C++ ``Packet`` has changed from
  ``uint32_t`` to an optional VlanTag struct. The corresponding ``dei`` and ``pcp``
  members have been removed and merged into the VlanTag struct. This does not change
  scripts. In order to access the ID as before, check the optional first:

    if ( packet.vlan )
      my_vlan = packet.vlan->id;

  This allows Zeek to properly handle VLAN IDs of 0, which before were handled as if
  there was no VLAN.

- Reverted the change that went into Zeek 8.1 where ASCII control characters < 32
  were encoded as \u00XX in JSON strings to the prior \xXX style. The escaping style
  will become configurable to allow for reliably representing the contained bytes
  in strings with Zeek 9.0.

  See the discussion at https://github.com/zeek/zeek/discussions/5240 for more background
  and feel free to chime in with feedback.

New Functionality
-----------------

- Added a new attribute ``&publish_on_change`` for global tables and sets as an
  alternative to the Broker-specific and deprecated ``&backend`` and ``&broker_store``
  synchronization attributes. The ``&publish_on_change`` attribute allows efficient
  publishing of selected table changes as remote events to a configurable cluster topic.
  Other cluster nodes by default apply received changes to their local table instances.

	# Publish any new entry as Cluster::table_change_infos() event to  /zeek/table/endpoints
	global endpoints: set[addr, addr] &write_expire=5min &publish_on_change=[
	    changes=set(TABLE_ELEMENT_NEW),
	];

  See the online documentation for a detailed description and further examples:

	https://docs.zeek.org/en/master/reference/zeekscript/attributes.html#attr-&publish_on_change

- Well-known ports of built-in analyzers can now be configured via redef. For example:

	redef HTTP::ports += { 8181/tcp };

  For protocol analyzers, the variable name is generally ``Analyzer_Module::ports``,
  but in certain cases (SSL, QUIC, RDP, ...) the variable name includes the protocol
  name to distinguish different internal analyzers. ``SSL::ssl_ports`` and ``SSL::dtls_ports``
  as a concrete example. Check the analyzer module's ``export`` section or online documentation.
  For packet analyzers, the analyzer name is included in the variable name for historical
  reasons. Example:

	redef PacketAnalyzer::VXLAN::vxlan_ports += { 4711/udp };

- The ``dns.log`` now also contains information about DNS notifications (RFC 1996).
  The ``opcode`` is set to 4 and ``opcode_code`` name will be "notify".

- ZeroMQ cluster communication can now be encrypted using the CURVE mechanism built
  into ZeroMQ. This requires a pair of keys, one for the server role and one for
  the client role. The central XPUB/XSUB sockets and LOG pull sockets are configured
  as CURVE servers, all other sockets (the connecting Zeek nodes) as CURVE clients.

  You can generate Z85-encoded keypair as follows with Zeek:

	$ zeek -e 'print to_json(Cluster::Backend::ZeroMQ::generate_keypair())' | jq
	{
	  "public": "}}6zuTySXq(C(6dF#D3Kvt@A5D}LcFlOgVav5{%)",
	  "secret": "h.<[iyv]O#cWdO%2yuLiEJQ}6tC)@HxN6Hp?![td"
	}

  When using ZeekControl, keys are automatically generated and configured when a multi-node
  cluster based on node IP addresses is detected. To force encryption to be always on, set
  the following ZeroMQ specific setting in zeekctl.cfg (default is "auto"):

	cluster_backend_zeromq.use_curve_encryption = 1

  More details and background is available in the
  ``policy/frameworks/cluster/backend/zeromq/main.zeek`` script documentation.

- The number of messages and bytes processed by the central ZeroMQ XPUB/XSUB
  cluster component is now exposed as metrics of the form:

	zeek_cluster_zeromq_proxy_{frontend,backend}_{bytes,messages}_{sent,received}

  by the process running this component in a cluster. Note that Zeek uses multipart
  messages for events: Publishing a single event currently counts as four messages
  as we're simply exposing ZeroMQ's low-level ``zmq::proxy_steerable()`` statistics.

- The ``@load`` directive now supports loading shared object files. This can
  be leveraged to experiment with alternative package and plugin directory layouts
  where a ``__load__.zeek`` file in a directory loads the required shared object
  explicitly rather than the current "magic discovery" via ``ZEEK_PLUGIN_PATH``
  and ``__zeek_plugin__`` files.

  Files are expected to end with ``.so`` regardless of the platform and need to
  be explicitly loaded with the suffix provided:

	@load ./plugin.so

  Such shared objects should instantiate a single zeek::plugin::Plugin instance at
  load time. The zeek::plugin::Plugin() will register it accordingly.

- ``bifcl`` now accepts missing return types in functions signatures, creating
  void functions rather than complaining. The C++ signature will continue
  to have a ``ValPtr`` return type and the implementation should return a ``Val::nil``,
  but the Zeek script function signature will have a void return type.

- The ``&on_change`` attribute for tables or sets now accepts variable argument functions.

- Added the ``modulo`` BiF, which behaves differently from Zeek's ``%`` operator
  for negative numbers.

- Added the ``connection_timing_out`` hook which, if ``break`` is used within, will
  prevent Zeek from timing out a particular connection. The motivation is to align
  a shunted connection's timeout with Zeek. Since Zeek does not see packets from
  a shunted connection, it needs special handling to keep the connection alive while
  shunted.

- The Zeek documentation has received a major refresh. A new tutorial walks newcomers
  through setup, basic Zeek invocations, the use of Zeek packages, ZeekControl for cluster
  maintenance, the basics of Zeek's logs, as well as scripting in Zeek's own language as
  well as JavaScript. A new reference section houses the introduction to common logs, the
  Zeek scripting language, Zeek's frameworks, and the scripting index.

- A new analyzer for IGMP was imported from an external project, originally written by
  François De Keersmaeker (@fdekeers). It adds new events for each of the types of IGMP
  messages, but does not add a new log.

- Windows support has been greatly improved, thanks to a raft of contributions from an
  engineering team at Microsoft. The btest suite now runs on CI builds. The great majority
  of btests pass, with a small number skipped for various documented reasons.

- A new packet source was added that supports reading pcapng files. This supports packet
  captures with multiple interfaces, packet metadata, and capture file metadata. It will
  be automatically used when the magic number in the file header is detected, or if
  ``pcapng::`` is passed as a prefix to the filename with Zeek's ``-r`` argument. It does
  not currently support BPF filtering via Zeek's ``-f`` argument.

Changed Functionality
---------------------

- Protocol parsers implemented in Spicy now suppress analyzer violations when
  a gap occurs and the parser doesn't implement error recovery. The most user
  visible aspect is that the analyzer's identifier is not removed from the
  service column in the ``conn.log``.

- The ``to_subnet()`` built-in function's parsing of IPv6 subnets was changed
  to align with how IPv6 subnet literals are parsed in Zeek scripts. Previously,
  any subnet containing the ``::ffff:0:0/96`` IPv4-mapped prefix would produce
  an IPv4 subnet, even if provided prefix was shorter than the required 96 bits.

  Internally, the behavior of the ``IPPrefix::ConvertString()`` API was changed
  to accommodate for this.

- The ``policy/frameworks/analyzer/detect-protocols`` script now respects analyzer
  violations to suppress ``Server_Found`` or ``Protocol_Found`` for connections which
  first had an analyzer confirmation, but later a analyzer violation happened. Previously,
  Zeek would report a HTTP server when a client issued a HTTP request to an SSH servers,
  or SSL when a client sent a TLS Client Hello to a HTTP server.

- The events ssl_extension_pre_shared_key_server_hello and ssl_extension_pre_shared_key_client_hello
  can now be used independently. Previously, both had to have a handler implemented for
  either of them to actually be invoked due to some logic confusion in the analyzer.

- Zeek new properly handles VLAN IDs of 0. Before, these were simply discarded.

- X.509 parsing now supports additional key types that were not handled previously. The
  certificate key length field will now be filled for additional ciphers, if supported by
  your OpenSSL version (like ML-DSA). Similarly, the key_type field will be filled out for
  additional ciphers, if supported by OpenSSL.

- The SMTP analyzer now forwards the first gap encountered during RFC 822 message analysis
  to the file object. This allows to determine if message analysis stopped due to a gap by
  inspecting the ``missing_bytes`` field during ``file_state_remove()``, or in ``files.log``.

  The SMTP analyzer tears down the active file upon encountering a gap, so the reported
  missing bytes will the gap length only.

Deprecated Functionality
------------------------

- The ``Broker::create_master()``, ``Broker::create_clone()`` and ``Cluster::create_store()``
  builtin functions have been deprecated. Consider using the new ``&publish_on_change``
  attribute on tables for distributing table entries, explicit ``Cluster::publish()`` calls
  with remote events, or using the storage framework for persistence.

  When ZeroMQ is selected as cluster backend, calling any of the above functions
  results in a fatal error as these are all Broker specific.

Zeek 8.1.0
==========

We'd like to thank Andrew Raffman (@andyraf), @arm7mm, Artyom Kalabukhov (@predator89090),
Benjamin Grap (@blightzero), @biswajitutil, @cccs-jsjm, @chrisjlly, Craig P
(@multicast-bytes), @DigiAngel, Mike Dopheide (@dopheide-esnet), Edoardo Mich
(@edoardomich), @franky-m, Fupeng Zhao (@AmazingPP), Jan Grashöfer (@J-Gras), Klemens
Nanni (@klemens-ya), Klemens Nanni (@klemensn), @kshitiz56, Mark Overholser
(@markoverholser), Mohan Dhawan (@Mohan-Dhawan), Peter Cullen (@pbcullen), RyugaXhypeR
(@RyugaXhypeR), Seth Hall (@sethhall), Yacin Nadji (@ynadji), Zhang Liang (@JosenLiang),
Zach Robinette (@zrobinette12) and @zzzdong for their contributions to this release.

Breaking Changes
----------------

- A standalone ``zeek`` invocation on the command line will now default to running a No-op
  Cluster backend (``Cluster::CLUSTER_BACKEND_NONE``). Previously this defaulted to Broker
  without having any real effect. For a multi-process / cluster deployment of Zeek, a
  cluster backend policy script needs to be loaded explicitly.

  Zeekctl has been updated to use the ZeroMQ cluster backend by default and should require
  no other action. If you encounter issues with ZeroMQ, it is possible to re-enable the
  Broker cluster backend by adding the following entry into ``zeekctl.cfg`` and running
  `zeekctl deploy``:

	ClusterBackend = Broker

  Note that ZeroMQ cluster communication is unencrypted and in the clear by default.
  If you're running Zeek on a single host, communication happens via localhost only.
  When running a multi host Zeek setup, Zeekctl will output the following warning,
  informing you about this behavior:

	Warning: ZeroMQ cluster backend enabled and multi-node cluster detected (10.0.0.1, 10.0.0.2).
	Communication between Zeek nodes using ZeroMQ is currently unencrypted. Use Broker with TLS if this
	is concerning to you. ZeroMQ encryption is tracked at https://github.com/zeek/zeek/issues/4432

	You may disable this warning by setting the following option in zeekctl.cfg:

	  cluster_backend_zeromq.disable_unencrypted_warning = 1

  Support for opt-in ZeroMQ encryption is targeted for Zeek 8.2. If this is a
  requirement for your environment, please report and for the time being continue
  using the Broker backend.

  If you manage a non-Zeekctl Zeek setup, load
  ``policy/frameworks/cluster/backend/zeromq`` or
  ``policy/frameworks/cluster/backend/broker``. If you forget to do so, Zeek will
  recognize that ``Cluster::node`` is set (e.g. the ``CLUSTER_NODE`` environment variable
  or ``Cluster::node=...`` is set) but no cluster backend was chosen and will terminate
  with a fatal error:

	fatal error in <...>/main.zeek, line 425: Cluster::node set to 'worker-1', but
	Cluster::backend is Cluster::CLUSTER_BACKEND_NONE - please select a cluster backend to
	use.

  If you used Zeekctl on a single physical system or virtual machine previously, this
  should all be transparent to you.

- The Broker-specific ``&backend`` and ``&broker_store`` attributes will result in startup
  errors when a non-Broker cluster backend is selected. See the entry about their
  deprecation below for more details.

- 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 automatically built as part of the main Zeek build whenever building on Linux.

- The global ``g_frame_stack`` C++ variable was removed. This variable was used to track
  the current stack of script-function frames, mostly for the built-in script debugger. We
  realized that we were also tracking this information in the global ``call_stack``
  variable, used by the script profiler. These two have now been combined together into
  ``call_stack``. Plugins using ``g_frame_stack`` will need to be adapted to use the other
  variable. We opted to not use a deprecation cycle for this due to the complication with
  managing the state across both variables.

- The `unique_id` and `unique_id_from` BIFs now return 96-bit UIDs, which makes them
  consistent with other UIDs created by Zeek such as connection IDs. They were previously
  returning shorter 64-bit UIDs.

- The metrics ``zeek_msgthread_pending_messages_in_buckets`` and
  ``zeek_msgthread_pending_messages_out_buckets`` had labels that did not conform with
  Prometheus' checks via ``promtool``. The labels have been renamed from ``le`` to
  ``leq``, given that they technically are less-than-or-equal values.

- The ``iosource/Packet.h`` header no longer depends on libpcap being installed and no
  longer directly includes the ``pcap.h`` header. This may cause some knock-on effects in
  building plugins that were depending on this header and others that it included
  indirectly.

- External plugins do not implicitly require OpenSSL and Broker anymore. Starting with
  Zeek 8.1, plugins that depend on these libraries are now required to explicitly call
  `find_package(OpenSSL REQUIRED)` and pass `OPENSSL_LIBRARIES` as dependencies to the
  `zeek_add_plugin()` call:

    find_package(OpenSSL REQUIRED)

    zeek_add_plugin(
      ...
      INCLUDE_DIRS
      ${OPENSSL_INCLUDE_DIR}
      DEPENDENCIES
      ${OPENSSL_LIBRARIES}
    )

- We are revisiting removing support for MD5 hashing across the Zeek code base. In support
  of this, the following changes were made:

  - The ``host_key`` field in ssh.log was removed and replaced with a new
    ``host_key_fingerprint`` field. The old field held an MD5 hash of the host key. The
    new field holds a base64-encoded version of the hash of the host key, in the same
    format that the ``ssh-keygen -l`` command would return. It currently uses SHA256 for
    the hashing, so the output is of the format ``SHA256:<fingerprint>``. A new
    ``policy/protocols/ssh/md5-host-key-logging.zeek`` script was added to restore the old
    field if desired.

  - The ``auth_ticket`` and ``new_ticket`` fields in krb.log were removed and replaced
    with new ``auth_ticket_sha256`` and ``new_ticket_sha256`` fields. The old fields held
    MD5 hashes of the tickets and the new fields hold SHA256 hashes of the same. A new
    ``policy/protocols/krb/md5-ticket-logging.zeek`` script was added to restore the old
    fields if desired.

  - A new ``mime_content_hash_sha256`` event was added to send a SHA256 version of the
    content in MIME messages. This is similar to the existing ``mime_content_hash`` event
    that sends MD5 versions.

  - The MD5 IP anonymizers (``RANDOM_MD5`` and ``PREFIX_PRESERVING_MD5``) have been
    deprecated in favor of new SHA256 anonymizers.

  - The ``md5_hmac`` BIF has been deprecated in favor of a new ``sha256_hmac`` BIF.

New Functionality
-----------------

- After recently-merged fixes to the ``node`` formula for Homebrew, JavaScript support via
  ZeekJS can now be built on macOS using that installation of Node.

- 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.

- There exists a new configuration file ``<PREFIX>/etc/zeek/zeek.conf`` and a small
  executable called ``zeek-systemd-generator`` that acts as a systemd unit file
  generator. These two pieces allow for quickly running an opinionated single node cluster
  deployment using systemd. See the ``tools/systemd-generator/README.md`` and
  ``tools/systemd-generator/etc/zeek/zeek.conf`` files for more information.

  If you've previously built Zeek process management by hand or with tools like
  supervisord, runit, s6, etc on Linux, this might be a viable option to explore.

  This is all Linux specific right now. However, the ``zeek.conf`` file is OS-agnostic to
  keep options open for re-use it elsewhere.

- The DNS analyzer now returns the set of parameters for SVCB data. It previously handled
  SVCB packets, but omitted the parameters while parsing.

- The QUIC analyzer now raises a ``QUIC::discarded_packet`` event when a packet with
  ``fixed_bit`` set to 0 is encountered. Such an occurrence is included in the QUIC
  history as ``X``.  This functionality can be controlled with
  ``QUIC::max_discarded_packet_events``. Setting this variable to -1 disables the
  ``QUIC::discarded_packet`` event.

- Added SHA224, SHA384, and SHA512 calculation BiFs: ``sha224_hash``, ``sha224_hash_init`,
  ``sha224_hash_update``, ``sha224_hash_finish``.  ``sha384_hash``, ``sha384_hash_init`,
  ``sha384_hash_update``, ``sha384_hash_finish``.  ``sha512_hash``, ``sha512_hash_init`,
  ``sha512_hash_update``, and ``sha512_hash_finish``.

- Added SHA224, SHA384 and SHA512 file hash analyzers. The analyzers are not enabled by
  default.

- Added the ``TCP::raw_options`` BiF, which returns the list of TCP options in the current
  packet, including their raw data.

- For SNMPv3, Zeek now parses the Security Parameters for the User-Based Security
  model. If present, the data is added to the new ``user_security_parameters`` field of
  the ``SNMP::HeaderV3`` record.

- The QUIC analyzer now raises ``QUIC::short_header_packet_threshold_crossed()`` for every
  binary logarithmic threshold for QUIC packets with short headers. Each threshold is
  added to the history as ``O`` or ``o``. E.g., a history containing ``oOoO`` indicates
  that originator and responder each send at least 3 short packets, while ``oOOoooooo``
  would indicate the originator sent at least 3 short packets early in the connection,
  while the responder sent at least 127 packets.

- Added SHA256 calculation BiFs: ``sha512_hash``, ``sha512_hash_init`,
  ``sha512_hash_update``, and ``sha512_hash_finish``.

- Added VLAN PCP and DEI bits when parsing packets. This is exposed alongside ``vlan`` and
  ``inner_vlan`` in a packet's ``l2_hdr`` when scripting, if a VLAN header was present.

- The DNS analyzer now supports parsing Dynamic Update messages (RFC 2136) and reporting
  information about them into ``dns.log``. The ``answer`` field in the log will contain
  the prerequisites and updates for the dynamic update requests, whereas the ``query``
  field logs the zone name for the update request.

  This also adds new ``opcode`` and ``opcode_name`` fields to the DNS log. Previously Zeek
  was only handling opcode 0 (normal requests) so that information wasn't pertinent, but
  with the addition of dynamic updates we're now handling a second opcode. The new policy
  script ``policy/protocols/dns/disable-opcode-log-fields.zeek`` can be loaded to remove
  these fields from the log if they are not desired.

  As part of these additions, an extra field ``is_netbios`` was added to the the
  ``dns_msg`` script-layer record. This boolean flag is ``T`` if the DNS message is from
  NetBIOS, and ``F`` if the message is standard DNS.

- The `policy/misc/dump-events.zeek` script now features a ``DumpEvents::use_json``
  boolean toggle, false by default, to report Zeek's events in JSON format.

- The list of HTTP methods accepted by dynamic protocol detection was updated to add some
  missing methods: BIND, LINK, MKCALENDAR, MKREDIRECTREF, REBIND, UNBIND, UNLINK.

- The Docker images generated by Zeek's CI process now contain OCI-approved annotation
  labels containing various metadata about the image. See
  https://github.com/opencontainers/image-spec/blob/main/annotations.md for more details
  about the labels.

- A new BIF ``Log::flush_all`` was added that causes all logs to be written to disk
  immediately.

Changed Functionality
---------------------

- A Zeekctl-managed Zeek cluster now uses the ZeroMQ cluster backend by default.

- The manager node of a Zeekctl-managed Zeek cluster now listens on 127.0.0.1:27759 for
  WebSocket connections by default. This can be disabled with the ``UseWebSocket`` setting
  in ``zeekctl.cfg``, or adapted using the ``WebSocketHost`` and ``WebSocketPort``
  settings.

- The var-extraction-uri.zeek policy does not include the path in the ``uri_vars`` field
  anymore.

- The ``get_current_packet_header()`` BIF now populates the returned record also for
  fragmented IP datagrams.

- The QUIC parser discards packets with the ``fixed_bit`` field set to 0, rather than
  continuing to parse and potentially running into analyzer violations.

- The Notice framework's suppression implementation was changed to batch suppression
  information for up up to 10msec before distributing it to other nodes in a Zeek cluster.
  This reduces cluster communication overhead when there's a storm of notices
  generated. Two new options, ``Notice::suppression_batch_period`` and
  ``Notice::suppression_batch_max_size`` can be used to tune this behavior. See their
  documentation for details. This most notably reduces CPU usage and cluster event traffic
  during cluster startup.

- Non-printable ASCII control characters now always result in ``\uXXXX`` characters when
  logging them as JSON. This follows the JSON standard more closely. Previously, they
  would have been logged in the ``\xXX`` format that Zeek typically uses. For example, an
  HTTP request with a non-printable character in the URI would have a ``uri`` field that
  changes from:

    "uri":"/non_printable_\\x07"

  to

    "uri":"/non_printable_\u0007"

- For SNMPv3, the ``community`` field of ``snmp.log`` now contains the SNMPv3 username (if
  present). Previously, the field was empty for all SNMPv3 connections.

- The ``x509.log`` deduplication logic has been reimplemented with explicit calls to
  ``Cluster::publish()``, rather than relying ``&backend`` tables using Broker.

- Sanitizer flags passed to a Zeek build with ``configure``'s ``--sanitizers`` argument
  are now automatically passed to plugins built against that Zeek source tree.

- The ``hash-all-files`` policy script now enables SHA256 logging, in addition to MD5 and
  SHA1.

- The LDAP analyzer was fixed to correctly escape non-ASCII characters when logging filter
  strings.

- The AF_Packet packet source now reports a warning if you attempt to use it on a loopback
  interface. This is because AF_PACKET will receive duplicates of every packet when run on
  a loopback interface and this can be confusing.

- The GSSAPI analyzer gained some fixes to reliably process Kerberos data when that data
  isn't preceded by an OID. This is valid a ASN.1 structure that wasn't being handled
  correctly.

- SSL certificates are now correctly logged even when protocol violations occur, assuming
  the certificate was encountered prior to the violation.

Deprecated Functionality
------------------------

- The ``&backend`` and ``&broker_store`` attributes for script-layer tables have been
  deprecated. These are only functional with the Broker cluster backend and their
  semantics and guarantees considered too loose. There is ongoing discussion and
  experiments how to provide state propagation and synchronization across cluster
  processes. Explicit topic-based state propagation using ``Cluster::publish()``, or
  switching to the storage framework for persistence are available today.

  If you've used ``&backend`` and ``&broker_store`` in your scripts and find it hard or
  inconvenient to replace them, please reach out with your use-cases, on GitHub or
  Slack. We're happy to support.

  Some references to GitHub discussion and prototypical ideas:

	https://github.com/zeek/zeek/discussions/5020
	https://github.com/zeek/zeek/pull/5040

- In Zeek 9.1, returning a value from a hook will become an error. Return values from a
  hooks were previously silently discarded. This behavior was found surprising in relation
  with the ``break`` statement available in hooks.

- The ``zeek::util::json_escape_utf8`` methods are being replaced by a new ``escape_utf8``
  method in order to fix a bug with how the ``escape_printable_controls`` argument was
  implemented. Previously, it was implemented in the reverse of what was intuitive given
  the name. It would escape the control characters when false, and not escape them when
  true. The new method has the correct semantics, as well as a new argument for
  controlling whether non-printable control characters are escaped.

- The ``zeromq/connect`` script has been deprecated. Load the
  ``frameworks/cluster/backend/zeromq`` package directly instead.

- The ``rfb_auth_result`` event from the RFB analyzer was deprecated and replaced with a
  new ``rfb_authentication_result`` event. This new event sets the correct value in the
  ``rfb$auth`` field in the connection.

Zeek 8.0.0
==========

We would like to thank @aidans111, Anthony Verez (@netantho), Baa (@Baa14453),
Bhaskar Bhar (@bhaskarbhar), @dwhitemv25, EdKo (@ephikos), @edoardomich, Fupeng
Zhao (@AmazingPP), hendrik.schwartke@os-s.de (@hendrikschwartke), @i2z1, Jan
Grashöfer (@J-Gras), @cccs-jsjm, Justin Azoff (@JustinAzoff), Mario D
(@mari0d), Markus Elfring (@elfring), Peter Cullen (@pbcullen), Sean Donaghy,
Simeon Miteff (@simeonmiteff), Steve Smoot (@stevesmoot), @timo-mue,
@wojciech-graj, and Xiaochuan Ye (@XueSongTap) for their contributions to this
release.

Breaking Changes
----------------

- Zeek by default now depends on the availability of the ZeroMQ library for building
  and running. This is in preparation of switching to the ZeroMQ-based cluster backend
  by default in future Zeek versions. On an Ubuntu based system, the required system
  packages are ``libzmq5``, ``libzmq3-dev`` and ``cppzmq-dev``. See the Dockerfiles
  in the ``ci/`` directory for other supported platforms.

- Zeek and all of its associated submodules now require C++20-capable compilers to
  build. This will let us move forward in using more modern C++ features and replace some
  workarounds that we have been carrying. Minimum recommended versions of compilers are
  GCC 10, Clang 8, and Visual Studio 2022.

- The ``zeek::Span`` class has been deprecated and the APIs in the telemetry subsystem
  switched to use ``std::span`` instead of ``zeek::Span``. If your plugin instantiates
  counter or gauge instances using the telemetry subsystem and you've previously used
  ``zeek::Span`` explicitly, updates may be needed.

- The code base underwent a big cleanup of #include usage, across almost all of the
  files. We tested builds of all of the existing third-party packages and only noticed one
  or two failures, but there is a possibility for breakage related to this cleanup.

- The ``lookup_connection()`` and ``connection_exists()`` builtin functions
  now require ``conn_id`` instances as argument, rather than internally supporting
  duck type matching ``conn_id``-like records.

- Network timestamps are not added to events by default anymore. Use the following
  redef line to enable them:

	redef EventMetadata::add_network_timestamp = T;

  The background is that event metadata has become more generic and may incur
  a small overhead when enabled. There's not enough users of network timestamp
  metadata to justify the complexity of treating it separate.

- The ASCII writer's ``JSON::TS_MILLIS`` timestamp format was changed to produce
  signed integers. This matters for the representation for timestamps that are
  before the UNIX epoch. These are now written as negative values, while previously
  the negative value was interpreted as an unsigned integer, resulting in very large
  timestamps, potentially causing issues for downstream consumers.

  If you prefer to always have unsigned values, it's possible to revert to the previous
  behavior by setting:

	redef LogAscii::json_timestamps = JSON::TS_MILLIS_UNSIGNED;

- The "endpoint" label of metrics exposed via Prometheus or the ``telemetry.log``
  was renamed to "node". This is done for consistency with cluster terminology:
  The label values have always been the value of ``Cluster::node`, so it's more intuitive
  to call it. The "endpoint" name originated from a time when the telemetry framework
  was implemented in Broker.

  To revert to the "endpoint" label, you can do the following, but we strongly
  suggest to migrate to the new default "node" instead:

	redef Telemetry::metrics_endpoint_label = "endpoint";

- The ``current_event_time()`` builtin function as well as ``Event::Time()``
  and ``EventMgr::CurrentEventTime()`` now return ``-1.0`` if no timestamp
  metadata is available for the current event, or if no event is being
  dispatched. Previously this would've been 0.0, or the timestamp of the previously
  dispatched event.

- Missing network timestamp metadata on remote events is not set to the local
  network time anymore by default. This potentially hid useful debugging information
  about another node not sending timestamp metadata. The old behavior can be
  re-enabled as follows:

	redef EventMetadata::add_missing_remote_network_timestamp = T;

- The ``IsPacketSource()`` method on ``IOSource`` was removed. It was unused
  and incorrectly returned ``false`` on all packet sources.

- The ``--with-binpac`` and ``--with-bifcl`` arguments for ``configure`` are now
  deprecated.  Both arguments have for a long time just used the internal version of the
  tooling even if something was passed, so they were mostly useless. This may cause
  breakage of cross-compiling, where the ``binpac`` and ``bifcl`` tooling needs to be run
  on the host machine. We haven't heard from anyone that this is the case with the
  arguments in their currently-broken state.

- The parsing of data for the ``ssl_session_ticket_handshake`` event was fixed.
  In the past, the data contained two extra bytes before the session ticket
  data. The event now contains only the session ticket data. You might have to
  adjust your scripts if you manually worked around this bug in the past.

New Functionality
-----------------

- Zeek now supports pluggable and customizable connection tracking. The default
  behavior remains unchanged and uses a connection's five tuple based on the
  IP/port pairs and proto field. Zeek 8 ships with one additional implementation,
  to factor VLAN tags into the connection tracking. To switch to VLAN-aware
  connection tracking:

	@load frameworks/conn_key/vlan_fivetuple

  By convention, additional fields used by alternative ConnKey implementations are
  added into the new ``ctx`` field of ``conn_id``. The type of ``ctx`` is ``conn_id_ctx``.

  The ``vlan_fivetuple`` script adds two additional fields to the ``conn_id_ctx``
  record type, representing any VLAN tags involved. Accordingly, every log
  using ``conn_id`` reflects the change as well as ``ctx`` and the VLAN fields have
  the ``&log`` attribute. The columns used for logging will be named ``id.ctx.vlan``
  and ``id.ctx.inner_vlan``.

  This feature does not automatically provide a notion of endpoint that
  corresponds with the effective connection tuple. For example, applications tracking
  endpoints by IP address do not somehow become VLAN-aware when enabling
  VLAN-aware tracking.

  Users may experiment with their own notion of endpoint by combining the ``orig_h``
  or ``resp_h`` field of ``conn_id`` with the new ``ctx`` field. For example, tracking
  the number of connections from a given host in a VLAN-aware fashion can be done
  as follows:

	global connection_counts: table[conn_id_ctx, addr] of count &default=0;

	event new_connection(c: connection) {
		++connection_counts[c$id$ctx, c$id$orig_h];
	}

  Note that this script snippet isn't VLAN-specific, yet it is VLAN-aware if the
  ``vlan_fivetuple`` script is loaded. In future Zeek versions, this pattern is
  likely to be used to adapt base and policy scripts for more "context awareness".

  Users may add their own plugins (for example via a zkg package) to provide
  alternative implementations. This involves implementing a factory for
  connection "keys" that factor in additional flow information. See the VLAN
  implementation in the ``src/packet_analysis/protocol/ip/conn_key/vlan_fivetuple``
  directory for an example.

- Added support to ZeekControl for seamlessly switching to ZeroMQ as cluster
  backend by adding the following settings to zeekctl.cfg:

	ClusterBackend = ZeroMQ
	UseWebSocket = 1

  With the ZeroMQ cluster backend, Zeekctl requires to use Zeek's WebSocket API
  to communicate with individual nodes for the ``print`` and ``netstats`` commands.
  Setting the ``UseWebSocket`` option enables a WebSocket server on the manager
  node, listening on 127.0.0.1:27759 by default (this is configurable with using
  the newly introduced ``WebSocketHost`` and ``WebSocketPort`` options).
  The ``UseWebSocket`` option can also be used when ``ClusterBackend`` is set
  to ``Broker``, but isn't strictly required.

  For ZeroMQ (or other future cluster backends), setting ``UseWebSocket`` is a
  requirement as Zeekctl does not speak the native ZeroMQ protocol to communicate
  with cluster nodes for executing commands. This functionality requires the
  ``websockets`` Python package with version 11.0 or higher.

- Cluster telemetry improvements. Zeek now exposes a configurable number of
  metrics regarding outgoing and incoming cluster events. By default, the number
  of events sent and received by a Zeek cluster node and any attached WebSocket
  clients is tracked as four individual counters. It's possible to gather more
  detailed information by adding ``Cluster::Telemetry::VERBOSE`` and
  ``Cluster::Telemetry::DEBUG`` to the variables ``Cluster::core_metrics`` and
  ``Cluster::webscoket_metrics``:

	redef Cluster::core_metrics += { Cluster::Telemetry::VERBOSE };
	redef Cluster::websocket_metrics += { Cluster::Telemetry::DEBUG };

  Configuring verbose, adds metrics that are labeled with the event handler
  and topic name. Configuring debug, uses histogram metrics to additionally track
  the distribution of the serialized event size. Additionally, when debug is selected,
  outgoing events are labeled with the script location from where they were published.

- Support for the X-Application-Name HTTP header was added to the WebSocket API at
  ``v1/messages/json``. A WebSocket application connecting to Zeek may set the
  X-Application-Name header to a descriptive identifier. The value of this header
  will be added to the cluster metrics as ``app`` label. This allows to gather
  incoming and outgoing event metrics of a specific WebSocket application, simply
  by setting the X-Application-Name header.

- The SMTP analyzer can now optionally forward the top-level RFC 822 message individual
  SMTP transactions to the file analysis framework. This can be leveraged to extract
  emails in form of ``.eml`` files from SMTP traffic to disk.

  To enable this feature, set the ``SMTP::enable_rfc822_msg_file_analysis`` option
  and implement an appropriate ``file_new()`` or ``file_over_new_connection()`` handler:

	redef SMTP::enable_rfc822_msg_file_analysis = T;

	event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) {
		if ( f$id == c$smtp$rfc822_msg_fuid )
			Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename="email"]);
	}


- Generic event metadata support. A new ``EventMetadata`` module was added allowing
  to register generic event metadata types and accessing the current event's metadata
  using the functions ``current()`` and ``current_all()`` of this module.

- A new plugin hook, ``HookPublishEvent()``, has been added for intercepting
  publishing of Zeek events. This hook may be used for monitoring purposes,
  modifying or rerouting remote events.

  Plugins can implement and enable this hook by calling the following method
  within their Configure() implementation.

	EnableHook(HOOK_PUBLISH_EVENT)

  The signature of ``HookPublishEvent()`` is as follows.

	bool HookPublishEvent(zeek::cluster::Backend& backend,
	                      const std::string& topic,
	                      zeek::cluster::detail::Event& event);

- Zeek now includes the Redis protocol analyzer from the evantypanski/spicy-redis
  project (https://github.com/evantypanski/spicy-redis). This analyzer is enabled
  by default. This analyzer logs Redis commands and their associated replies in
  ``redis.log``.

  To disable the analyzer in case of issues, use the following snippet:

	redef Analyzer::disabled_analyzers += {
		Analyzer::ANALYZER_REDIS,
	};

- The FTP analyzer now supports explicit TLS via AUTH TLS.

- Two new script-level hooks in the Intel framework have been added.

	hook indicator_inserted(indicator_value: string, indicator_type: Intel::Type)

	hook indicator_removed(indicator_value: string, indicator_type: Intel::Type)

  These are reliably invoked on worker and manager nodes the first time an
  indicator value is inserted into the store and once it has been completely
  removed from the store.

- The ``frameworks/intel/seen`` scripts have been annotated with event groups
  and a new ``frameworks/intel/seen/manage-event-groups`` policy script added.

  The motivation is to allow Zeek distributors to load the ``intel/seen`` scripts
  by default without incurring their event overhead when no Intel indicators are
  loaded. Corresponding event handlers are enabled once the first Intel indicator
  of a given ``Intel::Type`` is added. Event handlers are disabled when the last
  indicator is removed, again.

  Note that the ``manage-event-groups`` script interacts with the ``Intel::seen_policy``
  hook: If no indicators for a given ``Intel::Type`` are loaded, the ``Intel::seen_policy``
  will not be invoked as the event handlers extracting indicators aren't executed.

  If you rely on the ``Intel::seen_policy`` hook to be invoked regardless of the
  contents of the Intel store, do not load the ``manage-event-groups`` or set:

	redef Intel::manage_seen_event_groups = F;

- The DNS analyzer was extended to support NAPTR RRs (RFC 2915, RFC 3403).
  A corresponding ``dns_NAPTR_reply`` event was added.

- A new ``get_tags_by_category`` BIF method was added that returns a list of tags for a
  specified plugin category. This can be used in lieu of calling ``zeek -NN`` and
  parsing the output. For example, this will return the list of all analyzer plugins
  currently loaded:

    get_tags_by_category("ANALYZER");

- A new ``conn_generic_packet_threshold_crossed`` event was introduced. The event triggers
  for any IP-based session that reaches a given threshold. Multiple packet thresholds can
  be defined in ``ConnThreshold::generic_packet_thresholds``. The generic thresholds refer
  to the total number of packets on a connection without taking direction into account
  (i.e. the event also triggers on one-sided connections).

  The event is intended as an alternative to the ``new_connection`` event that allows for
  ignoring short-lived connections like DNS or scans. For example, it can be used to set
  up traditional connection monitoring without introducing overhead for connections that
  would never reach a larger threshold anyway.

- 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.

  The ``conn/pppoe-session-id-logging.zeek`` policy script adds pppoe session IDs to the
  connection log.

  The ``get_conn_stats()`` function's return value now includes the number of packets
  that have not been processed by any analyzer. Using data from ``get_conn_stats()`` and
  ``get_net_stats()``, it's possible to determine the number of packets that have
  been received and accepted by Zeek, but eventually discarded without processing.

Changed Functionality
---------------------

- The `Conn::set_conn` function is now always run in `new_connection`, instead of only
  being run in `connection_state_remove`.

- Logging of failed analyzers has been overhauled. `dpd.log` was replaced
  by a new `analyzer.log` that presents a more unified and consistent view
  of failed analyzers. The previous `analyzer.log` was renamed to `analyzer-debug.log`;
  see below for more details.

  For protocol analyzers, `analyzer.log` now reports initially confirmed analyzers that
  Zeek subsequently removed from the connection due to a protocol violation.

  For file and packet analyzers, all errors will be logged to `analyzer.log`.

  As part of this work, a new `analyzer_failed` event has been introduced. This event
  is raised when an analyzer is removed because of raising a violation.

- `analyzer.log` was renamed to `analyzer_debug.log`, and is no longer created
  by default. The log file will be created if the `frameworks/analyzer/debug-logging.zeek`
  policy script is loaded.

  Note that the namespace for options in the script changed to
  `Analyzer::DebugLogging`. Furthermore the default options changed to enable
  more detailed output by default.

- Record fields with a ``&default`` attribute are now consistently re-initialized
  after deleting such fields. Previously, this would only work for constant
  expressions, but has been extended to apply to arbitrary expressions.

- Publishing remote events with vector arguments that contain holes is now
  rejected. The receiver side never had a chance to figure out where these
  holes would have been. There's a chance this breaks scripts that accidentally
  published vectors with holes. A reporter error is produced at runtime when
  serialization of vectors with holes is attempted.

- Kerberos support on macOS has been enabled. Due to incompatibilities, the system
  provided libkrb5 is ignored, however. Only versions from homebrew are supported and
  found/picked-up by default. Use --with-krb5 for pointing at a custom librkb5
  installation.

- The ``$listen_host`` configuration for ``Cluster::listen_websocket()``'s
  ``WebSocketServerOptions`` was deprecated. Use the new ``$listen_addr`` field
  instead.

- The `service_violation` field of the connection record was marked as deprecated.
  Consider using the new `failed_analyzers` field of the connection record instead.

- `detect-protocol.zeek was the last non-deprecated policy script left in
  `frameworks/dpd`.  It was moved to `frameworks/analyzer/detect-protocol.zeek`.

- Running Zeek with Zeekygen for documentation extraction (-X|--zeekygen
  <cfgfile>) now implies -a, i.e., parse-only mode.

- The `not_valid_before` and `not_valid_after` times of X509 certificates are
  now logged as GMT timestamps. Before, they were logged as local times; thus
  the output was dependent on the timezone that your system is set to.
  Similarly, the related events and the Zeek data structures all interpreted
  times in X509 certificates as local times.

- The PPPoE parser now respects the size value given in the PPPoE header. Data
  beyond the size given in the header will be truncated.

- Record fields with ``&default`` attributes initializing empty ``vector``, ``table``
  or ``set`` instances are now deferred until they are accessed, potentially
  improving memory usage when such fields are never accessed.

- The handling of truncated 802.3 Ethernet frames changed. Before, truncated 802.3 frames
  were always discarded. Now, truncated 802.3 Ethernet frame data is forwarded to downstream
  analyzers. This aligns the handling of 802.3 Ethernet frames with the (much more common)
  Ethernet 2 frames which are forwarded when truncated.

  Due to this change, the ``truncated_vlan_frame`` was removed. 802.3 frames with a truncated
  header now raise the ``truncated_VLAN_header`` weird, which is similarly raised by Ethernet 2
  frames with a truncated VLAN header.

- Data beyond the length indicated in the header of an 802.3 Ethernet frame is no longer
  forwarded to downstream analyzers. This aligns our handling of 802.3 Ethernet frames with
  other protocols that have length headers.

Removed Functionality
---------------------

- The ``--with-bind`` argument for ``configure`` was removed. We removed the need for the
  BIND library from our CMake setup in the v7.2 release, but this non-functional argument
  was left behind.

- The ``--disable-archiver`` argument for ``configure`` was removed. This was deprecated
  and scheduled to be removed in v7.1, but we apparently missed it during the cleanup for
  that release.

Deprecated Functionality
------------------------

- The `dpd.log` is now deprecated and replaced by `analyzer.log` (see above).
  `dpd.log` is no longer created by default, but can be loaded using the
  `frameworks/analyzer/deprecated-dpd-log.zeek` policy script.

  Relatedly, the `service_violation` field of the connection record is
  deprecated and will only be present if the
  `frameworks/analyzer/deprecated-dpd-log.zeek` policy script is loaded.

- The ``protocols/http/detect-sqli.zeek`` script has been deprecated in favor of a
  new ``protocols/http/detect-sql-injection.zeek`` script to switch from the victim
  host being placed into the ``src`` field of a notice to instead use ``dst``.
  The attacker host is now placed into ``src``. Further, notices hold the first
  sampled connection uid.

  Note that the ``Notice::Type`` enumeration names remain the same. You can determine
  which script was used by the presence of populated ``uid`` and ``dst`` fields in the
  ``notice.log`` entries.

  The replacement script doesn't populate the ``email_body_sections`` anymore either.

- Using ``&default`` and ``&optional`` together on a record field has been deprecated
  as it would only result in ``&default`` behavior. This will become an error starting
  with Zeek 8.1.

- The ``zeek::Event()`` constructor was deprecated. Use ``event_mgr::Enqueue()``
  or ``event_mgr::Dispatch()`` instead.

- Passing ``ts`` as the last argument to ``EventMgr::Enqueue()`` has been deprecated
  and will lead to compile time warnings. Use ``EventMgr::Enqueue(detail::MetadataVectorPtr meta, ...)``
  for populating ``meta`` accordingly.

- For plugin authors: in the core, the constructor for Connection instances has
  been deprecated in favor of a new one to support pluggable connection
  tuples. The ConnTuple struct, used by this deprecated Connection constructor,
  is now deprecated as well.


- The ``zeek::filesystem`` namespace alias is deprecated in favor of using
  ``std::filesystem`` directly. Similarly, the ``ghc::filesystem`` submodule stored in
  ``auxil/filessytem`` has been removed and the files included from it in the Zeek
  installation will no longer be installed. Builds won't warn about the deprecation of
  ``zeek::filesystem`` due to limitations of how we can mark deprecations in C++.

- The ``zeek::util::starts_with`` and ``zeek::util::ends_with`` functions are deprecated.
  ``std::string`` and ``std::string_view`` added ``begins_with`` and ``ends_with`` methods
  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
==========

We would like to thank Aashish Sharma (@initconf), Anthony Verez (@netantho), Anthony
Kasza (@anthonykasza), @biswajitutil, Brendan Kapp (@BrendanKapp), Carlos Lopez, Chris
Hinshaw (@MMChrisHinshaw), Faan Rossouw (@faanross), @FishyFluffer, Fupeng Zhao
(@AmazingPP), Herbert (@Herbert-Karl), @jbaggs, Jan Grashöfer (@J-Gras), Julian Krieger
(@juliankrieger), Justin Azoff (@JustinAzoff), Kshitiz Bartariya (@kshitiz56), @Laotree,
Mark Overholser (@markoverholser), Mike Dopheide (@dopheide-esnet), @mnhsrj, Mohan Dhawan
(@Mohan-Dhawan), @philipp-tg, Seth Hall (@sethhall), and @timo-mue for their contributions
to this release.

Breaking Changes
----------------

- The ``is_remote_event()``, ``current_analyzer()`` and ``current_event_time()`` builtin
  functions do not return the previous event's values anymore when event draining has
  completed. The same applies to the corresponding C++ accessors on the ``EventMgr``
  class. The functions now return false, 0 or the zero time instead.

- The ``to_int()`` built-in function was changed to match the return behavior of
  ``to_count()``. Previously, ``to_int()`` would silently ignore invalid inputs and return a
  ``0``. It now returns an error instead.

New Functionality
-----------------

- The following dependencies have had updates:

  - The bundled version of c-ares has been updated to v1.34.5.

  - The bundled version of ZeekJS has been updated to v0.17.0.

- Some DNS events are not raised when ``dns_skip_all_addl`` is set to true.  Zeek now
  raises a warning when a script declares these events while this option is set to true.

- Types can now be used as constants in Zeek script. This allows types to be directly
  passed into BIFs without aliasing.

- A new ``enc_part`` field was added to the Kerberos ``KRB_Response`` record passed as
  part of the ``krb_as_response`` event. This field contains the encrypted session
  information from a Kerberos response, including the cipher and encrypted data.

- Geneve tunnel options of the current packet can be extracted from scripts using the new
  ``PacketAnalyzer::Geneve::get_options()`` builtin function.

- The new ``is_valid_subnet()`` function mirrors ``is_valid_ip()``, for subnets.

- A new Storage framework was merged into the Zeek tree. The intention with this framework
  is to eventually replace the storage functionality that Broker provides, including
  direct storage via calls such as ``Cluster::create_store`` and ``Broker::put_unique`` as
  well as storage-backed tables via the ``&backend`` attribute. This is an initial version
  for testing, and will be expanded upon in the future. The current state of the framework
  is as follows:

  - A new API was added for storage backend plugins.

  - Script-level functions for opening and closing backends, and insertion, retrieval, and
    erasure of elements are available.

  - Backends can support both asynchronous mode (using ``when`` statements) and
    synchronous mode (blocking until the operation completes). BIF methods were added
    under new ``Storage::Async`` and ``Storage::Sync`` modules for these two modes. The
    modes can be used interchangeably with the same backend handle.

  - SQLite and Redis backends exist in the Zeek tree by default. We are working on a
    backend for NATS that will be available as an external plugin, but it is not quite
    ready yet. Both of the existing backends support usage in a cluster environment.

- Improved alternative cluster backend support.

  The ZeroMQ cluster backend added in Zeek 7.1 has received various correctness,
  performance and robustness fixes, particularly concerning shutdown and high-load
  scenarios.

  Initial performance testing indicates less CPU time used on a large single node
  instance with high logging and eventing rates.

  We're evaluating switching the default cluster backend from Broker to ZeroMQ With
  Zeek 8.1. Therefore, we welcome early adopters and testers to validate ZeroMQ as an
  alternative to Broker. If you're not using Broker specific integrations (e.g. Broker's
  Python or C++ bindings) and run a single-node Zeek cluster, switching to ZeroMQ
  should be as simple as loading the following script on each of cluster node.

	@load frameworks/cluster/backend/zeromq/connect

  A proof-of-concept plugin for the open-source NATS messaging system is available at
  https://github.com/zeek/zeek-cluster-backend-nats for testing and experimentation.

- Broker now exposes more information through ``broker.log``. Broker generated log
  messages are now propagated as events to Zeek. This allows exposing more information for
  debugging and operational behavior of Broker via Zeek logs.  Two new script-level
  options ``Broker::log_severity_level`` and ``Broker::log_stderr_severity_level`` have
  been introduced to control the which events to expose by default.

- Broker's new per-peer send buffer backpressure handling, introduced in 7.1,
  has received several updates. We've increased the default buffer sizes to 8192
  messages for both peers and websockets, and switched the default overflow
  handling policy to "drop_oldest", meaning that in a full buffer the oldest
  message enqueued gets dropped to allow enqueuing a new one. Three additional
  metrics are available to understand the health of each peering's buffer,
  regardless of the overflow policy active. These are:

  - zeek_broker_peer_buffer_messages: a gauge of the current buffer fill level,

  - zeek_broker_peer_buffer_recent_max_messages: a gauge that tracks the maximum
    buffer fill level seen over the last ``Broker::buffer_stats_reset_interval`.

  - zeek_broker_peer_buffer_overflows_total: a counter that tracks the number
    of times a given peering's send buffer has overflowed. For the "drop_oldest"
    and "drop_newest" policies, this is the count of messages dropped.

  Each of these is labeled with the current endpoint and the peer's, as provided
  by the cluster topology.

- New WebSocket functionality was added to Zeek's cluster component.

  Users of Broker's WebSocket interface should replace their ``Broker::listen_websocket()``
  usage with ``Cluster::listen_websocket()``. The latter will support any cluster
  backends, while ``Broker::listen_websocket()`` is specific to Broker.

  A crucial difference between these two methods is that ``Cluster::listen_websocket()``
  will have TLS disabled by default, while Broker usually defaults to TLS enabled.
  If you require a TLS configuration for your WebSocket deployment, pass an appropriate
  ``WebSocketTLSOptions`` record or setup a TLS reverse proxy in front of Zeek.

  For WebSocket clients, there should not be an observable difference in behavior
  regarding the handshake and publishing of events. However, the implementation uses
  a different code path and supporting library (machinezone/IXWebSocket). If you
  observe any differences in behavior, please report these as regressions.
  Note that the new ``Cluster::listen_websocket()`` API will only become stable
  with Zeek 8.0.

  Two new events, ``Cluster::websocket_client_added()`` and ``Cluster::websocket_client_lost()``,
  have been added for WebSocket clients connecting and disconnecting. Note that
  currently, even after ``Cluster::websocket_client_lost()`` ran, events sent from
  that client may still be in transit and later executed, even on the node running
  the WebSocket server.

- Vectors containing ``pattern`` values can now be compared using ``==`` and ``!=`` in
  scripts. This previously resulted in a fatal error.

- The set of non-routable subnets defined in ``Site::private_address_space`` was expanded
  to include ``239.0.0.0/8``, ``224.0.0.0/24`, ``[2002:e000::]/40``, ``[2002:ef00::]/24``,
  and ``[fec0::]/10`. These addresses come from RFCs 2365, 3058, 3879, and 5771. This may
  result in traffic being considered as local traffic that wasn't previously.

- The ``to_count()`` and ``to_int()`` built-in functions now trim trailing spaces passed
  in the argument. They were already trimming leading spaces.

- The ``ip_proto`` field is now populated for a connection encapsulated in a tunnel.

- The documentation for ZeekJS is now included in the main Zeek documentation (as seen on
  https://docs.zeek.org) by default.

- Searching for the headers for libkrb5 was made more robust. Additionally, the
  restrictions on using libkrb5 only on Linux platforms was removed. CMake will now search
  for it on all platforms as expected.

- The HTTP analyzer now checks for the HTTP-name field to be case-insensitive, even though
  the spec specifies that field must be uppercase. If a non-uppercase string is
  encountered, a new ``lowercase_HTTP_keyword`` weird is emitted.

Changed Functionality
---------------------

- The ``service`` field in the connection log is now sorted in the order that protocol
  analyzers raise their confirmation events.  Since the time at which the protocol
  confirmation is raised depends on the individual implementation of each analyzer, there
  is no specific meaning to the order that the services appear. However, the order should
  be deterministic between runs. It also will in many cases represent the order in which
  layered protocols are parsed (e.g. "quic,ssl").

- The way that protocol violations are handled by the dynamic protocol detection (DPD)
  changed. Now, a violation that is raised by an analyzer before it is confirmed will
  immediately disable the analyzer. This adjusts the behavior back to the historically
  desired state, and aligns it with the treatment of confirmed analyzers.

  As a consequence of this, the option ``DPD::max_violations`` is no longer used.
  It will be retained till Zeek 8.1 to prevent script errors, and raises a
  deprecation warning.

  To extend the visibility of protocol violations, a new option
  ``DPD::track_removed_services_in_connection`` was added. Enabling it causes failed
  analyzers to no longer be removed from the ``service`` field of the connection
  log. Instead, analyzers are never removed after they are confirmed.  Instead, failed
  analyzers are logged by additionally adding an entry with a prepended "-". So a
  connection that attached the ``ssl`` analyzer which later failed due to a protocol error
  will be logged as ``ssl,-ssl``.

  This change also adds a new policy script,
  ``protocols/conn/failed-service-logging.zeek``. Loading this script adds the column
  ``failed_service`` to the connection.log. This column contains the list of protocol
  analyzers that failed due to a protocol error.

- Command line options processing will no longer print usage whenever there is an
  error. Instead, issues in command line processing will print an error, then prompt to
  use --help. The --help usage will now print to standard output rather than standard
  error.

- Saving seeds with ``--save-seeds`` will now put Zeek into deterministic mode.  A
  subsequent ``--load-seeds`` run with the same scripts and traces will produce identical
  UID values as the original ``--save-seeds` run.

- The `policy/protocols/dns/detect-external-names.zeek` script now no longer logs names
  that were found in mDNS broadcasts by default. This is configurable with the new
  `DNS::skip_resp_host_port_pairs` option.

  Furthermore, the script now supports and logs IPv6 results.

- The ``mkdir()``, ``rmdir()``, ``unlink()``, and ``rename()`` functions now trigger
  reporter warnings instead of builtin errors when hitting trouble. This allows Zeek to
  continue gracefully in case of such problems, particularly during ``zeek_init()``.

- The RDP analyzer now also parses connections that do not contain the cookie field, which
  were previously rejected.

- An enum's zeek::detail::ID instance now holds its ``EnumVal``. For example, looking up
  the "Conn::LOG" identifier allows to directly query the ``EnumVal`` using
  ``ID::GetVal()``.

- When the send buffer to a Broker peer overflows and the "disconnect" overflow policy is
  in use, Zeek now only attempts to re-establish peerings when the node observing the
  overflow originally established the peering. That is, re-peering is now only attempted
  in consistency with the underlying Broker peering topology. This avoids pointless
  connection attempts to ephemeral TCP client-side ports, which could clutter the Broker
  logs.

- The connect and listen retry intervals of Broker and the Cluster framework
  have all been reduced to one second, from previously 30s/60s.

- The protocol confirmation for IRC was made more robust. It now checks for valid commands
  before confirming a connection as IRC.

- Packet dumping now properly handles both the inner and outer packets of a tunneled
  connection, ensuring that the outer packets are always dumped correctly alongside the
  inner packets.

- SSH banner parsing was previously a bit too strict in some ways and too permissive in
  others. This has been changed to be more robust, now accepting text before the SSH
  banner starts. This was previously a protocol violation but is actually allowed by the
  spec. This should help prevent non-ssh traffic on port 22 from causing an ssh.log to be
  created. A new event called ``ssh_server_pre_banner_data`` was added, and is set When
  this kind of text data is encountered.

- The SNAP analyzer now uses both the OUI and protocol identifier in forwarding
  decisions. Previously it only used the identifier, which lead to some packets not being
  handled at all and also not being logged in ``unknown_protocols.log``.

- The BIND library is no longer required for building Zeek. It hasn't been required since
  our switch to use the C-Ares library back in the 5.0 release, but we never removed the
  requirement from CMake.

Removed Functionality
---------------------

- Broker's broker_buffered_messages metric has been removed, since the
  backpressure handling introduced in 7.1 rendered it obsolete. Use the new
  per-peering metrics described above instead.

Deprecated Functionality
------------------------

- Support for DNS resolution of hostname literals in Zeek scripts has been deprecated. If
  you've used this feature, use the new ``blocking_lookup_hostname()`` builtin function to
  populate sets or tables in a ``zeek_init()`` handler, or with top-level statements.

- ``Broker::listen_websocket()`` was deprecated in favor of ``Cluster::listen_websocket()`.

- The ``Broker::congestion_queue_size`` tunable has had no effect since Zeek 5.0
  and is slated for removal without replacement.

Zeek 7.1.0
==========

We would like to thank Aashish Sharma (@initconf), Andras Gemes (@gemesa),
Anthony Kasza (@anthonykasza), Benjamin Grap (@blightzero), Chiragdeshlehra27,
@cooper-grill, Craig Leres (@leres), Eldon Koyle (@ekoyle), Emmanuele Zambon
(@zambo99), Fox-IT Data Science (@fox-ds), Fupeng Zhao (@AmazingPP), Jan
Grashöfer (@J-Gras), Jordan Barnartt (@JordanBarnartt), Jürgen Löhel (@jloehel),
Justin Azoff (@JustinAzoff), Lucas (@Lucasmeteenc), Martin van Hensbergen
(@martinvanhensbergen), Matti Bispham (@mbispham), Matteo (@skorpion98), Mike
Dopheide (@dopheide-esnet), Mike Peters (@MP-Corelight), Mohan Dhawan
(@Mohan-Dhawan), Pierre (@p-l-), @robinkou, Rodrigo Rojo (@r-rojo), @scyllaever,
Seth Hall (@sethhall), Simeon Miteff (@simeonmiteff), @Sonderino, @superzerosec,
Sven (@svenvanhal), Theo Buehler (@botovq), @timo-mue, @Zopazz, and
@zrobinette12 for their contributions to this release.

Breaking Changes
----------------

- The ``OpaqueVal::DoSerialize`` and ``OpaqueVal::DoUnserialize`` methods were
  marked as deprecated in v7.0 and have now been removed as per the Zeek
  deprecation policy. Plugins that were overriding these methods and were not
  updated will fail to compile. Those plugins should be updated to override the
  new ``OpaqueVal::DoSerializeData`` and ``OpaqueVal::DoUnserializeData``
  methods.

- Certain internal methods on the broker and logging classes have been changed to
  accept std::vector<threading::Value> parameters instead of threading::Value**
  to leverage automatic memory management, reduce the number of allocations
  and use move semantics to express ownership.

  The DoWrite() and HookLogWrite() methods which can be provided by plugins
  are not affected by this change, so we keep backwards compatibility with
  existing log writers.

- ``Func::Name()`` was deprecated, use ``Func::GetName()`` instead.

New Functionality
-----------------

- The following dependencies have had updates:

  - The bundled version of Spicy was updated to 1.12.0. See
    https://github.com/zeek/spicy/releases/tag/v1.12.0 for notes on what's new
    with Spicy.

  - The bundled version of c-ares has been updated to v1.34.2, which required
    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.

  - Python 3.9 is now required for Zeek and all of its associated subprojects.

- 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
  entries have a new ``ip_proto`` column that indicates the numeric IP protocol
  identifier used by the connection. A new policy script at
  ``policy/protocols/conn/ip-proto-name-logging.zeek`` can be loaded to also add
  an ``ip_proto_name`` column with a string version of the ``ip_proto`` value.
  This entire feature can be disabled by loading the new
  ``policy/protocols/conn/disable-unknown-ip-proto-support.zeek`` policy script.

- New ``Cluster::publish()``, ``Cluster::subscribe()`` and ``Cluster::unsubscribe()``
  functions have been added. In contrast to their ``Broker`` counterparts, these
  will operator on whichever cluster backend is enabled. Going forward, in-tree
  ``Broker::publish()`` usages will be replaced with ``Cluster::publish()`` and
  script writers should opt to prefer these over the Broker-specific functions.

- Zeek now includes a PostgreSQL protocol analyzer. This analyzer is enabled
  by default. The analyzer's events and its ``postgresql.log`` should be
  considered preliminary and experimental until the arrival of Zeek's next
  long-term-stable release (8.0).

  If you observe unusually high CPU consumption or other issues due to this
  analyzer being enabled by default, the easiest way to disable it is via the
  ``Analyzer::disabled_analyzers`` const as follows:

	redef Analyzer::disabled_analyzers += {
		Analyzer::ANALYZER_POSTGRESQL,
	};

  If you observe PostgreSQL traffic in your environment, please provide feedback
  about the analyzer and structure of the new log.

- Broker's message I/O buffering now operates on per-peering granularity at the
  sender (it was previously global) and provides configurable overflow handling
  when a fast sender overwhelms a slow receiver, via the following new tunables
  in the ``Broker`` module:

	const peer_buffer_size = 2048 &redef;
	const peer_overflow_policy = "disconnect" &redef;
	const web_socket_buffer_size = 512 &redef;
	const web_socket_overflow_policy = "disconnect" &redef;

  When a send buffer overflows (i.e., it is full when a node tries to transmit
  another message), the sender may drop the message and unpeer the slow receiver
  (policy ``disconnect``, the default), drop the newest message in the buffer
  (``drop_newest``), or drop the oldest (``drop_oldest``). Buffer sizes are
  measured in number of messages, not bytes. Note that "sender" and "receiver"
  are independent of the direction in which Zeek established the peering. After
  disconnects Zeek automatically tries to re-establish peering with the slow
  node, in case it recovers.

  Zeek notifies you in two ways of such disconnects:

    * A cluster.log entry for the sending node indicates that a slow peered node
      has been removed. Here node ``worker01`` has removed a peered ``proxy01`:

	1733468802.626622  worker01  removed due to backpressure overflow: 127.0.0.1:42204/tcp (proxy01)

    * The labeled counter metric ``zeek_broker_backpressure_disconnects_total``
      in the telemetry framework tracks the number of times such disconnects
      happen between respective nodes. The following scraped telemetry indicates
      the same disconnect as above:

	zeek_broker_backpressure_disconnects_total{endpoint="worker01",peer="proxy01"} 1

  To implement custom handling of a backpressure-induced disconnect, add a
  ``Broker::peer_removed`` event handler, as follows:

	event Broker::peer_removed(endpoint: Broker::EndpointInfo, msg: string)
		{
		if ( "caf::sec::backpressure_overflow" !in msg )
			return;

		# The local node has disconnected the given endpoint,
		# add your logic here.
                }

  These new policies fix a problem in which misbehaving nodes could trigger
  cascading "lockups" of nodes, each ceasing to transmit any messages.

- The LDAP analyzer now supports handling of non-sealed GSS-API WRAP tokens.

- StartTLS support was added to the LDAP analyzer. The SSL analyzer is enabled
  for connections where client and server negotiate to TLS through the extended
  request/response mechanism.

- The ``unknown_protocols()`` event now includes the name of all packet
  analyzer used for processing the packet when the event is raised. The
  ``unknown_protocol.log`` file was extended to include this information.

- The MySQL analyzer now generates a ``mysql_change_user()`` event when the user
  changes mid-session via the ``COM_USER_CHANGE`` command.

- The DNS analyzer was extended to support TKEY RRs (RFC 2390). A corresponding
  ``dns_TKEY`` event was added.

- The ``signature_match()`` and custom signature events now receive the end of
  match offset within the ``data`` parameter as an optional parameter named
  ``end_of_match``.

	event signature_match(state: signature_state, msg: string, data: string, end_of_match: count);

- A new plugin hook ``InitPreExecution()`` has been added to allow introspection
  of Zeek's AST after ZAM optimizations ran. This hook executes right before
  the ``zeek_init()`` event is enqueued.

- The SQLite logger now supports setting the value of the SQLite synchronous mode,
  as well as of the journal mode. For example, WAL mode can be enabled by setting:

  redef LogSQLite::journal_mode=LogSQLite::SQLITE_JOURNAL_MODE_WAL;

- A pseudo protocol analyzer StreamEvent has been added. Attaching this analyzer
  to TCP connections allows processing the connection's stream data in the
  scripting layer. One example use-case is interactive terminal sessions over
  HTTP connections upgraded to TCP.

	redef HTTP::upgrade_analyzers += {
		["tcp"] = Analyzer::ANALYZER_STREAM_EVENT,
	};

	event stream_deliver(c: connection, is_orig: bool, data: string);

  This comes with performance caveats: For use-cases with high-data rates
  a native protocol analyzer with dedicated events will be far more efficient.

- Experimental support for pluggable cluster backends has been added. New plugin
  components have been introduced to support switching Zeek's Broker-based
  publish-subscribe and remote logging functionality to alternative implementations.

	redef Cluster::backend = Cluster::CLUSTER_BACKEND_ZEROMQ;

  Besides the backend, the serialization format used for events and log-writes
  has become pluggable as well.

- The Zeek distribution now includes an experimental ZeroMQ based cluster backend.
  To experiment with it, load the following script on each cluster node.

	@load frameworks/cluster/backend/zeromq/connect

  Note that Broker-dependent scripts or integrations will become non-functional
  when doing so as Zeek nodes will not listen on Broker ports anymore, nor will
  they establish a peering to other nodes.

- Zeek now ships with an experimental Spicy-based SSL analyzer, which is
  disabled by default. This analyzer can be enabled using the
  ``--enable-spicy-ssl`` configure-time option. The Spicy-based analyzer has
  full support for SSL and TLS, just like the current binpac analyzer. It does,
  however, not support any version of DTLS. Enabling it will disable DTLS
  parsing in Zeek.

  The analyzer is currently mostly interesting if you want to experiment with
  SSL; we do not yet recommend to enable it in normal Zeek deployments.

- The majority of the metrics reported via stats.log are also now reported via
  the Telemetry framework, and are visible in the output passed to Prometheus.

- A new weird ``DNS_unknown_opcode`` was added to the DNS analyzer to report
  when it receives opcodes that it cannot process.

Changed Functionality
---------------------

- Heuristics for parsing SASL encrypted and signed LDAP traffic have been
  made more strict and predictable. Please provide input if this results in
  less visibility in your environment.

- The MySQL analyzer has been improved to better support plugin authentication
  mechanisms, like caching_sha2_password, as well as recognizing MySQL query
  attributes.

- The ``mysql.log`` for user change commands will contain *just* the username
  instead of the remaining parts of the command, including auth plugin data.

- The POP3 parser has been hardened to avoid unbounded state growth in the
  face of one-sided traffic capture or when enabled for non-POP3 traffic.
  Concretely, the Redis protocol's AUTH mechanism enables the POP3 analyzer
  for such connections through DPD.

- Batching and flushing for local log writers can now be controlled via the
  options ``Log::flush_interval`` and ``Log::write_buffer_size``. Previously
  the ``Threading::heartbeat_interval`` was used for flushing and the buffer
  size fixed at 1000.

- Logging of the FTP PASS command in ``ftp.log`` now honors ``FTP::default_capture_password``
  and the password is blanked with "<hidden>". Previously, the argument for the PASS
  command would be logged in clear.

- The ASCII input reader now suppresses warnings for consecutive invalid lines,
  producing a summary of total suppressions once a valid line is encountered.

- The `Telemetry::sync()` hook is now invoked on demand. Either when the metrics
  of a node are scraped via the Prometheus HTTP endpoint, or one of the collect
  methods is invoked from Zeek script.

- The community-id-logging.zeek policy script was used to set ``c$conn$community_id``
  during ``new_connection()`` rather than ``connection_state_remove()``, allowing
  other scripts to reuse its value early.

- Calling ``Broker::publish()`` now uses the event time of the currently
  executing event as network time metadata attached to the remote event.
  Previously, ``network_time()`` was used. This matters if ``Broker::publish()``
  is called within scheduled events or called within remote events.

- The SSL analyzer now reports the correct version when an SSLv2 client hello is
  used. Zeek previously always reported these as v2, even when the v2 client
  hello indicated support for a later version of SSL.

Deprecated Functionality
------------------------

- The ``Broker::auto_publish()`` function has been deprecated and should
  be replaced with explicit ``Broker::publish()`` invocations that are
  potentially guarded with appropriate ``@if`` or ``@ifdef`` directives.

- The misspelled ``complte_flag`` in the ``dns_binds_rr`` record has been deprecated.
  The new ``complete_flag`` uses type ``count`` instead of ``string``.

Zeek 7.0.0
==========

Breaking Changes
----------------

- The Telemetry framework has had a major rework, and includes a number of
  breaking changes. The biggest change is a move towards a Prometheus-first
  model. This removes the internal aggregation of metrics from nodes onto the
  manager node, replacing it with a Prometheus service discovery endpoint. The
  usage of this endpoint is described in the updated documentation for the
  Telemetry framework. Using this endpoint also requires adding a new
  ``metrics_port`` field to each node in the cluster configuration, denoting
  what port to connect to for each node.

  All of the metrics-related script-level options, type, and methods have been
  moved to the Telemetry framework:
    * Option ``Broker::metrics_port` is now ``Telemetry::metrics_port``
    * Option ``Broker::metrics_export_endpoint_name`` is now ``Telemetry::metrics_endpoint_name``

  The following options have been removed:
    * ``Broker::metrics_export_interval``
    * ``Broker::metrics_export_topic``
    * ``Broker::metrics_import_topics``
    * ``Broker::metrics_export_prefixes``

  The ``unit`` field has been removed from the telemetry log.

  All of the ``BROKER_METRICS_*`` environment variables have been removed. Use
  the equivalent script-level variables for setting configuration settings. For
  cluster settings, a new ``metrics_port`` option was added to the ``node.cfg``
  options and can be used to set the port number. The cluster layout record
  defined in ``cluster-layout.zeek`` has the same option, and it can be
  automatically populated by ``zeekctl`` during the ``install`` or ``deploy``
  commands.

  The instruments that previously supported ``count`` in scripts and ``int64_t``
  in C++ were removed in favor of only providing ``double`` versions. Prometheus
  only handles ``double`` underneath the Zeek code, so it makes sense to only
  support it directly in Zeek as well. This also simplifies the code
  significantly.

  The ``is_sum`` argument has been removed from the constructors/creation
  methods for all of the instruments. This again follows how Prometheus works,
  where ``counter`` instruments are always considered sums and ``gauge``
  instruments are not. ``Histogram`` instruments don't have the concept of
  summing.

- Zeekctl now sets `FileExtract::prefix` to `spool/extract_files/<node>` to avoid
  deletion of extracted files when stopping worker nodes. To revert to the
  previous behavior, set `FileExtractDir` to an empty string in `zeekctl.cfg`.

  If you never enabled Zeek's file extraction functionality, there's no impact.

New Functionality
-----------------

- Support ``delete`` on tables, sets and vectors to clear their contents.

	global v = vector(1, 2, 3);
	delete v;
	assert |v| == 0;

- A new helper function ``can_load()`` backed by a new bif ``find_in_zeekpath()``
  was added to determine if a non-relative ``@load`` directive might work. This
  can be used to guard ``@load`` directives when script packages may or may not
  be installed.

	@if ( can_load("my-package") )
	@load my-package
	@endif

- Zeek packagers can now include a "local" addition into Zeek's version string.
  Configure your Zeek build with ``--localversion=XXX`` to add the provided
  string, dash-separated, at the end of Zeek's regular version string. The build
  setup will refuse strings that contain dashes, to avoid confusing the version
  components.  For debug builds, the ``-debug`` suffix remains at the end. For
  example, the version string on a debug-enabled build with local addition "XXX"
  might be "7.0.0-dev.114-XXX-debug". For Docker builds, the ``LOCALVERSION``
  environment variable configures the addition.

- SMB2 packets containing multiple PDUs now correctly parse all of the headers,
  instead of just the first one and ignoring the rest. This may cause increased
  CPU load on SMB2-heavy networks.

- The new built-in function ``lookup_connection_analyzer_id()`` retrieves the
  numeric identifier of an analyzer associated with a connection. This enables
  the use of the ``disable_analyzer()`` BiF outside of the analyzer
  confirmation/violation events that have so far been the only providers of
  those identifiers. For example, this allows the suppression of an analyzer
  from the outset for specific connections:

	event connection_established(c: connection):
		{
		if ( no_http_for_this_conn_wanted(c) )
			{
			local aid = lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP);
			if ( aid > 0 )
				disable_analyzer(c$id, aid, T, T);
			}
		}

  Use ``Analyzer::get_tag()`` if you need to obtain an analyzer's tag from its
  name (such as "HTTP").

- The ``from_json()`` function now supports ingesting JSON representations of
  tables as produced by the ``to_json()`` function. It now also supports reading
  the object-based representation of ports that ``to_json()`` generates for that
  Zeek type.

- The ``analyzer.log`` now optionally supports logging of disabled analyzers
  through the new option ``Analyzer::logging::include_disabling``.

Changed Functionality
---------------------

- The ``ftp.log`` fuid field is now cleared after handling a command with a fuid
  associated with it. Previously, fuid was sticky and any subsequent FTP command
  would reproduce the same fuid, even if the command itself did not result in
  a file transfer over a data connection (e.g., CWD, DEL, PASV, SIZE).

- The type_name field populated by ``global_ids()`` now aligns with the value
  returned by ``type_name()`` for each identifier. E.g, ``Site::local_nets``
  has a type_name of ``set[subnet]`` rather than ``table``.

- The ISO 9660 file signature has been moved into the policy directory. The
  signature has previously been non-functional due to implicit anchoring. Further,
  this signature requires users to significantly increase their
  ``default_file_bof_buffer_size``. Users can now enable this signature by loading
  ``frameworks/signatures/iso-9660`` which also increases the BOF buffer sufficiently.
  Note, doing so may increase memory and CPU usage significantly.

- The ``val_footprint()`` BiF now factors in the size of strings when reporting
  footprints, roughly equating a string's size with the number of elements
  comparable to that length. As before, footprints are not meant to be precise
  but mainly for providing comparisons, which is why this is not a breaking
  change.

- The tuning/defaults policy has been deprecated and will be removed in
  v7.1. This policy was already being loaded by default via local.zeek. The
  settings contained within have become the overall defaults for Zeek now,
  instead of having to load the policy. The two changes here are that fragments
  now timeout after 5 minutes by default instead of no timeout, and extracted
  files now have a default size limit of 100MB instead of unlimited.

- If a Spicy protocol analyzers feeds data into file analysis, it now
  needs to call Zeek's `Files::register_protocol()` and provide a
  callback for computing file handles. If that's missing, Zeek will
  issue a warning. While this was not necessary in previous versions,
  it aligns with the same requirement for traditional analyzers and
  enables customizing file handles for protocol-specific semantics.

- The Supervisor's API now returns NodeConfig records with a cluster table whose
  ClusterEndpoints have a port value of 0/unknown, rather than 0/tcp, to
  indicate that the node in question has no listening port.

Removed Functionality
---------------------

Deprecated Functionality
------------------------

- The ``--disable-archiver`` configure flag no longer does anything and will be
  removed in 7.1. zeek-archiver has moved into the zeek-aux repository.

- The policy/frameworks/telemetry/prometheus.zeek script has been deprecated
  and will be removed with Zeek 7.1. Setting the ``metrics_port`` field on a
  ``Cluster::Node`` implies listening on that port and exposing telemetry
  in Prometheus format.

Zeek 6.2.0
==========

We would like to thank Anthony Verez (netantho), Bijoy Das (mute019), Jan
Grashöfer (J-Gras), Matti Bispham (mbispham), Phil Rzewski (philrz), and
xb-anssi for their contributions to this release.

Breaking Changes
----------------

- The methods ``Dispatcher::Lookup()`` and ``Analyzer::Lookup()`` in the packet_analysis
  namespace were changed to return a reference to a std::shared_ptr instead of a copy
  for performance reasons.

- Zeek's ``OPENSSL_INCLUDE_DIR`` is not automatically added to an external plugin's
  include path anymore. A plugin using OpenSSL functionality directly can use the
  following explicit entry to re-use Zeek's ``OPENSSL_INCLUDE_DIR``:

	zeek_add_plugin(
		Namespace Name
		INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}"
		SOURCES ...
	)

- The "segment_profiling" functionality and ``load_sample`` event have been removed
  without deprecation. This functionality was unmaintained and not known to be used.

- Certain ``ldap.log`` and ``ldap_search.log`` fields have been renamed from
  plural to singular and their types changed to scalars. This maps better onto
  the expected request-response protocol used between client and server. Additionally,
  it removes the burden of working with non-scalar columns from downstream systems.

  Specifically, for ``ldap.log``:
    * ``arguments: vector of string`` is now ``argument: string``
    * ``diagnostic_messages: vector of string`` is now ``diagnostic_message: string``
    * ``objects: vector of string`` is now ``object: string``
    * ``opcodes: set[string]`` is now ``opcode: string``
    * ``results: set[string]`` is now ``result: string``

  For ``ldap_search.log``, the following fields were changed:
    * ``base_objects: vector of string`` is now ``base_object: string``
    * ``derefs: set[string]`` is now ``deref_aliases: string``
    * ``diagnostic_messages: vector of string`` is now ``diagnostic_message: string``
    * ``results: set[string]`` is now ``result: string``
    * ``scopes: set[string]`` is now ``scope: string``

  In the unlikely scenario that a request-response pair with the same message
  identifier is observed, containing different values for certain fields, new
  weirds are raised and will appear in ``weird.log``, including the old and new
  values as well as the LDAP message identifier. The value within the LDAP logs
  will be the most recently observed one.

- BIF methods now return a ``ValPtr`` directly instead of a ``BifReturnVal`` object
  which was just a thin wrapper around ``ValPtr``. This may cause compilation errors
  in C++ code that was calling BIF methods directly.

New Functionality
-----------------

- The table type was extended to allow parallel regular expression matching
  when a table's index is a pattern. Indexing such tables yields a vector
  containing all values of matching patterns for keys of type string.

  As an example, the following snippet outputs ``[a, a or b], [a or b]``.

	global tbl: table[pattern] of string;
	tbl[/a/] = "a";
	tbl[/a|b/] = "a or b";
	tbl[/c/] = "c";
	print tbl["a"], tbl["b"];

  Depending on the patterns and input used for matching, memory growth may
  be observed over time as the underlying DFA is constructed lazily. Users are
  advised to test with realistic and adversarial input data with focus on
  memory growth. The DFA's state can be reset by removal/addition of a single
  pattern. For observability, a new bif ``table_pattern_matcher_stats()``
  can be used to gather ``MatcherStats``.

- Support for delaying log writes.

  The logging framework offers two new functions ``Log::delay()`` and ``Log::delay_finish()``
  to delay a ``Log::write()`` operation. This new functionality allows delaying of
  a specific log record within the logging pipeline for a variable but bounded
  amount of time. This can be used, for example, to query and wait for additional
  information to attach to the pending record, or even change its final verdict.

  Conceptually, delaying a log record happens after the execution of the global
  ``Log::log_stream_policy`` hook for a given ``Log::write()`` and before the
  execution of filter policy hooks. Any mutation of the log record within the
  delay period will be visible to filter policy hooks. Calling ``Log::delay()``
  is currently only allowed within the context of the ``Log::log_stream_policy`` hook
  for the active ``Log::write()` operation (or during the execution of post delay callbacks).
  While this may appear restrictive, it makes it explicit which ``Log::write()``
  operation is subject to the delay.

  Interactions, semantics and conflicts of this feature when writing the same
  log record multiple times to the same or different log streams need to be taken
  into consideration by script writers.

  Given this is the first iteration of this feature, feedback around usability and
  use-cases that aren't covered are more than welcome.

- A WebSocket analyzer has been added together with a new ``websocket.log``.

  The WebSocket analyzer is instantiated when a WebSocket handshake over HTTP is
  recognized. By default, the payload of WebSocket messages is fed into Zeek's dynamic
  protocol detection framework, possibly discovering and analyzing tunneled protocols.

  The format of the log and the event semantics should be considered preliminary until
  the arrival of the next long-term-stable release (7.0).

  To disable the analyzer in case of fatal errors or unexpected resource usage,
  use the ``Analyzer::disabled_analyzers`` pattern:

	redef Analyzer::disabled_analyzers += {
		Analyzer::ANALYZER_WEBSOCKET,
	};

- The SMTP analyzer was extended to recognize and properly handle the BDAT command
  from RFC 3030. This improves visibility into the SMTP protocol when mail agents
  and servers support and use this extension.

- The event keyword in signatures was extended to support choosing a custom event
  to raise instead of ``signature_match()``. This can be more efficient in certain
  scenarios compared to funneling every match through a single event.

  The new syntax is to put the name of the event before the string used for the
  ``msg`` argument. As an extension, it is possible to only provide an event name,
  skipping ``msg``. In this case, the framework expects the event's parameters to
  consist of only state and data as follows:

	signature only-event {
		payload /.*root/
		event found_root
	}

	event found_root(state: signature_state, data: string) { }

  Using the ``msg`` parameter with a custom event looks as follows. The custom
  event's parameters need to align with those for ``signature_match()` event:

	signature event-with-msg {
		payload /.*root/
		event found_root_with_msg "the-message"
	}

	event found_root_with_msg(state: signature_state, msg: string, data: string) { }

  Note, the message argument can currently still be specified as a Zeek identifier
  referring to a script-level string value. If used, this is disambiguated behind
  the scenes for the first variant. Specifying ``msg`` as a Zeek identifier has
  been deprecated with the new event support and will be removed in the future.

  Note that matches for signatures with custom events will not be recorded in
  ``signatures.log``. This log is based on the generation of ``signature_match()``
  events.

- The QUIC analyzer has been extended to support analyzing QUIC Version 2
  INITIAL packets (RFC 9369). Additionally, prior draft and some of
  Facebook's mvfst versions are supported. Unknown QUIC versions will now be
  reported in ``quic.log`` as an entry with a ``U`` history field.

- Conditional directives (``@if``, ``@ifdef``, ``@ifndef``, ``@else`` and
  ``@endif``) can now be placed within a record's definition to conditionally
  define or extend a record type's fields.

	type r: record {
		c: count;
	@if ( cond )
		d: double;
	@else
		d: count;
	@endif
	};

  Note that generally you should prefer record extension in conditionally loaded
  scripts rather than using conditional directives in the original record definition.

- The 'X' code can now appear in a connection's history. It is meant to indicate
  situations where Zeek stopped analyzing traffic due to exceeding certain limits or
  when encountering unknown/unsupported protocols. Its first use is to indicate
  ``Tunnel::max_depth`` being exceeded.

- A new ``Intel::seen_policy`` hook has been introduced to allow intercepting
  and changing ``Intel::seen` behavior:

	hook Intel::seen_policy(s: Intel::Seen, found: bool)

- A new ``NetControl::rule_added_policy`` hook has been introduced to allow modification
  of NetControl rules after they have been added.

- The IP geolocation / ASN lookup features in the script layer provide better
  configurability. The file names of MaxMind databases are now configurable via
  the new ``mmdb_city_db``, ``mmdb_country_db``, and ``mmdb_asn_db`` constants,
  and the previously hardwired fallback search path when not using an
  ``mmdb_dir`` value is now adjustable via the ``mmdb_dir_fallbacks``
  vector. Databases opened explicitly via the ``mmdb_open_location_db`` and
  ``mmdb_open_asn_db`` functions now behave more predictably when updated or
  removed. For details, see:
  https://docs.zeek.org/en/master/customizations.html#address-geolocation-and-as-lookups

- The ``zeek-config`` script now provides a set of ``--have-XXX`` checks for
  features optionally compiled in. Each check reports "yes"/"no" to stdout and
  exits with 0/1, respectively.

Changed Functionality
---------------------

- The ``split_string`` family of functions now respect the beginning-of-line ^ and
  end-of-line $ anchors. Previously, an anchored pattern would be matched anywhere
  in the input string.

- The ``sub()`` and ``gsub()` functions now respect the beginning-of-line ^ and
  end-of-line $ anchors. Previously, an anchored pattern would be matched anywhere
  in the input string.

- Ed25519 and Ed448 DNSKEY and RRSIG entries do not cause weirds anymore.

- The OpenSSL references in ``digest.h`` and ``OpaqueVal.h`` headers have been
  hidden to avoid unneeded dependencies on OpenSSL headers. Plugins using the
  detail API from ``digest.h`` to compute hashes likely need to accommodate for
  this change.

- The ``Tunnel::max_depth`` default was changed from 2 to 4 allowing for more than
  two encapsulation layers. Two layers are already easily reached in AWS GLB
  environments.

- Nested MIME message analysis is now capped at a maximum depth of 100 to prevent
  unbounded MIME message nesting. This limit is configurable with ``MIME::max_depth``.
  A new weird named ``exceeded_mime_max_depth`` is reported when reached.

- The ``netcontrol_catch_release.log`` now contains a plugin column that shows which
  plugin took an action. The logs also contain information when errors or existing
  rules are encountered.

- The ``Cluster::PoolSpec`` record no longer provides default values for its
  ``topic`` and ``node_type`` fields, since defaults don't fit their intended
  use and looked confusing in generated documentation.

Removed Functionality
---------------------

- Zeek no longer automatically subscribes to topics prefixed with "bro/" whenever
  subscribing to topics prefixed with "zeek/". This was a leftover backward-
  compatibility step in the Broker code that should have been removed long ago.

Deprecated Functionality
------------------------

- The virtual functions ``DoSerialize``and ``DoUnserialize`` of the ``OpaqueVal``
  (and ``BloomFilter``) class will be removed with Zeek 7.1. Unfortunately, code
  implementing the deprecated methods does not produce compiler warnings.

  Plugin authors implementing an ``OpaqueVal`` subclass need to convert to
  ``DoSerializeData`` and ``DoUnserializeData``:

    * ``std::optional<BrokerData> OpaqueVal::DoSerializeData() const``
    * ``bool OpaqueVal::DoUnserializeData(BrokerDataView data)``

  When overriding ``DoSerializeData()``, return ``std::nullopt`` (or a
  default-constructed ``optional``) for values that cannot be serialized.
  Otherwise, the canonical way to create a ``BrokerData`` for serialization is
  by using a ``BrokerListBuilder``. For example, creating a ``BrokerData`` that
  contains ``true`` and the count ``42`` could be implemented as follows:

    BrokerListBuilder builder;
    builder.Add(true);
    builder.AddCount(42u);
    return std::move(builder).Build();

  Please refer to the respective class documentation for a full list of member
  functions on ``BrokerListBuilder`` and ``BrokerDataView``.

  For plugins that are using the macro ``DECLARE_OPAQUE_VALUE`` to generate the
  function prototypes for the serialization functions: please use
  ``DECLARE_OPAQUE_VALUE_DATA`` instead to generate prototypes for the new API.

  Plugin authors that need to support multiple Zeek versions can use the
  ``ZEEK_VERSION_NUMBER`` macro to conditionally implement the new and old
  methods. Provide the new versions with Zeek 6.2 (60200) or later, otherwise
  keep the old signature. The default implementations for the new functions
  as used by Zeek will call the old signatures and convert the results.

- The ``Cluster::Node$interface`` field has been deprecated. It's essentially
  unneeded, unused and not a reliable way to gather the actual interface used
  by a worker. In Zeekctl deployments the field will be populated until its
  removal. The ``packet_source()`` bif should be used on worker processes to
  gather information about the interface.

- The ``policy/misc/load-balancing`` script has been deprecated in favor of
  AF_PACKET PF_RING, Netmap or other NIC specific load balancing approaches.

- Time machine related enums, options and fields have been marked for removal.

- The ``check_for_unused_event_handlers`` options the related ``UsedHandlers()``,
  ``UnusedHandlers()`` and their related ``SetUsed()`` and ``Used()`` methods
  have been marked for removal. The feature of finding unused event handlers is
  provided by default via the ``UsageAnalyzer`` component.

- Using a Zeek identifier for the ``msg`` argument within a signatures's ``event``
  keyword has been deprecated.

Zeek 6.1.0
==========

Breaking Changes
----------------

- ``assert`` is now a reserved keyword for the new ``assert`` statement.

- The ``__bro_plugin__`` file that gets generated as part of plugin builds was
  renamed to ``__zeek_plugin__``. This will affect the ability for older
  versions of ``zkg`` to use the ``zkg unload`` and ``zkg load`` commands. This
  should only cause breakage for people using a version of ``zkg` that doesn't
  come bundled with Zeek (which we generally don't recommend doing).

- Zeek does not traverse into dot directories to find plugins or hlto files
  anymore.  Any dot directories found below the directories specified in
  ZEEK_PLUGIN_PATH or ZEEK_SPICY_MODULE_PATH are now skipped. Dot directories
  explicitly listed in ZEEK_PLUGIN_PATH or ZEEK_SPICY_MODULE_PATH are not
  skipped.

- External plugins will fail to configure if their minimum required CMake
  version is below 3.15. This was a warning with Zeek 6.0, but has caused user
  confusion due to unhelpful error messages around the IN_LIST operator policy.

- The FindBISON, FindOpenSSL, FindPackageHandleStandardArgs, FindPackageMessage,
  and SelectLibraryConfigurations cmake files were removed from our cmake
  repository in favor of the versions that come with CMake. This should not
  cause any breakage, but it is possible in the case that someone was using
  these in a plugin.

New Functionality
-----------------

- Zeek now includes the LDAP protocol analyzer from the zeek/spicy-ldap project
  (https://github.com/zeek/spicy-ldap). This analyzer is enabled by default. The
  analyzer's events and its ``ldap.log`` and ``ldap_search.log`` should be
  considered preliminary and experimental until the arrival of Zeek's next
  long-term-stable release (7.0).

  If you observe unusually high CPU consumption or other issues due to this
  analyzer being enabled by default, the easiest way to disable it is via the
  ``Analyzer::disabled_analyzers`` const as follows:

	redef Analyzer::disabled_analyzers += {
		Analyzer::ANALYZER_LDAP_UDP,
		Analyzer::ANALYZER_LDAP_TCP,
	};

  Please do report issues to us including diagnostic information in case this is
  necessary in your environment. We're also open to general feedback about the
  structure of the new logs.

- Zeek now includes the QUIC protocol analyzer from the zeek/spicy-quic project
  (https://github.com/zeek/spicy-quic). This project is a fork of Fox-IT's
  initial implementation (https://github.com/fox-ds/spicy-quic).

  As for the LDAP analyzer, the analyzer's events and the new ``quic.log``
  should be considered preliminary and experimental until the arrival of Zeek's
  next long-term-stable release (7.0). As above, any feedback and contributions
  to this analyzer and the new log are welcome.

  The analyzer's functionality is limited to decryption of the INITIAL packets
  of QUIC version 1. If decryption of these packets is successful, the handshake
  data is forwarded to Zeek's SSL analyzer. An ``ssl.log`` entry will appear in
  ``ssl.log`` for QUIC connections. The entry in the ``conn.log`` will contain
  ``quic`` and ``ssl`` in the service field.

  To disable the analyzer in case of issues, use the following snippet:

	redef Analyzer::disabled_analyzers += {
		Analyzer::ANALYZER_QUIC,
	};

- Added a new ``assert`` statement for assertion based testing and asserting
  runtime state.

	assert <expr: bool>[, <message: string>];

  This statement comes with two hooks. First, ``assertion_failure()`` that is
  invoked for every failing assert statement. Second, ``assertion_result()``
  which is invoked for every assert statement and its outcome. The latter allows
  to construct a summary of failing and passing assert statements. Both hooks
  receive the location and call stack for the ``assert`` statement via a
  ``Backtrace`` vector.

  A failing assert will abort execution of the current event handler similar to
  scripting errors. By default, a reporter error message is logged. Using the
  break statement within ``assertion_failure()`` or ``assertion_result()``
  allows to suppress the default message.

- Add a new ``&default_insert`` attribute for tables. This behaves as
  ``&default`` with the addition that the default value is inserted into the
  table upon a failed lookup. Particularly for tables with nested container
  values, the ``&default`` behavior of not inserting the value can be of little
  use.

- The ``from_json()`` function now takes an optional key_func argument to
  normalize JSON object key names. This can be useful if the keys in a JSON
  object are not valid Zeek identifiers or reserved keywords.

- Module names are now included in ``global_ids()``. Their key in the returned
  table is prefixed with "module " and their value will have the ``type_name``
  field set to "module".

- Identifiers in the global scope can now be referenced and defined from within
  modules by prefixing their names with ``::``. Previously, these required an
  explicit ``GLOBAL::`` prefix to be used. Using ``GLOBAL::`` has been
  deprecated.

- The ``as`` keyword now supports casting between ``set`` and ``vector`` values
  with the same element type. Converting ``set`` values with multiple index
  values is not supported. We plan to extend the use of the ``as`` keyword to
  support more type conversions in the future.

- Added new packet analyzer to handle PCAP files DLT_PPP link type.

- Fixed appending of ``any`` to ``vector of any``.

- The ModBus analyzer's function support was expanded, with new handling of the
  Encapsulation Interface Transport (function 28) And Diagnostics (function 8)
  functions. This adds new ``modbus_encap_interface_transport_{request,response}``
  and ``modbus_diagnostics_{request,response}`` events.

- The ModBus file record read and write events now provide the full data from
  the request and response messages as part of the event data.

- The full PDU length was added to the ``ModBusHeader`` record type passed with
  all of the ModBus events.

Changed Functionality
---------------------

- A connection's value is now updated in-place when its directionality is
  flipped due to Zeek's heuristics (for example, SYN/SYN-ACK reversal or
  protocol specific approaches).  Previously, a connection's value was discarded
  when flipped, including any values set in a ``new_connection()`` handler. A
  new ``connection_flipped()`` event is added to allow updating custom state in
  script-land.

- Loading ``policy/frameworks/notice/community-id.zeek`` now also automatically
  community ID logging. In the past, loading the script had no effect unless
  ``policy/protocols/conn/community-id-logging.zeek`` was loaded before. This
  was fairly unusual and hard to debug behavior.

- Connections to broadcast addresses are not flipped based on
  ``likely_server_ports`` anymore. Previously, broadcast packets originating
  from a likely server port resulted in 255.255.255.255 being the originator in
  ``conn.log``.

- When too many HTTP requests are pending, Zeek will now log them at once and
  reset request/response correlation instead of running into unbounded state
  growth. This behavior is configurable via a new option
  ``HTTP::max_pending_requests``.  The default is ``100``.

- Fix deferred initialization of nested records containing non-const &default
  attributes.

- Parameter lists for functions, events and hooks now use commas instead of
  semicolons in error messages or when printing such functions.

- The IO buffer size used for PCAP file reading is now always 128kb. This new
  default can be changed via ``Pcap::bufsize_offline_bytes``.

- The input framework now provides better information in error messages when
  encountering missing non-optional field while loading data.

- The SSL analyzer will now parse a configurable maximum of 10 SSL Alerts per
  SSL message. For TLS 1.3, the maximum is implicitly 1 as defined by RFC 8446.
  If there are more alerts, a new weird "SSL_excessive_alerts_in_record" is raised.
  For non-TLS 1.3, the maximum can be redefined via ``SSL::max_alerts_per_record``.

- The ``ssl_history`` field in the ssl.log is now capped at a configurable
  limit of 100 characters prevent unbounded growth. The limit can be changed
  via the option ``SSL::max_ssl_history_length``. When reached, a new weird
  named "SSL_max_ssl_history_length_reached" is raised.

Deprecated Functionality
------------------------

- Accessing globals with ``GLOBAL::name`` has been deprecated and will be
  removed with Zeek 7.1. Use ``::name`` instead.

- The original ``trigger::Trigger`` constructor has been deprecated and will be
  removed with Zeek 7.1. Use the new alternative constructor (per
  ``src/Trigger.h``) instead, including replacing any use of ``new ...`` with
  ``make_intrusive<...>``. The new constructor differs only in the placement of
  the ``timeout`` parameter, and in that - unlike the original - it always
  returns a valid pointer, which must be Unref()'d after construction, either
  explicitly (if using ``new``) or implicitly (if using
  ``make_intrusive<...>``).

Zeek 6.0.0
==========

Breaking Changes
----------------

- Zeek now treats private address space (i.e., non-routable IP address ranges)
  as local by default, matching the intuition of many users that e.g. a
  192.168/16 IP address should show up as local in the logs. To do this, Zeek
  automatically adds ``Site::private_address_space`` to ``Site::local_nets`` at
  startup. Subsequent runtime updates to ``Site::private_address_space``
  propagate to ``Site::local_nets``, while updates to the latter don't affect
  the former.

  You're free to define ``Site::local_nets`` as before and do not need to update
  your configurations. If you added standard private address space to
  ``Site::local_nets`` in the past, you no longer need to do so. This also
  applies to zeekctl's ``networks.cfg`` file.

  The new global Boolean ``Site::private_address_space_is_local``, true by
  default, controls the behavior. A redef to false brings back Zeek's prior
  behavior of considering private address space an unrelated concept, which will
  come in handy for example when working with tests that compare results against
  log baselines that have not yet been updated.

- Telemetry centralization and Prometheus exposition is not enabled by default
  anymore. Previously, the manager node would open port 9911/tcp by default and
  import all metrics from other nodes. For large clusters, the current implementation
  introduces significant processing overhead on the manager even if the Prometheus
  functionality is not used. While inconvenient, disable this functionality
  (assumed to be used by few as of now) by default to preserve resources.

  The script to enable centralization and the Prometheus endpoint is now
  located in the ``policy/`` folder. Re-enable the old functionality with:

	@load frameworks/telemetry/prometheus

  You may experiment with increasing ``Broker::metrics_export_interval``
  (default 1s) to reduce the extra overhead and communication at the expense
  of stale metrics.

- Custom source tarballs require a ``repo-info.json`` file.

  Note, should you be using official Zeek release tarballs only, or build
  Zeek solely from git checkouts, this does not affect you.

  However, if you're building your own Zeek source tarballs, it is now required
  that a ``repo-info.json`` file exists at the top-level. The ``dist`` target was
  extended to add this file and official Zeek release source tarballs will
  contain it going forward.

  The following command can be used to produce ``repo-info.json``:

	python3 ./ci/collect-repo-info.py --only-git > ../path/to/tarballdir/repo-info.json

  This is required to support the new ``-V`` / ``--build-info`` option that
  provides information about git submodules and included plugins used during
  the build. The ``ci/collect-repo-info.py`` tool runs at ``./configure`` time
  and either collects the required information from a git clone (when git is
  installed), or otherwise uses the content of a file named ``repo-info.json``.

  If you see opportunities to extend ``repo-info.json`` with further information,
  please get in touch.

- Plugin authors should raise the minimum required CMake version to 3.15 to
  ensure compatibility with new CMake scaffolding included in this
  release. Older versions will trigger a warning at configuration time and,
  depending on the functionality included in the plugin, may trigger subsequent
  errors during configuration or build.

- Zeek container images are not pushed to the zeekurity organization anymore.
  Please switch to using the ``zeek/zeek`` image on DockerHub, or the images
  published to ``public.ecr.aws/zeek/zeek``.

- The IRC_Data analyzer declaration has been moved to protocols/irc/IRC.h.

- The error message returned when using ``bro_init``, ``bro_done``, and
  ``bro_script_loaded`` events is now removed.  removed. Usage of these events
  has returned that error during script parsing for a few years, and time has
  come to finally remove it.

New Functionality
-----------------

- Zeek now features experimental JavaScript support:

	/* hello.js */
	zeek.on('zeek_init', () => {
	  console.log('Hello, Zeek!');
	});

	$ zeek ./hello.js
	Hello, Zeek!

  When building Zeek on a system that features a recent (16.13+) version of the
  libnode package with development headers, Zeek automatically includes the
  externally-maintained ZeekJS plugin (https://github.com/corelight/zeekjs) as a
  builtin plugin. This allows Zeek to load and execute JavaScript code located
  in ``.js`` or ``.cjs`` files. When no such files are passed to Zeek, the
  JavaScript engine and Node.js environment aren't initialized and there is no
  runtime impact.

  The Linux distributions Fedora 37 & 38, Ubuntu 22.10, and the upcoming Debian
  12 release provide suitable packages. On other platforms, Node.js can be built
  from source with the ``--shared`` option.

  To disable this functionality, pass ``--disable-javascript`` to configure.

- Zeek now comes with Spicy support built in, meaning it can now
  leverage any analyzers written in Spicy out of the box. While the
  interface layer connecting Zeek and Spicy used to be implemented
  through an external Zeek plugin, that code has now moved into the
  Zeek code base itself. We also added infrastructure to Zeek that
  enables its built-in standard analyzers to use Spicy instead of
  Binpac. As initial (simple) examples, Zeek's Syslog and Finger
  analyzers are now implemented in Spicy. While their legacy versions
  remain available as fallbacks for now in case Spicy gets explicitly
  disabled at build time, their use is deprecated and their code won't
  be maintained any further. (Some of these Spicy updates were part of
  Zeek 5.2 already, but hadn't been included in its NEWS section.)

- Zeek events now hold network timestamps. For scheduled events, the timestamp
  represents the network time for which the event was scheduled for, otherwise
  it is the network time at event creation. A new bif ``current_event_time()``
  allows to retrieve the current event's network timestamp within the script-layer.

  When Zeek sends events via Broker to other nodes in a cluster, an event's network
  timestamp is attached to the Broker messages. On a receiving Zeek node executing a
  handler for a remote event, ``current_event_time()`` returns the network time of
  the sending node at the time the event was created.

  The Broker level implementation allows to exchange arbitrary event metadata, but
  Zeek's script and C++ APIs currently only expose network timestamp functionality.

- A new bif ``from_json()`` can be used to parse JSON strings into records.

	type A: record { a: addr; };
	local p = from_json({\"a\": \"192.168.0.1\"}", A);
	if ( p$valid )
		print (p$v as A)

  Implicit conversion from JSON to Zeek types is implemented for bool, int, count,
  real, interval (number as seconds) and time (number as unix timestamp), port
  (strings in "80/tcp" notation), patterns, addr, subnet, enum, sets, vectors
  and records similar to the rules of the input framework. Optional or default
  record fields are allowed to be missing or null in the input.

- Zeek now provides native "Community ID" support with a new bif called
  ``community_id_v1()``. Two policy scripts ``protocols/conn/community-id-logging``
   and ``frameworks/notice/community-id`` extend the respective logs with a
  ``community_id`` field the same way as the external zeek-community-id plugin
  provides. A main difference to the external ``hash_conn()`` bif is that the
  ``community_id_v1()`` takes a ``conn_id`` record instead of a ``connection``.

  Loading the new policy scripts and using the external zeek-community-id
  plugin at the same time is unsupported.

- ZeekControl is now multi-logger aware. When multiple logger nodes are configured
  in ZeekControl's node.cfg, by default the log archival logic adds a logger's name
  as suffix to the rotated file name:

	stats.11:18:57-11:19:00-logger-1.log.gz
	stats.11:18:57-11:19:00-logger-2.log.gz

  Previously, in a multi-logger setup, individual logger processes would overwrite
  each other's log files during rotation, causing data loss.

  For setups with a single logger, there's no change in behavior. The naming
  of the final logs can be customized by providing an alternative
  ``make-archive-name`` script and using the new ``ZEEK_ARG_LOG_SUFFIX``
  environment variable.

- A supervisor controlled Zeek cluster is now multi-logger aware. This avoids
  loggers overwriting each other's log files within a single log-queue directory.
  By default, a logger's name is appended to the rotated logs by zeek-archiver.

- Introduce a new command-line option ``-V`` / ``--build-info``. It produces
  verbose output in JSON format about the repository state and any included
  plugins.

- The X.509 certificate parser now exposes the signature type that is given inside
  the signed portion of the certificate.

- The SSL parser now parses the CertificateRequest handshake message. There is a new
  ``ssl_certificate_request`` event and a new ``parse_distinguished_name`` function.
  We also added the ``protocols/ssl/certificate-request-info`` policy script, that
  adds some additional information to ``ssl.log``.

- Add logging metrics for streams (``zeek-log-stream-writes``) and writers
  (``zeek-log-writer-writes-total``).

- Add networking metrics via the telemetry framework. These are enabled
  when the ``misc/stats`` script is loaded.

	zeek-net-dropped-packets
	zeek-net-link-packets
	zeek-net-received-bytes
	zeek-net-packet-lag-seconds
	zeek-net-received-packets-total

  Except for lag, metrics originate from the ``get_net_stats()`` bif and are
  updated through the ``Telemetry::sync()`` hook every 15 seconds by default.

- The DNS analyzer now parses RFC 2535's AD ("authentic data") and CD ("checking
  disabled") flags from DNS requests and responses,  making them available in
  the ``dns_msg`` record provided by many of the ``dns_*`` events. The existing
  ``Z`` field remains unchanged and continues to subsume the two flags, for
  backward compatibility.

- The supervisor framework can now start worker nodes that read from a trace file.

- Zeek can be prevented from updating ``network_time()`` to the current time
  by setting ``allow_network_time_forward=F``. Together with ``set_network_time()``
  or a custom plugin, this allows control of ``network_time()`` without Zeek
  interfering.

- The setting ``Pcap::non_fd_timeout`` can be used to configure the timeout
  used by non-selectable packet sources in the idle case (default 20usec).
  This value has previously been hard-coded, but increasing it can significantly
  reduce idle CPU usage in low packet rate deployments.

- Zeek now supports a new ``@pragma`` directive. It currently allows suppressing
  deprecation warnings in Zeek scripts by opening with
  ``@pragma push ignore-deprecations`` and closing with ``@pragma pop``.
  This particularly helps in situations where use of the Zeek base scripts, for
  example to populate a deprecated field for API compatibility, would otherwise
  trigger deprecation warnings.

- The ``Reporter`` class was extended by a ``Deprecation()`` method to use
  for logging deprecations rather than using ad-hoc ``Warning()`` calls.

- The network statistics record type features a new ``pkts_filtered`` field for
  reporting the number of packets that the interface filtered before hand-off to
  Zeek. Packet source implementations are free to fill this field as
  feasible. The default pcap packet source does not provide this information
  because its availability depends on the libpcap version.

- Packet statistics (packets received, packets dropped, bytes received, packets
  seen on link, and packets filtered) are now reported to the Telemetry
  framework, under the ``zeek_net`` prefix.

- Zeek's cluster framework provides the new ``get_node_count(node_type: NodeType)``
  function to obtain the number of nodes for a given node type as defined in the
  cluster layout. Furthermore, ``broadcast_topics`` was added as a collection of
  broker topics that can be used to reach all nodes in a cluster.

- The new ``Cluster::Experimental`` namespace has been introduced to Zeek's cluster
  framework to provide experimental features. Based on practical experiences and the
  adoption of an experimental feature, it may become a regular feature or be removed
  in future releases. Experimental features are loaded via:
  ``@load policy/frameworks/cluster/experimental``

- Zeek's cluster framework provides two new experimental events:

  - ``cluster_started``: This event will be broadcasted from the manager once all
    cluster-level connections have been established based on the given cluster layout.
    If any node restarts (including the manager itself), the event will neither be
    rebroadcasted nor raised locally for the restarted node.

  - ``node_fully_connected``: This event will be sent to the manager and raised
    locally once a cluster node has successfully conducted cluster-level handshakes
    for all its outgoing connections to other cluster nodes based on the given cluster
    layout.

  Note: There is no tracking of cluster node connectivity. Thus, there is no guarantee
  that all peerings still exist at the time of these events being raised.

- The IEEE 802.11 packet analyzer gains the ability to parse encapsulated A-MSDU
  packets, instead of just dropping them. It also gains the ability to properly
  recognize CCMP-encrypted packets. These encrypted packets are currently
  dropped to Zeek's inability to do anything with them.

- Add packet analyzers for LLC, SNAP, and Novell 802.3, called from the Ethernet
  and VLAN analyzers by default.

- Environment variables for the execution of log rotation postprocessors can
  be set via ``Log::default_rotation_postprocessor_cmd_env``.

- The ``record_field`` record was extended by ``optional`` and ``record_fields()``
  can now be used to determine the optionality of record fields.

- The ``ip4_hdr`` record was extended by ``DF``, ``MF``, ``offset`` and ``sum``
  to aid packet-level analysis use-cases.

- Zeek now supports parsing the recently standardized DTLS 1.3. Besides the protocol
  messages being correctly parsed and raising the typical SSL/TLS events, the biggest
  visible change is the newly added ``ssl_extension_connection_id`` event.

- The NTP analyzer now recognizes when client and server mode messages disagree
  with the notion of "originator" and "responder" and flips the connection. This
  can happen in packet loss or packet re-ordering scenarios. Such connections will
  have a ``^`` added to their history.

- New bifs for ``ceil()`` and ``log2()`` have been added.

- Seeds for deterministic processing can now also be set through a new environment
  variable called ``ZEEK_SEED_VALUES``. The format is expected to contain 21
  positive numbers separated by spaces.

Changed Functionality
---------------------

- The base distribution of the Zeek container images has been upgraded to
  Debian 12 "bookworm" and JavaScript support was enabled.

- When ``get_file_handle()`` is invoked for an analyzer that did not register
  an appropriate callback function, log a warning and return a generic handle
  value based on the analyzer and connection information.

- The ``&on_change`` attribute of set and tables is propagated through ``copy()``.

- Revert back to old method of preallocating ``PortVal`` objects for all valid
  port numbers, as it was implemented prior to the Windows port. Not
  preallocating these objects saves a minor amount of memory for short runs of
  Zeek, but comes at a performance cost for having to allocate the objects every
  time a new port is seen plus do map lookups for each port. This memory savings
  is mostly lost for long runs of Zeek, since all of the ports will likely end
  up allocated in time.

  If the version from the Windows port is desired, a new configure option
  ``--disable-port-prealloc`` will disable the preallocation and enable the map
  lookup version.

- The main-loop has been changed to process all ready IO sources with a
  zero timeout in the same loop iteration. Previously, two zero-timeout
  sources would require two main-loop iterations. Further, when the main-loop
  is polling IO sources with file descriptors, zero timeout IO sources are
  added to the list of sources to be processed as well.

  The intervals to decide when Zeek checks FD-based IO sources for readiness
  have been made configurable through ``io_poll_interval_default`` and
  ``io_poll_interval_live`` for ease of testing, development and debugging
  of the main-loop.

- Zeek does not arbitrarily update ``network_time()`` to current time anymore.
  When a packet source is providing a constant stream of packets, packets
  drive network time. Previously, Zeek updated network time to current
  time in various situations, disregarding timestamps of network packets.
  Zeek will now update ``network_time()`` only when a packet source has been
  inactive/idle for an interval of ``packet_source_inactivity_timeout``
  (default 100msec). When a worker process suddenly observes no packets, timer
  expiration may initially be delayed by ``packet_source_inactivity_timeout``.

- Calling ``suspend_processing()`` when reading traces does not update network
  time to the current time anymore. Instead, Zeek keeps ``network_time()``
  according to the trace file. This causes scheduled events to not fire once
  ``suspend_processing()`` is called, which seems more reasonable than
  arbitrarily setting ``network_time()`` to current time. Processing can still
  be continued from broker events or input readers.

- Previously, Zeek would process and dispatch events for the very first packet
  in a trace file in order to initialize time, even if ``suspend_processing()``
  was called in a ``zeek_init()`` handler. This has been changed such that the
  first packet will only be processed once ``continue_processing()`` has been
  invoked again. Some background around the previous behavior can be found
  in GH-938. Given that the ``network_time_init()`` event explicitly signals
  initialization of network time, this behavior seems more reasonable.

- If an event is scheduled with a 0.0sec timeout from a ``zeek_init()`` handler
  that also invokes ``suspend_processing()``, the scheduled event will fire
  immediately with ``network_time()`` still yielding ``0.0``. Previously,
  ``network_time()`` was set to the current time. The new behavior provides
  more deterministic operation and aligns with timers stopping during a
  ``suspend_processing()``.

- Broker no longer initializes network time to current time when processing
  input. Particularly in combination with pcap processing this was not desirable
  behavior.

- The IO loop's poll interval is now correctly reduced from 100 to 10 for
  live packet sources. This should lower CPU usage for deployments with
  non-selectable packet sources.

- Zeek's CMake scaffolding has received an overhaul for modernizing the build
  system and to make it easier to maintain going forward. Plugins can now use a
  declarative interface for adding all sources, BIFs, etc. in one block instead
  of using the previous begin/end functions. While the old plugin functions
  still exist for backward compatibility, the underlying codebase requires newer
  CMake features. Plugin authors should raise their minimum required CMake
  version to 3.15, to match Zeek's.

- The IRC data analyzer does not extract DCC acknowledgements to files anymore.
  Instead, ``irc_dcc_send_ack`` is raised with the bytes acknowledged by the
  recipient.

- The IRC base script now use ``file_sniff()`` instead of ``file_new()`` for
  DCC file transfers to capture ``fuid`` and inferred MIME type in irc.log.

- The ``ignore_checksums`` script variable now reflects the correct value
  when using the ``-C`` command-line flag.

- Support for ARUBA GRE tunnels now covers all of the known protocol type values
  for those tunnels.

- The vlan field reported by the AF_PACKET packet source is now properly
  masked to exclude PCP and DEI bits. Previously, these bits were included
  and could cause invalid vlan values > 4095 to be reported.

- Libpcap based packet source now avoids the 32bit wraparound of link and
  dropped packet counters as reported by users.

- The `ssl_history` field in ssl.log indicates that the letter `j` is reserved
  for hello retry requests. However, this logging was never fully implemented;
  instead, hello retry requests were logged like as a server hello (with the letter
  `s`). This oversight was fixed, and hello retry requests are now correctly logged.

- When per-connection SMB parser state (read offsets, tree ids, ...) exceeds
  ``SMB::max_pending_messages`` (default 1000), Zeek discards such per-connection
  state and raises a new ``smb2_discarded_messages_state()`` event. This event is
  used to reset script-layer SMB state. This change provides protection against
  unbounded state growth due to partial or one-sided SMB connections.

  Setting ``SMB::max_pending_messages`` to 0 can be used to switch back to the
  previous behavior of not discarding state. Setting ``SMB::enable_state_clear``
  to ``F`` skips the script-layer state clearing logic.

- Fix ``disable_analyzer()`` builtin function crashing when attempting to
  disable connection's root analyzers.

- Zeek script vectors now support negative indices.

	local v = vector(1, 2, 3);
	print v[-1];  # prints 3

- Function parameters are rendered by Zeekygen as ``:param x`` rather than just
  ``:x:``. This allows to group parameters Zeek's documentation.

Removed Functionality
---------------------

- Mixing vector and scalar operands for binary expressions, like addition,
  multiplication, etc., is now an error.

- Using deprecated ``when`` semantics without capturing variables is now an error.

- Referencing local variables in a more outer scope than where they were declared
  is now an error

Deprecated Functionality
------------------------

- The cluster framework's ``worker_count`` has been deprecated in favor of the
  new function ``get_active_node_count(node_type: NodeType)`` that can be used
  to obtain the number of nodes of a given type the calling node is currently
  connected to.


Zeek 5.2.0
==========

Breaking Changes
----------------

- Zeekctl now assigns network ports to workers starting at port 27760. This
  fixes an issue where workers were starting up with ports within Linux's
  ephemeral port range, and were potentially failing to startup due the ports
  already being in use. This change may require changes in firewall/routing
  configurations between hosts in a Zeek cluster. This should not affect
  clusters running on FreeBSD, as that OS uses a different range for ephemeral
  ports.

- Zeekctl support for the AF_PACKET plugin specific options (af_packet_*) has
  been integrated into zeekctl directly. Upgrading to Zeek 5.2 with a builtin
  AF_PACKET packet source (default on Linux) requires an upgrade of zeekctl
  to the version bundled with Zeek to continue using these options.

- The blank identifier ``_`` cannot be used in expressions and options anymore.
  Outside of obfuscation exercises, this should have little real-world impact.

- A new ``mysql_eof`` event has been introduced and the ``mysql_ok`` event
  is not raised in its place or artificially anymore. The base scripts were
  adapted accordingly. Users of ``mysql_ok()`` likely need to switch to
  ``mysql_eof()``.

- Zeek will now exit at startup if an external plugin (e.g. from a package) is
  discovered to have the same name as a built-in plugin. See below for the
  change regarding the AF_PACKET plugin now being built-in for an example of
  this potentially being triggered.

- DNS query type strings were updated to match the current standardized list of
  strings. This changes the string reported for a small subset of query types:

	30: Changed from "EID" to "NXT"
	31: Changed from "NIMLOC" to "EID"
	32: Changed from "NB" to "NIMLOC"

- The ``--with-caf`` option for the ``configure`` script was removed. Broker now
  requires specific versions of CAF per Zeek release, and passing an
  externally-built version of CAF often lead to build failures.

New Functionality
-----------------

- Experimental support added for building and running Zeek on Microsoft Windows
  environments. This is considered experimental due to the fact that our
  standard testing setup (btest) doesn't run properly on Windows. This will be
  fixed in the future. In the meantime we have done some basic testing against
  builds done with Visual Studio 2019. Information on how to build on Windows is
  available in the Zeek documentation. Note also that Spicy is currently
  unsupported and will be fixed in the future.

  The feature as checked into the repository is not considered production-ready.
  There are many bugs to squash and features to improve, and we will be steadily
  fixing things over the next few months.

  The Zeek team wants to give a huge thank you to the team at Microsoft for all
  of their effort in completing this port.

- Zeek container images are now being published to zeek/zeek and zeek/zeek-dev
  rather than zeekurity/zeek and zeekurity/zeek-dev on Docker Hub (and continue
  to be published to public.ecr.aws) Further, container images for amd64 and
  arm64 platforms are now available. Main driver for the latter was to allow
  usage of the official container images on Apple's M1 systems.

- Zeekctl support for using ``af_packet`` as ``lb_method`` has been added.

- New ``analyzer_confirmation_info`` and ``analyzer_violation_info`` events with
  accompanying record types ``AnalyzerConfirmationInfo`` and
  ``AnalyzerViolationInfo`` have been added. These supersede
  ``analyzer_confirmation`` and ``analyzer_violation``, which have been
  deprecated.

- Added helpers to determine protocol, packet or file analyzer based on
  ``AllAnalyzers::Tag`` values named ``is_protocol_analyzer()``,
  ``is_packet_analyzer()`` and ``is_file_analyzer()``.

- File analyzers can now raise analyzer violations to the script-layer via the
  new ``AnalyzerViolation()`` method.

- Packet and file analyzers can now be disabled and enabled at runtime using the
  ``Analyzer::enable_analyzer()`` and ``Analyzer::disable_analyzer()``
  wrappers. While initially for protocol analyzers only, these have been
  extended to work for packet and file analyzers. This now allows to leverage
  ``Analyzer::disabled_analyzers`` for these kinds of analyzers.

- The blank identifier ``_`` can now be used to ignore loop variables of
  different types without type clash errors. This allows to do the following
  within the same scope:

	local vec = vector("a", "b", "c");
	for ( _, v in vec )
		print v;

	for ( i, _ in vec )
		print v;

  Iterating over only the values of a table can be done by ignoring the full
  index with a single blank identifier. Due to the internal structure of Zeek
  tables, this can result in a performance improvement.

	local tab = table(["a", 1, T] = "a1T", ["b", 2, F] = "b2f");
	for ( _, v in tab )
		print v;

  It's also possible ignore individual indices of different types with the blank
  identifier ``_`` as follows:

	for ( [_, i, _], v in tab )
		print i, v;

  As noted under breaking changes, the blank identifier ``_`` cannot be
  referenced in expression anymore.

- It is now possible to put trailing commas within table, vector, set and record
  construction. For example, the following code is now valid, which can make for
  more uniform style and smaller diffs.

	local vec = vector(
		"1",
		"2",
	);

	local tab: table[string] of count = [
		["a"] = 1,
		["b"] = 2,
	];

  Function calls and record constructors can have a trailing comma after the
  last argument.

	Analyzer::schedule_analyzer(
		chan$orig_h,
		chan$resp_h,
		chan$resp_p,
		Analyzer::ANALYZER_FTP_DATA,
		5mins,
	);

- Re-introduce event groups. Allow the ``&group`` attribute on event and hook
  handlers for annotating them with one or more event groups. These groups can
  be disabled and enable during runtime. Disabling an event group implies
  disabling all event and hook handlers that are part of it.

  The main difference to a previous implementation in (very) old Zeek versions
  is its granularity: It is now possible to toggle individual event handlers
  (event handler bodies). The original implementation worked at the level of
  events, disabling or enabling all event handlers for a given event at once.
  Additionally, support for hooks was added as these are structurally similar to
  events.

  The BIFs ``disable_event_group()`` and ``enable_event_group()`` are
  re-instantiated and allow controlling event groups based on the group
  attribute.

  Additionally, event and hook handlers are implicitly placed into event module
  groups based on the module they are implemented in. All events implemented in
  a given module can be toggled with ``disable_module_events()`` and
  ``enable_module_events()``.

- Extend the ``Logging::Stream`` record with an ``event_groups`` field and
  toggle these during ``Log::disable_stream`` and ``Log::enable_stream``
  invocations. This allows for explicit/manual opt-in performance optimizations
  by turning off event handlers at runtime that are only needed for log
  generation.

- On Linux, the AF_PACKET packet source plugin
  (https://github.com/zeek/zeek-af_packet-plugin) is included as a builtin
  plugin by default. To select this packet source, prefix the interface name
  with ``af_packet``.

	zeek -i af_packet::eth0

- Usage of ``break`` and ``next`` statements is now validated. It was previously
  possible to place these outside of ``for``, ``while`` or ``switch`` statements
  without any error indication.

- Add two BIFs ``get_identifier_declaring_script()`` and
  ``get_record_field_declaring_script()`` to query the declaring scripts for
  identifiers and record fields from Zeek scripts.

- Extend the SSH analyzer to produce new events (``ssh2_ecc_init``,
  ``ssh2_gh_gex_init``, ``ssh2_gss_init``, ssh2_rsa_secret``) to detect when SSH
  client and server roles are reversed.

- Analyzers found in the new ``Analyzer::requested_analyzers`` set will be
  enabled at ``zeek_init()`` time. The set can be populated via
  :zeek:see:`redef`.  This change only has an effect in settings where
  ``Analyzer::disable_all`` is changed to ``T``. By default, all analyzers
  continue to be enabled.

- A new ``analyzer.log`` was added to log all analyzer violations and optionally
  analyzer confirmations. This log can be useful during development of new
  analyzers as well as for collecting operational data in production
  environments.

- Expose configurability of for SQLite's synchronous and journal_mode PRAGMAs
  for SQLite backed Broker data stores. Setting these to synchronous=normal
  and journal_mode=wal can significantly improve throughput at the cost of
  some durability in the presence of power loss or OS crash. In the context
  of Zeek, this is likely more than acceptable.

  Additionally, add integrity_check and failure_mode options to support
  detecting and deleting corrupted SQLite database at store initialization.

- A new ``join_string_set`` BIF was added, replacing the existing script-level
  version from utils/strings.zeek.

- A new ``&ordered`` attribute for tables and sets was added. This attribute
  causes iteration over a table/set to return elements in the order of their
  insertion.

- A new ``-D`` argument was added to the ``configure`` script to allow passing
  parameters directly to the underlying CMake call.

- Added parsing for the challenge and response fields to the NTLM analyzer.

- A new ``FTP::max_command_length`` value was added to script-land, defaulting
  to 100. This value is used by the FTP analyzer to limit the size of commands
  accepted by the analyzer. A ``FTP_max_command_length_exceeded`` weird is
  raised for any violations of that length.

- The MySQL analyzer has been extended to detect when client and server negotiate
  to use a SSL encrypted session. This allows analysis of the subsequent SSL
  handshake. The service field for encrypted MySQL connections in the conn.log
  will have entries for both, mysql and ssl.

Changed Functionality
---------------------

- Violations for packet analyzers that have sessions attached with them will be
  raised once only. Further, analyzer confirmations are not raised after a
  violation.

- The parameter given to ``enum_names()`` can now be a string naming the enum
  type, rather than the type itself.

- The ``type_name`` of enum types produced by ``record_fields()`` now includes
  the actual type name rather than just ``"enum"``.

- Passing non-string ``sep`` and ``def`` arguments to ``cat_sep()`` isn't a
  fatal error anymore. More descriptive error messages are produced, too.

- The number of analyzer violation events that can be raised by protocol
  analyzer instances is now capped by the const
  ``max_analyzer_violation_events``.

- The number of analyzer violation events that can be raised by protocol and
  file analyzer instances is now capped by the const
  ``max_analyzer_violation_events``.  Its default is 1000 and the main purpose
  is to prevent analyzers from scheduling too many ``analyzer_violation_info``
  events before the DPD ``max_violations`` script-level logic has a chance to
  run and disable the problematic analyzer.

- The TCP analyzer now continues processing payload for some
  connections missing initial packets where it would previously have
  stopped. This fixes a few cases where we already had the logic to
  continue in place, but we still ended up considering them partial.

- Count underflows via ``--c`` or subtract from statements (``c = c - 1``) are
  now consistently warned about. Previously, underflows through ``--c`` were
  treated as runtime errors, while "subtract from" underflows were silently
  accepted. The following (surprising behavior) now causes a warning, too:

	$ zeek -e 'print 1 - 2'
	expression warning in <command line>, line 1: count underflow (1 - 2)
	18446744073709551615

- The MQTT scripts registering the analyzer and DPD signatures have been moved
  from the policy folder to base and are loaded by default.

- Notices created for files transferred over multiple connections will now be
  associated with one of the connections rather than none.

- The MySQL analyzer has been switched to parse in little endian. This avoids
  analyzer violations due to out of bound errors for length encoded strings.

- Non-fatal errors when setting up BPF filtering will no longer cause Zeek to
  exit, but instead will log the error in reporter.log and continue processing.

- The languages reported for the ``keyboard_layout`` field in rdp.log were
  updated to match the current standardized set of languages. Unknown layout
  values now attempt to fallback to a "parent" layout if one is available.

- In the cluster management framework, the controller now supports Broker's
  WebSocket data transport for communication with clients. It listens on TCP
  port 2149 for this purpose. zeek-client now likewise uses the WebSocket
  transport, removing its runtime dependency on the Broker library and enabling
  standalone installation. The client still bundles with Zeek by default but is
  now also available on PyPI and installable via ``pip install zeek-client``.
  The documentation provides additional details.

Deprecated Functionality
------------------------

- The global ``disabling_analyzer()`` hook has been deprecated and replaced
  with ``Analyzer::disabling_analyzer()`` that has the same semantics.

- The ``analyzer_confirmation`` and ``analyzer_violation`` events have been
  deprecated in favor of the more generic ``analyzer_confirmation_info`` and
  ``analyzer_violation_info`` events.

- The const values for toggling individual tunnel packet analyzers have been
  deprecated in favor of using ``Analyzer::disable_analyzer()`` directly. This
  affects:

	Tunnel::enable_ip
	Tunnel::enable_ayiya
	Tunnel::enable_teredo
	Tunnel::enable_gtpv1
	Tunnel::enable_gre

  Setting these explicitly to F can be achieved by leveraging
  ``Analyzers::disabled_analyzers``, for example:

	redef Analyzer::disabled_analyzers += { PacketAnalyzer::ANALYZER_GRE };

- The ``zeek::merge_type_list()`` function has been deprecated. Please consider
  the partially compatible and saner ``zeek::maximal_type()`` instead. See
  GH-2604 for context.

- The pre-authentication data field (pa_data) available in certain Kerberos
  events now exposes the (encrypted) PA-ENC-TIMESTAMP field (padata-type=2).

- The ``SupressWeirds()`` method in the ContentLine analyzer was deprecated in
  favor of the correctly-spelled ``SuppressWeirds()`` method.

- The `bro` symlink has finally been removed.

Zeek 5.1.0
==========

Breaking Changes
----------------

- The ``Packet::{l2,l3}_checksummed`` variables were reworked to correctly match
  the network layers that they apply to. A new ``Packet::l4_checksummed``
  variable was added to cover the transport layer. See this GitHub issue for
  more detail: https://github.com/zeek/zeek/issues/2183.

- The STREAM mode of the ASCII reader now behaves like `tail -F`: when file is
  removed/replaced, it will start tracking the new file. See
  https://github.com/zeek/zeek/pull/2097 for more detail

- The Dictionary and PDict classes are now C++ templates. This may cause
  plugin/package builds to fail due to needing to modify uses of them to match.

- By default, ``files.log`` does not have the fields ``tx_hosts``, ``rx_hosts``
  and ``conn_uids`` anymore. These have been replaced with the more commonly
  used ``uid`` and ``id`` fields. They can be re-instantiated by loading the
  following policy script through ``local.zeek``:

	@load frameworks/files/deprecated-txhosts-rxhosts-connuids

  Note, however, that this script will be removed with Zeek 6.1. Consumers
  of ``files.log`` should convert to using the singular ``uid`` and ``id``
  fields instead.

- The ``files.log`` is now unrolled consistently. That is, when Zeek associates
  multiple connections with a single file, each of these connections will result
  in individual ``files.log`` entries with unique connection uids, all sharing
  the same file uid.

  This unrolling behavior always existed in a Zeek cluster when the network
  connections involved in a file transfer are load-balanced to different
  workers.  Due to this affecting only a marginal ratio of files on real-world
  networks, unrolling the log was chosen as the more efficient approach over
  making the current logic cluster aware.

  The ``seen_bytes`` and ``missing_bytes`` fields of a ``File::Info`` record
  continue to represent the total number across all connections seen by the
  current instance of Zeek.

- The barnyard2 policy scripts have been removed. The integration with the
  Barnyard2 project used the pre-Broker Broccoli library, which got removed in
  Zeek 3.0.

- The unified2 analyzer and accompanying scripts have been removed without
  deprecation.

- The return value of ``packet_analysis::IP::ParsePacket`` has changed to return
  enum values. This makes it easier to look at the result and immediately know
  what it means. Unfortunately, because we can't overload a method on the return
  value alone, we aren't able to deprecate the original version of the method.
  This may cause build of packages to fail if they were using this method.

- Conditional directives (``@if``, ``@ifdef``, ``@ifndef``, ``@else`` and
  ``@endif``) can not be placed directly following ``if``, ``for`` or ``while``
  statements anymore. This was interpreted non-intuitively and could lead to
  subtle bugs.  The statement following the directive was placed outside of its
  intended block.  Placing braces after ``if``, ``for`` or ``while`` should
  result in the intended behavior.

- The ``bro`` symlink to the ``zeek`` binary has finally been removed.

- The connection's service field does not hold "negated" analyzer names
  anymore (analyzers that triggered violations after a confirmation).
  These analyzers are now tracked in a separate ``service_violation``
  field with their respective enum values instead.

New Functionality
-----------------

- Added support for the /s regular expression modifier. Using this modifier in
  patterns in Zeek scripts will cause the '.' character to also match newline
  characters.

- Added a new telemetry framework for providing high-level access to Zeek's
  metric subsystem. This framework allows script writers to use different metric
  types (counters, gauges and histograms) for tracking metrics without using
  lower-level BiFs from ``telemetry.bif``. Additionally, metrics can now be
  accessed from script land using ``Telemetry::collect_metrics()`` and
  ``Telemetry::collect_histogram_metrics()``.

  The framework is located in ``base/frameworks/telemetry``.

  In addition to the Prometheus endpoint for metrics export that has existed
  since Zeek 4.1, two new log streams, ``telemetry.log`` and
  ``telemetry_histogram.log``, can be enabled by loading
  ``policy/frameworks/telemetry/log``. This policy script is included in
  ``local.zeek`` by default.

  For further details on the framework and examples, please refer to the
  Zeek documentation.

- Allow redef'ing the ``&log`` attribute of record fields:

	redef Notice::Info$email_dest -= { &log };

  While the syntax allows for any attribute, only ``&log`` is supported. The
  semantics for other record field attributes are not easy to grasp and there
  were no obvious use-cases identified.

- Introduced a global ``disabling_analyzer()`` hook to allow vetoing calls
  to ``disable_analyzer()``.

  The contract is simple: Any script can veto a ``disable_analyzer()`` call by
  breaking from this hook. The decision is local to the script taking into
  account any state attached to the connection or state stored elsewhere.
  A script breaking from the hook takes over responsibility to call
  ``disable_analyzer()`` at a later point when it finds the condition due
  to which it vetoed fulfilled (which may be never).

- Add support for iterating over indices and values of a vector using the
  same syntax as used for iterating over key-value pairs of tables, where
  ``value`` will be set to ``vec[idx]``.

	local vec = vector("zero", "one", "two");
	for ( idx, value in vec )
		print idx, value;

- The Supervisor framework now allows better control over where to place
  additional scripts in the load sequence of new nodes. It previously always
  loaded such scripts after any other user scripts, which could create pitfalls
  when users expected their scripts to run last. Scripts placed in
  ``NodeConfig``'s new ``addl_base_scripts`` and ``addl_user_scripts`` fields
  will be loaded after the base scripts (and thus before any user scripts) and
  after any user scripts, respectively. The old ``NodeConfig$scripts` field
  still adds to the very end and is deprecated.

- Added a new script-level option ``max_changes_per_connection`` to limit the
  number of ``tunnel_changed`` events that can be sent for a connection. This
  helps prevent log spam from connections that regularly swap. The option
  defaults to 5, and can be set to zero do disable the limiting.

- Added a new BIF ``bytestring_to_float`` for converting 4-byte bytestrings to
  float values.

- Added a new BIF ``pow``.

- Added new bit-shift operators ``<<`` and ``>>`` for use in scripts.

- Added a new BIF ``table_keys`` which returns a ``set`` of keys from a table.

- Added a new BIF ``table_values`` which returns a ``vector`` of keys from a
  table.

- Added new fields to the Modbus log for the Modbus PDU type, the transaction
  ID, and the unit ID. See https://github.com/zeek/zeek/pull/2281 for more
  information.

- Added support for parsing TCP option 27, and fixed validation of lengths for
  TCP options 28, 29, and 34.

- Added new packet-analyzer to handle the DLT_LINUX_SLL2 PCAP link type.

Changed Functionality
---------------------

- The SSL analyzer now determines the direction of the SSL/TLS session by examining
  the packets, and no longer assumes that the connection originator is the client.
  Due to this, the ``is_orig`` field in all SSL/TLS events was renamed to ``is_client``.

  Furthermore, the ``ssl_history`` now can indicate that the connection was flipped
  (meaning that it is not in the normal order of the originator is the client) using
  the ``^`` character. A new ``ssl_connection_flipped`` is raised when the connection
  is flipped. Furthermore, a ``SSL_unclear_connection_direction`` weird is raised when
  we cannot determine the connection direction, because both sides of the connection
  send packets that are associated with being a client/server.

- The default logging directory is now set globally across all log
  writers through ``Log::default_logdir``.

- Calling `Option::set()` when Zeek is terminating is now a noop and returns `F`.
  This prevents callbacks into script-land through change handlers when parts
  of the environment have already been torn down.

- When running in cluster mode, the manager by default now imports metrics from
  all other cluster nodes and opens port 9911/tcp for Prometheus metrics exposition.

- The ``smb2_file_delete`` event will now be raised for SMB2 ``CREATE`` requests
  marked with the ``FILE_DELETE_ON_CLOSE`` option.

- Fixed ``bytestring_to_count`` to handle 3-, 5-, 6-, and 7-byte strings.

Removed Functionality
---------------------

- The barnyard2 policy scripts have been removed.

- The unified2 analyzer and accompanying scripts have been removed.

Deprecated Functionality
------------------------

- The ``PDict`` class is now an alias to ``Dictionary`` and has been
  deprecated. Use ``Dictionary`` directly, passing a pointer type to the
  template.

- ``LogAscii::logdir`` and per-writer log directories have been deprecated in
  favor of the new ``Log::default_logdir``.

- The ``HOOK_BRO_OBJ_DTOR`` hook and associated methods have been
  deprecated. They are replaced by the ``HOOK_OBJ_DTOR`` hook and methods.

- The ``bro_int_t`` and ``bro_uint_t`` types have been deprecated and replaced
  by ``zeek_int_t`` and ``zeek_uint_t``.

- The ``bro_inet_ntop.h`` and ``bro_inet_ntop.c`` files have been deprecated and
  replaced by ``zeek_*`` files.

- The ``BRO_PLUGIN_API_VERSION`` has been deprecated and replaced by
  ``zeek::PLUGIN_API_VERSION``.

- The ``misc/scan.zeek`` script has been marked for removal in Zeek 6.1.  Use
  github.com/ncsa/bro-simple-scan instead.

- The Supervisor framework's ``NodeConfig$scripts`` field has been deprecated
  and marked for removal in Zeek 6.1. Use ``NodeConfig$addl_user_scripts``
  instead.

Zeek 5.0.0
==========

Breaking Changes
----------------

- Zeek now requires at least CMake version 3.15.0.

- If Zeek is configured with support for included Spicy (the default) we now
  require at least Flex version 2.6 and its development headers, at least Bison
  version 3.3, and GCC version 8.3 or Clang version 9.0 or higher.

- The script-land ``union`` and ``timer`` types have been removed. They haven't
  had any actual semantics backing them for some time and shouldn't have
  functioned in any useable way. We opted to skip the deprecation cycle for
  these types for that reason.

- Broker now uses a new network backend with a custom network protocol that is
  incompatible with the pre-5.0 backend. In practice, this means Zeek 4.x will
  not be able to exchange events with Zeek 5.x. Going forward, this new backend
  will allow us to keep the Broker protocol more stable and add new capabilities
  in a backwards compatible way.

New Functionality
-----------------

- The Zeek cluster management framework now supports operational use of
  single-instance clusters, meaning setups in which all Zeek cluster nodes
  (manager, workers, etc) reside on a single machine. The framework builds upon
  Zeek's Supervisor (``-j`` is a requirement) and includes three components:

  (1) A cluster controller, loaded via ``policy/frameworks/management/controller`.
      The controller is the central management entity for a Zeek cluster. It
      interacts with one or more agents to enact instructions delivered by a
      management client. The controller is stateful and can persist cluster
      state to disk.

  (2) One or more cluster agents, loaded via ``policy/frameworks/management/agent`.
      Each agent assists the controller in managing the local instance (typically
      a machine or container) of Zeek cluster nodes. Agents interact with the
      local Supervisor to control nodes and peer directly with running Zeek
      nodes via Broker to carry out node-local tasks.

  (3) zeek-client, the cluster management client. A standalone client running
      outside of Zeek, it's now installed by default, alongside the other
      executables. The client supports uploading cluster configurations to the
      controller, deploying them, retrieving them, checking cluster node status,
      restarting individual cluster nodes, and retrieving the current value(s)
      of global identifiers in one or more Zeek nodes.

  Controller and agent come pre-configured for single-instance deployments of
  Zeek clusters, with automated log rotation and archival via Zeek's
  ``zeek-archiver`` tool. For further details on the framework, please refer
  to the Zeek documentation.

  zeekctl remains included and offers more knobs and features than the
  management framework. It remains the recommended solution for multi-machine
  clusters and those needing rich management capabilities.

- Zeek now automatically warns about unused functions, hooks, and event
  handlers.  The intent behind these checks is to catch instances where the
  script writer has introduced typos in names, or has forgotten to remove
  code that's no longer needed.

  For functions and hooks, "unused" means the function/hook is not exported or
  in the global scope (nor deprecated), and no "live" (i.e., not "unused")
  function/hook/event handler calls it.  For event handlers, "unused" means
  that the event engine does not generate the event, nor do any "live"
  function/hook/event handler generates (and the event handler is not
  deprecated).

  The warnings can occasionally be or inappropriate or incorrect, such as due
  to the use of conditional code (which Zeek does not try to incorporate
  into its analysis), or events sent via Broker.  You can mark such instances
  using the ``&is_used`` attribute to suppress the associated warning.
  You can also suppress all such warnings using the ``--no-unused-warnings``
  command-line option.

- A new feature, ``--profile-scripts[=file]`` instructs Zeek to write (upon
  termination) a profile of every function body to the given file (default:
  stdout), along with some aggregate profiles. A function body is associated
  with a function or a BiF (they can only have one), or a hook or event handler
  (they can have multiple).  The profile is in TSV, quasi-Zeek-log format.  It
  includes (1) the name of the script body, (2) its location, (3) its type
  (e.g., "BiF" or "function"), (4) how many times it was called, (5) the total
  CPU time that accumulated during its execution, (6) how much of that time was
  due to execution of its "children" (other functions it called), (7) the total
  memory allocated during its execution (approximately), and (8) how much of
  that memory was due to its children.  Note that profiling is expensive and may
  not be suitable for execution on live traffic.

- Zeek now includes support for building Spicy and spicy-plugin as part of
  Zeek. This feature is enabled by default, and can be turned off by passing the
  ``--disable-spicy`` flag to ``./configure``.

- Zeek now supports generation and replay of event traces via the new
  ``--event-trace`` / ``-E`` command-line options. For details, see:
  https://docs.zeek.org/en/master/quickstart.html#tracing-events

- Zeek now features limited TLS decryption capabilities. This feature is
  experimental and only works for TLS 1.2 connections that use the
  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ciphersuite. Furthermore Zeek requires
  access to the pre-master secret of each TLS connection. Typically this
  functionality will be most useful when analyzing trace-files where the TLS
  client recorded the key material. For more details and examples how to use
  this functionality, see the TLS Decryption documentation at
  https://docs.zeek.org/en/master/frameworks/tls-decryption.html

- Zeek now provides WebSocket support for exchanging events with external
  clients. To enable it, call `Broker::listen_websocket()`.  Zeek will then
  start listening on port 9997 for incoming WebSocket connections. Zeek/Broker
  communicates via JSON messages. See the Broker documentation for a description
  of the message format expected over these WebSocket connections at
  https://docs.zeek.org/projects/broker/en/current/web-socket.html.

- Compiling scripts to C++ (via ``-O gen-C++``) is now "feature complete", i.e.,
  the compiler should be able to process any script - other than those
  potentially affected by ``@if`` conditionals - regardless of which Zeek
  language constructs it uses.  That said, such compilation remains
  experimental and only lightly tested.

- ZAM script optimization (``-O ZAM``) now includes some major performance
  improvements.

- The new --with-gen-zam configure flag and its corresponding GEN_ZAM_EXE_PATH
  cmake variable allow reuse of a previously built Gen-ZAM code generator. This
  aids cross-compilation: the Zeek build process normally compiles Gen-ZAM on
  the fly, but when cross-compiling will do so for the target platform, breaking
  its use on the host platform. Gen-ZAM is similar to binpac and bifcl in this
  regard. Like binpac and bifcl, it's now also available as a standalone git
  repository and hooked into the Zeek distribution as a submodule.

- Zeek now uses the c-ares (https://c-ares.org) library for performing DNS
  requests, replacing an old custom implementation of a DNS resolver. Switching
  to this library simplifies the DNS code, adds support for IPv6 lookups, and
  adds the ability to support more DNS request types in the future.

- Two new BiFs, val_footprint() and global_container_footprints(), offer
  substitutes for the deprecated val_size() and global_sizes() BiFs.  A value's
  "footprint" is the number of elements it includes either directly or
  indirectly.  The number is not meant to be precise, but rather comparable:
  larger footprint correlates with more memory consumption.

- The Supervisor features two new events, ``Supervisor::node_status`` and
  ``SupervisorControl::node_status``, to notify recipients of the fact that the
  stem process has (re-)started a node. The events indicate the node's name and
  its new PID, reflecting the information the stem already shares with the
  Supervisor core.

- The new ``configure --statedir`` option lets you adjust the installation's
  persistent state directory. It defaults to ``var/lib`` under your Zeek
  installation's root directory.

- The ``base/misc/installation.zeek`` script provides your Zeek installation's
  key directories.

- Zeek now lets you decrement Counting Bloom Filters using the new
  ``bloomfilter_decrement`` BiF. Furthermore, two Bloom Filters can be
  intersected using the new ``bloomfilter_intersect`` BiF.

Changed Functionality
---------------------

- The behavior of the ``=``, ``+=``, and ``-=`` operators has been expanded and
  unified. It now covers ``{ ... }`` initializer lists, supports cross-product
  initialization, enables ``+=`` for table, set, vector and pattern values,
  similarly allows ``-=`` for table and set values, and supports listing
  multiple sets for ``+=`` initialization. For details, see:
  https://docs.zeek.org/en/master/script-reference/operators.html#assignment-operators

- The is_num(), is_alpha(), and is_alnum() BiFs now return F for the empty
  string.

- Type mismatch error messages now print the easier to understand type names,
  instead of the fully expanded raw type.

- Errors caused by setting a filter at start-up are now more informative about
  what actually caused the error, including with the default ``ip or no ip``
  filter.

- Log messages about errors in input files are now more informative about where
  errors occurred.

- The ``--enable-zeek-client`` configure flag has been removed and is now the
  default. The new ``--disable-zeek-client`` flag allows users to skip
  installation of the client.

Deprecated Functionality
------------------------

- For developers of asynchronous BiFs, or other uses of ``when`` statement
  triggers, the versions of ``Trigger::Cache`` and ``Trigger::Lookup`` that take
  ``const CallExpr*`` parameters have been deprecated.  The replacements take
  ``const void*`` parameters.  Usually all you'll need to do is replace previous
  uses of ``Frame::GetCall`` with ``Frame::GetTriggerAssoc``.

- The ``--caf-root`` option of ``zeek-config`` was made obsolete by the changes
  to how we include CAF and has been marked as deprecated.

Zeek 4.2.0
==========

Breaking Changes
----------------

- The existing ``Tag`` types in C++ (``zeek::Analyzer::Tag``, etc) have been
  merged into a single type called ``zeek::Tag``. This is a breaking change, and
  may result in plugins failing to build where they were relying on those types
  being different for function overloading and such. We attempted to include
  deprecated versions of the old types, but were unable to do so because of
  changes to return types from a number of methods. With this change, any uses
  of the `zeek::*::Tag` types will need to be replaced by `zeek::Tag`.

- The DPD signature for SSL version 2 is no longer enabled by default. SSLv2
  is basically extinct nowadays - and the protocol has a relatively high probability
  of matching with random traffic and being misidentified. If you want to enable
  the SSLv2 dpd signature, you can load the signature from `policy/protocols/ssl/dpd-v2.sig`

  The DPD signature for SSL version 3 and up (including TLS 1.0 and above) now matches
  for one-sided connections and does not require a reverst match anymore. This prevents
  missed handshakes, where the client handshake contains a lot of data.

New Functionality
-----------------

- We now provide minimal official Docker images for the Zeek project via two
  repositories on the Docker hub, ``zeekurity/zeek`` and ``zeekurity/zeek-dev``.
  The former receives all Zeek release versions, with tag ``zeek:latest`` being
  the most recent. An image corresponding to our latest merge into the master
  branch is tagged at ``zeek-dev:latest``.

  The images run Debian and provide a full install of the Zeek distribution into
  ``/usr/local/zeek``. They do not set Zeek-specific entrypoints or provide any
  particular configuration for operationally running Zeek. To keep the images
  lightweight they also do not contain a development toolchain as needed for
  example to build a Zeek plugin. You can add any required system packages in a
  derived image, or install them directly in the running container.

- Zeek now supports formatting the C++ code using clang-format. Also provided is
  a configuration for ``pre-commit`` to run clang-format when add new commits via
  ``git``. More details can be found at https://github.com/zeek/zeek/wiki/Coding-Style-and-Conventions#clang-format.

- Experimental support for speeding up Zeek script execution by compiling
  scripts to a low-level form called "ZAM".  You activate this feature by
  specifying ``-O ZAM`` on the command line.  See
  ``src/script_opt/ZAM/README.md`` for more information.

- Improvements for compiling scripts to C++ (an experimental optimization
  feature introduced in 4.1).  The generated C++ now compiles much faster than
  previously, though it can still take quite a while when using C++ optimization
  on large sets of scripts.  You can incrementally compile additional scripts
  using ``-O add-C++``.  See ``src/script_opt/CPP/README.md`` for details.

- The new flags --optimize-files=/pat/ and --optimize-funcs=/pat/ apply
  to both ZAM and compile-to-C++ script optimization.  The first instructs
  Zeek to optimize any functions/hooks/event handlers residing in files
  matching the given pattern (unanchored).  The second does the same but
  based on the function name, and with the pattern anchored (so for example
  --optimize-funcs=foo will optimize any functions named "foo" but not
  those named "foobar", or "MYSCOPE::foo").  The flags can be combined
  and can also be used multiple times to specify a set of patterns.
  If neither flag is used then optimization is applied to all loaded
  scripts; if used, then only to those that match.

- The ``-uu`` flag for analyzing potentially unused record fields has been
  removed because, due to other changes in script optimization, keeping it
  would now require about 1,800 lines of code not otherwise needed.

- The DNS analyzer has initial support for the SVCB and HTTPS types. The new
  events are ``dns_SVCB`` and ``dns_HTTPS``.

- The ``find_str`` and ``rfind_str`` bifs now support case-insensitive searches.

- Added a new plugin hook for capturing packets that made it through analysis
  without being processed called ``Plugin::HookUnprocessedPacket``. Currently
  ARP packets or packets with a valid IP-based transport header are marked as
  processed. This also adds an event called ``packet_not_processed`` that
  reports the same packets.

- A new command-line option ``-c`` or ``--capture-unprocessed`` will dump any
  packets not marked as being processed, similar to the new hook and event
  above.

- In Zeek plugins, the new cmake function ``zeek_plugin_scripts()`` should be
  used alongside ``zeek_plugin_cc()`` and related functions to establish
  dependency tracking between Zeek scripts shipped with the plugin and plugin
  rebuilds.  Previously, updates to included Zeek scripts didn't reliably
  trigger a rebuild.

- Added PacketAnalyzer::register_for_port(s) functions to the packet analyzer
  framework in script-land. This allows a packet analyzer to register a port
  mapping with a parent analyzer just like any other numeric identifier, while
  also adding that port to the now-global Analyzer::ports table used by BPF
  filtering.

- Added AllAnalyzers::Tag enum type that combines the existing Analyzer::Tag,
  PacketAnalyzer::Tag, and Files::Tags into a single enum. The existing types
  still exist, but the new type can be used as an argument for
  functions/hooks/events that need to handle any of the analyzer types.

- Added protocol detection functionality to the packet analyzer framework.
  Packet analyzers can register for protocol detection using the
  ``PacketAnalyzer::register_protocol_detection`` script function and implement
  the ``PacketAnalyzer::DetectProtocol`` method in C++. This allows packet
  analyzer plugins to detect a protocol via byte matching or other heuristics
  instead of relying solely on a numeric identifier for forwarding.

- The JSON logger's new LogAscii::json_include_unset_fields flag provides
  control over how to handle unset "&optional" fields. By default it continues
  to skip such fields entirely. When redef'ing the flag to T it includes such
  fields, with a "null" value. This simplifies data import use cases that
  require fields to be present at all times, regardless of their value.

- A new external testsuite, https://github.com/zeek/zeek-testing-cluster,
  focuses on testing the emerging controller framework. It leverages the new
  official Zeek Docker image for building docker-compose test setups, driven via
  btest. The GitHub CI setup now includes a workflow that deploys and runs this
  testsuite.

- The GRE analyzer now supports the Aruba WLAN protocol type.

Changed Functionality
---------------------

- Zeek now treats non-atomic index types for sets and tables more consistently.
  Indexing now generally works with any types Zeek's hashing subsystem knows how
  to serialize, meaning that you can now also index with sets, vectors,
  patterns, and even tables.

- The traditional TSV Zeek logs are now valid UTF8 by default. It's possible to
  revert to the previous behavior by setting ``LogAscii::enable_utf_8`` to
  false.

- The ``SYN_packet`` record now records TCP timestamps (TSval/TSecr) when
  available.

- The ``init-plugin`` script now focuses purely on dynamic Zeek plugins. It no
  longer generates Zeek packages. To instantiate new Zeek packages, use the
  ``zkg create`` command instead.

- The ``ignore_checksums`` options and the ``-C`` command-line option now
  additionally cause Zeek to accept IPv4 packets that provide a length of zero
  in the total-length IPv4 header field. When the length is set to zero, the
  capture length of the packet is used instead.  This can be used to replay
  traces, or analyze traffic when TCP sequence offloading is enabled on the
  local NIC - which typically causes the total-length of affected packets to be
  set to zero.

- The existing tunnel analyzers for AYIYA, Geneve, GTPv1, Teredo, and VXLAN are
  now packet analyzers.

- C++ unit tests are now compiled in by default and can be disabled by
  configuring the build with --disable-cpp-tests. We removed the former
  --enable-cpp-tests configure flag. Unit tests now also work in (static and
  dynamic) Zeek plugins.

- This release expands the emerging cluster controller framework. Most changes
  concern internals of the framework. Agent/controller connectivity management
  has become more flexible: configuration updates pushed by the client can now
  convey the agent topology, removing the need to hardwire/redef settings
  in the controller. The new ClusterController::API::notify_agents_ready event
  declares the management infrastructure ready for use. zeek-client's CLI has
  expanded to support the new functionality.

  The framework is still experimental and provides only a small subset of
  ZeekControl's functionality. ZeekControl remains the recommended tool for
  maintaining your cluster.

- Entries in ``http.log`` now record the original ``HOST`` headers.
  Previously, they would skip any port specification a header might
  include.

Deprecated Functionality
------------------------

- The ``protocol_confirmation`` and ``protocol_violation`` events along with the
  corresponding ``Analyzer::ProtocolConfirmation` and
  ``Analyzer::ProtocolViolation`` C++ methods are marked as deprecated. They are
  replaced by ``analyzer_confirmation`` and ``analyzer_violation`` which can
  also now be implemented in packet analyzers.

- Declaring a local variable in an inner scope and then accessing it in an
  outer scope is now deprecated.  For example,

	if ( foo() )
		{
		local a = 5;
		...
		}
	print a;

  is deprecated.  You can address the issue by hoisting the declaration
  to the outer scope, such as:

	local a: count;
	if ( foo() )
		{
		a = 5;
		...
		}
	print a;

Zeek 4.1.0
==========

New Functionality
-----------------

- Lambda functions can now use capture-list to help specify exactly which local
  variables from outer scopes need to made available while evaluating the lambda
  and also the method by which they're made available: deep vs. shallow copy.

  For examples, see: https://docs.zeek.org/en/master/script-reference/types.html#type-function

- Support for VN-Tag protocol headers: the new VN-Tag packet analyzer simply
  skips past the VN-Tag header, allowing for further analysis of subsequent
  packet contents.

- Support for decapsulating Geneve packets to process the inner
  payload, similar in operation to the existing VXLAN support.

- Support for Zeek script "Reaching Definitions" (RD) analysis: tracking the
  extent to which a given variable definition (assignment) can be visible
  elsewhere in the Zeek script.  The analysis works on local variables in
  function/event/hook bodies, but not across them.

  The code tracks two forms of RDs, "minimal" (what's guaranteed to reach a
  given point in a function body) and "maximal" (what possibly could reach).
  Upcoming script optimization will use the latter, but the former currently
  allows identification of places for which a value is used where it
  does not appear that it will necessarily be defined. Specifying the
  ``zeek -u`` option will generate warnings for instances where this holds for
  local variables. Specifying ``zeek -uu`` turns on additional (expensive)
  analysis to report instances where record fields might be used without
  having previously been set.

  The ``zeek -u`` option can also identify assigned-to variables that aren't
  subsequently used (i.e. "dead code") and issues a warning.  A new ``is_used``
  attribute can be used situationally to suppress such warnings.

  The base scripts have some places where the static analysis lacks sufficient
  power to tell that values are being used safely (guaranteed to have been
  identified). In order to enable users to employ ``zeek -u`` on their own
  scripts without being distracted by these instances, this change also
  includes a new attribute, ``&is_assigned``, which can be associated with a
  variable or a record field to inform Zeek's analysis that the script writer
  asserts the value will be set, suppressing the associated warnings.

- A Telemetry API was added to assist in gathering arbitrary runtime
  metrics and allows export to Prometheus. This is still
  work-in-progress, preliminary documentation for current, low-level
  API lives at https://github.com/zeek/zeek/wiki/Telemetry for now.

- Experimental support for translating Zeek scripts to equivalent C++.
  The generated C++ can then be compiled directly into the ``zeek`` binary,
  replacing use of the interpreter and producing better runtime performance.
  See ``src/script_opt/CPP/README.md`` for a guide on how to use this feature.

- Support for more generic session management. The NetSessions class has been
  renamed to SessionMgr (with the old name marked deprecated). The new
  class allows plugins to take advantage of session management similar to how
  Connection objects were handled previously, but without the need to be based
  on IP-based protocols.

- The logging framework now provides a global policy hook, ``Log::log_stream_policy``.
  Like the existing filter-level hooks, handlers for the new hook can provide
  additional processing and veto the log write. The new hook runs once per
  write, prior to any filter-level policy hooks. Even when it vetoes,
  filter-level policy hooks still run, but cannot "un-veto" the write.

- The ASCII writer gained a new option LogAscii::logdir, which can be used to
  change the logging output directory.

- Added a ``--include-plugins`` argument to ``configure``. This argument
  takes a semicolon separated list of paths containing plugins that will be
  statically built into Zeek.

- Added a ``--plugindir`` argument to ``configure`` to set the
  installation path for plugins.

- The X509 analyzer now can check if a specific hostname is valid for a
  certificate. Two new BIFs were added for this, ``x509_check_hostname`` and
  ``x509_check_cert_hostname``. A new field ``sni_matches_cert`` that tracks
  this information was added to ``ssl.log``.

- Added new functions to dynamically enable/disable file analyzers:

  - ``global enable_analyzer: function(tag: Files::Tag): bool;``
  - ``global disable_analyzer: function(tag: Files::Tag): bool;``
  - ``global analyzer_enabled: function(tag: Files::Tag): bool;``

- Zeek now includes its own BTest tooling in the distribution, enabling other
  tests (e.g. in Zeek packages) to use it. The ``$PREFIX/share/btest folder``,
  reported via ``zeek-config --btest_tools_dir``, includes:

  - ``scripts/`` for ``btest-diff`` canonifiers
  - ``data/`` for data files, including ``random.seed``
  - ``data/pcaps`` for the test pcaps

  Configuring with ``--disable-btest-pcaps`` suppresses installation of the
  test pcaps.

- The Supervisor now defaults to starting with a minimal set of Zeek
  scripts controlled by a new init file, ``base/init-supervisor.zeek``.
  One may still run it with a larger configuration by loading additional
  scripts, including ``init-default.zeek``, as always. (Bare mode continues
  to work as usual, reducing the configuration to a minimum.)

  The ``NodeConfig`` record has two new members, providing additional
  control over launched nodes.  The ``env`` member allows setting environment
  variables in the launched process.  The ``bare_mode`` member, an optional
  boolean, provides control over the bare-mode state of the new node.
  When not provided, the node inherits the bare-mode status of the
  Supervisor, and setting the variable enables/disables bare mode.

- Zeek now includes an incomplete, preliminary version of the future
  cluster controller framework.  Loading ``policy/frameworks/cluster/agent``
  and/or ``policy/frameworks/cluster/agent`` in a Zeek running with the
  Supervisor will launch the corresponding cluster management node(s).
  An experimental management client, `zeek-client`, connects to the
  controller and lets you issue commands. It requires configuration with
  ``--enable-zeek-client``.  This does not yet provide a functional
  substitute for ``zeekctl``, which users should continue to use for now.

Changed Functionality
---------------------

- The default IP-based transport protocols (UDP, TCP, and ICMP) have been
  moved to the packet analysis framework. This change allows us to move other
  analyzers in the future that better align with the packet analysis framework
  than they do with session analysis.

- The input framework's handling of unset fields (commonly expressed as "-")
  in ingested data is now safer and more consistent. When reading data into
  records, Zeek now accepts unset fields in the input data only when the
  corresponding record field is ``&optional``. Unset fields for non-optional
  fields cause the input line to be skipped. Reading data into tables with complex
  index types (such as ``table[count, count] of string``) now also skips lines
  with unset fields, since such indexes require fields to be present.

  Note that this may change the behavior of existing scripts if you have unset
  fields in your input data.

- The version field in ssh.log is now optional and will not be set if we cannot
  determine the version that was negotiated by the client and server.

- Add a new field ``email_dest`` to NOTICEs, which defines where to
  send email to. The email-related NOTICE actions fill this now, and
  then emails will be sent to all recorded addresses at the end of
  NOTICE processing. This makes email generation more consistent and
  extensible.

- Add page and email administrator to mails processed by hostnames extension.

- SSL and X509 handling was significantly overhauled with the goal to make
  the data that is logged by Zeek more helpful and compact.

  This change means that there are significant changes to the default log files,
  as well as changes to functionality:

  - ``x509.log`` is now indexed by the sha256 of the certificate, with deduplication
    being automatically performed. By default, the same certificate is only logged
    once per day.

    This also means that the file ID is no longer present in X509 log. Similarly,
    ``ssl.log`` now contains hashes for X509 certificates.

    The hash function that is used for indexing the certificates is changeable by
    changing the ``X509::hash_function`` option.

    The time period after which a certificate is logged again can be configured by
    changing ``X509::relog_known_certificates_after``.

    By default deduplication of certificates is done across the entire cluster using
    broker. If this is not desired due to the higher communication overhead, this
    behavior can be disabled using ``X509::known_log_certs_use_broker``.

  - X509 certificates are, by default, no longer logged into files.log. This
    behavior is configurable and the previous default can be restored by changing
    the ``X509::log_x509_in_files_log`` option.

  - ``x509.log`` now tracks if a certificate was encountered as a end-host certificate
    or as a client certificate.

  - OCSP logging is now enabled by default.

  - ``ssl.log`` now no longer includes information about the certificate issuer and
    subject. This information is still available in X509.log. If you need this
    information in ``ssl.log``, the old behavior can be restored by changing the
    ``SSL::log_include_server_certificate_subject_issuer`` and
    ``SSL::log_include_client_certificate_subject_issuer`` configuration options.

  - ``ssl.log`` now contains a ``ssl_history`` field, which tracks which protocol
    messages were seen in an SSL/TLS connection.

  - We added a policy script ``ssl-log-ext.zeek`` which greatly extends the amount
    of protocol information logged to SSL.log. The script is not loaded by default.

  - We added a ``disable-certificate-events-known-certs.zeek`` policy script. This script
    will completely disable X509 events for known certificates over SSL/TLS connections.

    For Zeek installations in settings where you encounter a lot of certificates,
    this could improve the performance of your installation. Before enabling this
    script, make sure that you do not use any third-party scripts that depend on the
    X509 events. The script is not loaded by default.

  - The ICSI SSL Notary script was deprecated. This functionality is superseded by newer
    approaches, like SCT validation (which is supported by Zeek).

  - ``extract-certs-pem.zeek`` was deprecated - it never really worked in cluster modes.
    A new policy script, ``log-certs-base64.zeek`` that can be used to log raw certificates
    was added instead.

- The CT logs listed in ``ct-list.zeek`` are now derived from the list of CT
  logs that are accepted by Google Chrome. In the past, we allowed the list
  of all known CT logs. This no longer makes sense since nowadays logs exist that
  contain, e.g., only outdated or invalid certificates. If the old behavior is
  desired, you can re-add Logs to ``SSL::ct_logs``.

- The Mozilla CA list was updated to the state of NSS 3.67.

- SQLite was updated to 3.36.0.

- The list of subnets that are considered private addresses was updated to mostly
  match IANA's list unroutable addresses. This brings it in line with Chrome, the
  W3C spec, and Python's ipaddress module.

Removed Functionality
---------------------

- Support for the RocksDB Broker data store was previously broken and unusable,
  so all code/options related to it are now removed.

- Support for the ``ENABLE_MOBILE_IPV6`` compiler variable has been removed. Mobile
  IPv6 is now enabled by default. The ``--enable-mobile-ipv6`` option for
  ``configure`` now returns a warning that it will be removed in v5.1 and no
  longer has any effect.

- The logging framework's filter records no longer provide predicate
  functions. Policy hooks, introduced in Zeek 4, replace them:
  https://docs.zeek.org/en/master/frameworks/logging.html#filtering-log-records

Deprecated Functionality
------------------------

- Lambda/closure support: automatic capturing of references to variables
  outside a lambda's scope is now deprecated.  An explicit capture
  list which also specifies the desired copy-semantics is now required when
  writing lambda functions that refer to local variables of an outer scope.

  For examples, see: https://docs.zeek.org/en/master/script-reference/types.html#type-function

- The ``IterCookie`` version of iteration over ``Dictionary`` and ``PDict``
  objects was marked as deprecated. It was replaced by standard-library
  compatible iterators. This enables the use of standard constructs such
  as ranged-for loops to iterate over those objects.

- The ``zeek::util::zeekenv()`` function is deprecated since use of all
  environment variables prefixed by ``BRO_`` is now removed and calling
  ``getenv()`` directly with ``ZEEK_`` environment variables can be done.

- ``supervisor_rotation_format_func`` is renamed to ``archiver_rotation_format_func``

- The ``MemoryAllocation()`` function implemented by a number of interfaces
  is now deprecated. In testing we found that the values returned were mostly
  incorrect and weren't useful. The ``val_size`` and ``global_sizes`` BIF
  methods have also both been marked deprecated.

Zeek 4.0.0
==========

New Functionality
-----------------

- Added support for EDNS0 Cookie and Keep-Alive options.

- Added new Packet Analysis plugin architecture for parsing packet headers
  at layers below the existing Session analysis plugins. This allows
  writing plugins to parse the various parts of a packet header separately,
  chaining down into other plugins as needed.

- Add ``dce_rpc_request_stub`` and ``dce_rpc_response_stub`` events for
  accessing the contents of DCE-RPC request/response stub data.

- Add support for log filter policy hooks, which supersede the current
  log predicates. The hook signature is as follows:

        hook(rec: any, id: Log::ID, filter: Log::Filter);

  The logging manager invokes hooks on each log record. Hooks can veto
  log records via a break, and modify them if necessary. Log filters
  inherit the stream-level hook, but can override or remove the hook
  as needed. The distribution's existing log streams now come with
  pre-defined hooks that users can add handlers to. The existing
  predicates are deprecated for removal in 4.1 but continue to work.

  See https://docs.zeek.org/en/master/frameworks/logging.html#filter-log-records
  for more details.

- Added a ``udp-state`` signature condition to enforce matching against
  either "originator" or "responder" flow direction of UDP packets.

- Improvements to capture-loss.zeek:

  - A new option, ``CaptureLoss::initial_watch_interval``.  When restarting a
    Zeek cluster, one usually wants some immediate feedback as to the health of
    the monitoring via capture loss. However, you previously needed to wait a
    full ``CaptureLoss::watch_interval``, which defaults to 15 minutes.  The
    new option specifies the interval for the first-time report.  So the new
    default behavior provides stats after 1 minute and then after
    15 minutes afterward.

  - A new notice type, ``CaptureLoss::Too_Little_Traffic``.
    If a Zeek process sees less than ``CaptureLoss::minimum_acks`` ACKs in a
    given interval, this notice gets raised.  This can be a useful diagnostic
    if, for whatever reason, a Zeek process stops seeing traffic, but
    capture-loss.zeek would have previously only reported that "0 gaps and 0
    ACKs is 0% loss".

- A new ``zeek_script_args`` variable contains a list of arguments passed
  to a script.  E.g. either when explicitly executing Zeek like
  ``zeek -- myscript.zeek -arg1 -arg2``, or when using Zeek to interpret
  executable scripts that contain a hashbang line at the top like::

    #!/usr/local/zeek/bin/zeek --

- Added a new ``generate_all_events`` bif, which can be used to always raise
  events, even when they are not used by scripts. This can be used by the
  ``dump-events.zeek`` script to log all events that happen; the script
  got a new option to enable this behavior.

- Added new unknown_protocols.log that will log analyzer and protocol pairs
  via the packet analysis framework for packet protocols that aren't
  supported by Zeek. It can be enabled by loading the
  ``policy/misc/unknown-protocols`` script. The script adds a new
  ``unknown_protocol`` event.

- Added support for DNS resource records LOC, SSHFP, NSEC3PARAM, and custom
  BIND9 signaling. The associated events are:

  - dns_LOC
  - dns_SSHFP
  - dns_NSEC3PARAM
  - dns_BINDS

- Zeek now supports SSH clients/servers that advertise SSH version 1.99, which
  is a special version indicating that the server/client supports both SSH2 and
	SSH1.

- Added ``count_to_double()`` and ``int_to_double()`` type-conversion BIFs.

- Added these string-processing BIFs:

  - count_substr
  - find_str
  - rfind_str
  - starts_with
  - ends_with
  - is_num
  - is_alpha
  - is_alnum
  - ljust
  - rjust
  - swap_case
  - to_title
  - zfill
  - remove_prefix
  - remove_suffix

- Added a new ``Weird::sampling_global_list`` option to configure global
  rate-limiting of certain weirds instead of per connection/flow.

- Added a ``Pcap::findalldevs()`` for obtaining available network devices.

- Added ``enum_names()`` BIF to return names of an enum type's values

- Added ``type_aliases`` BIF for introspecting type-names of types/values

- Added composite-index support for ``&backend`` (Broker-backed tables).
  An example of a set with composite index is ``set[string, count, count]``.

- Sumstats now allows manual epochs. If an ``epoch`` interval of 0 is specified,
  epochs will have to be manually ended by calling ``SumStats::next_epoch``. This
  can be convenient because epochs can be synced to other events.

- The Zeek distribution now includes Zeek's package manager, zkg. Its
  code, configuration, and state reside in Zeek's installation tree,
  as follows:

  - The toplevel script, ``zkg``, installs alongside ``zeek`` in the
    distribution's ``$prefix/bin`` folder.

  - The config file installs into ``$prefix/etc/zkg/config``. The
    distribution's zkg command uses it by default, but you can switch
    to a different one via the ``ZKG_CONFIG_FILE`` environment
    variable or the ``--configfile`` command-line flag.

  - zkg's package state resides in ``$prefix/var/lib/zkg``. This
    implies that parallel Zeek installations now automatically
    separate their package installations.

  These folders have the same ownership and access permissions as the
  rest of the installation, , meaning that in order to manage zkg
  packages you need to run zkg as a user with corresponding access.
  Apart from these location overrides, the bundled zkg installation
  behaves as usual.

  local.zeek now contains a (commented out) ``@load`` statement you
  can use to source zkg's package state automatically.

  zkg's own Python module resides in ``zeek/python/zeekpkg`, in the
  installation tree's library folder. See below for additional changes
  around the library folder.

  zkg has external Python module dependencies. The Zeek configuration
  does not verify whether these dependencies are met. A new warning
  message at zkg launch flags missing packages and how to install them
  (e.g. via pip).

  Configuring with ``--disable-zkg`` disables the zkg inclusion. You
  can continue to install and use zkg independently. You're also free
  to use the config file in ``$prefix/etc/zkg/config`` with other zkg
  installations.

  The zkg source tree resides in ``auxil/package-manager`` as an
  additional Git submodule.

- Added a new ``ssl_probable_encrypted_handshake_message`` event, which
  is raised for encrypted TLS 1.3 handshake messages.

Changed Functionality
---------------------

- ``NetControl::DROP`` had 3 conflicting definitions that could potentially
  be used incorrectly without any warnings or type-checking errors.
  Such enum redefinition conflicts are now caught and treated as errors,
  so the ``NetControl::DROP`` enums had to be renamed:

  - The use as enum of type ``Log::ID`` is renamed to ``NetControl::DROP_LOG``

  - The use as enum of type ``NetControl::CatchReleaseInfo`` is renamed to
    ``NetControl::DROP_REQUESTED``

  - The use as enum of type ``NetControl::RuleType`` is unchanged and still
    named ``NetControl::DROP``

- The extract_email_addrs_vec() BIF now returns all occurrences of emails,
  including duplicates, with preserved order of occurrence.  This seems like
  the original/documented intent of the function, but the previous
  implementation did not preserve ordering or duplicates.

- The Dictionary implementation is replaced (no API changes).  The new version
  uses clustered hashing, a variation of Robinhood / Open Addressing hashing.
  This implementation generally performs better and utilizes less memory
  than the previous one.  A detailed explanation of the implementation is here:
  https://jasonlue.github.io/algo/2019/08/20/clustered-hashing.html

- The ``p`` fields of ``Cluster::Node`` records now use a
  ``&default=0/unknown`` attribute with ``0/unknown`` meaning that the node is
  not pre-configured to listen for incoming connections from other cluster
  nodes.

- The ``|x|`` operator, where ``x`` is an expression with an integral result,
  no longer performs an implicit coercion of that result into a signed
  ``int`` type.  This was actually the behavior before Zeek 3.0 as well, but
  the attempt to prevent mistakes that easily result from integer literals in
  Zeek being unsigned like ``|5 - 9|`` causing an overflow/wraparound and
  yielding a very large number is not generally consistent since overflows
  are still generally able to happen in other ways and also in other contexts
  besides just the absolute-value operator.  So the preference was to revert
  to a behavior that favors consistency.  For reference, see
  https://github.com/zeek/zeek/pull/251#issuecomment-713956976

- The Zeek installation tree is now more consistent in using a ``lib64/``
  (rather than ``lib/``) subdirectory for platforms where that's the common
  convention.  If the old hardcoded ``lib/`` path exists while installing Zeek
  4.0 and the new subdirectory differs, the old ``lib/`` remains untouched.
  This clutters the installation but is safe: the new installation does not
  require the old location, and any files you might require still in the old
  tree (e.g. ZeekControl plugins) remain available.

  Due to Zeek 4's reorganization of the installation tree we recommend
  a clean-slate install when possible.

- Python modules installed with the Zeek distribution now reside in a
  common ``zeek/python`` directory below the library path (such as
  ``lib64/zeek/python``) and no longer assume ZeekControl. The
  ``zeek/python/zeekctl`` folder now contains only ZeekControl's own
  functionality, ``zeek/python/zeekpkg`` contains zkg's Python module, and
  Broker's Python bindings live in ``zeek/python/broker``. ``zeek-config
  --python_dir`` now reports this new ``zeek/python`` folder. Several
  new configure options allow you to customize the Python folder location,
  depending on your needs.

  As with the new libdir, no cleanup of the existing Python tree occurs.

- Continued renaming/namespacing of many classes into either ``zeek`` or
  ``zeek::detail`` namespaces as already explained in Zeek 3.2's release notes.
  Deprecation warnings should generally help notify plugin developers of these
  changes.

- Changed HTTP DPD signatures to trigger analyzer independent of peer state.

  This is to avoid missing large sessions where a single side exceeds
  the DPD buffer size. It comes with the trade-off that now the analyzer
  can be triggered by anybody controlling one of the endpoints (instead
  of both).  For discussion, see https://github.com/zeek/zeek/issues/343.

- TLS 1.3 support was improved in several ways:

  * In the past, some TLS 1.3 sessions were misidentified as using session
    resumption when, in fact, they were not resumed. This was caused by
    the TLS session ID which no longer has any meaning in TLS 1.3. This was
    fixed.

  * Similarly, in the past, TLS 1.3 sessions that use TLS 1.3 PSKs for
    session resumption were not marked as resumed. This also was fixed.

  * The way in which session establishment for TLS 1.3 is performed was
    rewritten. This causes the ``ssl_encrypted_data`` event to be correctly
    raised; in the past this did not work for some sessions. A new
    ``ssl_probable_encrypted_handshake_message`` event was added that is
    raised for encrypted TLS 1.3 handshake packets.

  * In the same vein, hello retry requests in TLS 1.3 should now always
    be handled correctly; in the past this only happened in some cases.

    Please note: When a connection uses Hello Retry requests you will see
    two client hello and two server hello events in a single connection.

    This happened in the past, but may become more common now; this might
    trigger unexpected behavior in your scripts.

Removed Functionality
---------------------

- The counter type was removed. This type was never fully functional/used
  anywhere.

- Removed the PRI_PTR_COMPAT_INT, PRI_PTR_COMPAT_UINT, and PRI_SOURCE_ID
  macros. There are no deprecation warnings for these because they were C
  macros. Use the PRIdPTR and PRIuPTR macros from the standard library
  instead.

- The  ``successful_connection_remove`` and ``connection_successful`` events
  as well as ``connection$successful`` field that were added in Zeek v3.1.0 are
  now removed.  They were found to be unintuitive along with having unresolved
  corner cases.  The original goal/intent to avoid the overhead and scalability
  issues with every new protocol-analysis adding a new
  ``connection_state_remove`` handler can now be resolved with a less-confusing
  approach: see the ``Conn::register_removal_hook`` function.

- Python 2 is no longer supported.  Python 3.5 is the new minimum requirement.

- CMake versions less than 3.5 are no longer supported.

- CAF version 0.18 is now required and, by default, that is bundled with
  the Zeek distribution and will get built unless overridden with the
  ``--with-caf=`` configuration option.

- ``server_appdata`` and ``client_appdata`` were removed from ``SSL::Info``.
  These variables were only used internally, and did not give a correct counts
  in all circumstances.

Deprecated Functionality
------------------------

- Marked the Continuation.h and PacketDumper.h files as deprecated. The code
  contained within them is unused by Zeek.

- ``Type::GetAliases()`` and ``Type::AddAlias()`` are deprecated, use
  ``Type::Aliases()`` and ``Type::RegisterAlias()``.

- The ``ssh1_server_host_key`` event's modulus and exponent parameters,
  *e* and *p*, were named in misleading way (*e* is the modulus)
  and now deprecated in favor of the new *modulus* and *exponent* parameters.

- The logging framework's log filter predicates are now deprecated. Please
  use the new policy hooks instead.

Zeek 3.2.0
==========

New Functionality
-----------------

- X509 Certificate caching:

  Zeek now caches certificates if they have (by default) been encountered
  more than 10 times in 62 seconds. Information for cached certificates is
  retained; if the certificate is encountered again it does not have to
  be re-parsed and already existing information is used to raise the events.

  This should especially help with performance in environments where the
  same certificates are seen very often.

  Certificate caching is very configurable; it is possible to disable the
  feature, change the time intervals or even suppress X509 events.
  For details see ``scripts/base/files/x509/main.zeek``.

- Add parsing support for Remote Desktop Protocol UDP Transport Extension
  (RDPEUDP versions 1 and 2).  This primarily only adds "rdpeudp" to
  connection record service fields when an RDPEUDP session handshake is
  detected, but also provides a few other events related to the RDPEUDP
  connection establishment.

- Add the ``udp_content_ports`` configuration option. Any port added to
  this set will cause the ``udp_contents`` event to be raised.

- Add the ``udp_content_delivery_ports_use_resp`` option which can be used
  to specify how the destination port for the ``udp_content_delivery_ports_orig``
  and ``udp_content_delivery_ports_orig`` options is determined. The current value
  keeps behavior as it was in previous versions of Zeek.

- Add a file signature to identify ISO9660 disk images (application/x-iso9660-image)

- Add file signature to identify Python bytecode (application/x-python-bytecode)

- Events and hooks are now allowed to have multiple, alternate prototype
  declarations.  This allows for extending event/hook parameters in a way that
  won't break an existing user's handlers and also allows users to define their
  own custom event/hook prototypes that consume a subset of the parameters
  (convenience of typing/memory/etc).  This feature is documented in detail
  here: https://docs.zeek.org/en/current/script-reference/types.html#type-event

- Add ``flags`` parameters to ``rdp_connect_request``,
  ``rdp_negotiation_response``, and ``rdp_negotiation_failure`` events.

- ``Reporter::conn_weird`` now correctly handles weirds for expired connections,
  for which no connection state information is available in the core anymore. These
  cases will raise the new ``expired_conn_weird`` event.

- Broker Store table synchronization (experimental).

  Zeek now supports synchronizing tables/sets across clusters using a backing Broker
  store. The same feature also allows persistent storage of data in tables/sets
  over Zeek restarts. This feature is implemented using the new ``&backend`` attribute.

  To synchronize a table over a cluster, you can, e.g., use:

    global t: table[string] of count &backend=Broker::MEMORY;

  This feature is documented in detail here:

    https://docs.zeek.org/en/current/frameworks/broker.html#broker-store-backed-zeek-tables-for-data-synchronization-and-persistence

  Note: this feature is experimental and the syntax/specifics can change in the future.

Changed Functionality
---------------------

- Several C++ functions have been changed to pass smart pointers
  (``class IntrusivePtr<>``) instead of raw pointers.  This makes the
  code more robust.  External plugins may need to be updated to this
  API change.

- BIFs that use @ARG@, @ARGS@, or @ARGC@ may break since their type has
  changed: BIF arguments are now passed as a ``std::vector<IntrusivePtr<Val>>``
  rather than a ``val_list`` (i.e. ``List<Val*>``).

- RocksDB support for Broker data stores is now opt-in instead of automatically
  detected and used at configuration-time.  Use the ``--enable-rocksdb`` and
  ``--with-rocksdb=`` flags to opt-in.

- At the C++ level, a large number of functions had their return
  values and/or arguments changed to use ``bool`` types instead of
  ``int``. This includes some virtual methods, which may cause build
  failures in plugins that were overriding those methods. Those
  plugins will need to be updated to match these API changes. To make
  sure to catch changes you need to make to your plugin, double-check
  that all virtual method implementations use "override".

- Many C++ classes were marked "final" which also has some performance benefits
  due to devirtualization optimizations.

- Data members of many C++ classes/structs were reordered to achieve better
  packing and smaller memory footprint.

- "using namespace std" was removed from the Zeek header files; Zeek now always
  explicitly specifies std when using STL functionality in headers. This may
  necessitate small changes in external plugins, if they relied on the using
  statement in Zeek headers.

- The ``connection_external`` event was removed. This functionality that could
  raise this event (injecting connections via broccoli) was removed a while ago;
  the event handler served no purpose anymore.

- Reorganize the file signatures to break them out into more groups.  This may
  break scripts that had been explicitly loading any signature files that moved.

- The DCE/RPC operation string of "NetrLogonSamLogonWithFlags" has been
  corrected from "NetrLogonSameLogonWithFlags".

- ``AsRecord()`` and ``AsNonConstRecord()`` have changed to return
  ``std::vector<IntrusivePtr<Val>>*``.

- ``AsVector()`` has changed to return ``std::vector<IntrusivePtr<Val>>*``.

- Moved a large number of classes from the global namespace into either the
  ``zeek`` or ``zeek::detail`` namespace. See https://github.com/zeek/zeek/issues/266
  for the rationale behind these changes. Most types that were moved and functions
  that used them have been marked as deprecated and will generate compiler
  warnings if used (a few exceptions will not generate compiler warnings,
  but the Deprecated Functionality section below will mention those
  ones specifically).

  This includes a number of renames to classes, removing 'Bro' from their
  names. Deprecation warnings should notify plugin developers of these
  name changes.

Removed Functionality
---------------------

- The fmt() function which takes a va_list argument is replaced, use
  the new vfmt() function for equivalent functionality.  The former is
  deprecated because overloading it with the variadic fmt() function
  can cause the unintended overload to be chosen depending on how the
  platform implements va_list.

Deprecated Functionality
------------------------

- The ``plugin::Plugin::HookCallFunction()`` method is deprecated.  Note
  that compilers will not emit a deprecation warning, but the replacement
  method to now use is called ``HookFunctionCall`` and uses ``IntrusivePtr``
  arguments and return value.

- The ``Func::Call(val_list*, ...)`` method is now deprecated.  Use ``Invoke()``
  instead which takes a ``zeek::Args`` (``std::vector<IntrusivePtr<Val>>``).
  There's also a variadic template for ``Invoke()`` that forwards all arguments
  into a ``zeek::Args`` for you.

- The ``EventMgr::QueueEvent()`` and EventMgr::QueueEventFast()`` methods
  are now deprecated, use ``EventMgr::Enqueue()`` instead.

- The ``Connection::ConnectionEvent()``, ``Connection::Event()``, and
  ``Connection::ConnectionEventFast()`` methods are now deprecated, use
  ``Connection::EnqueueEvent()`` instead.

- The ``file_analysis::File::FileEvent()`` methods taking ``val_list``
  arguments are now deprecated, use the overload that takes a ``zeek::Args``
  instead.

- The ``analyzer::Analyzer::ConnectionEvent()``, ``analyzer::Analyzer::Event``,
  and ``analyzer::Analyzer::ConnectionEventFast()`` methods are deprecated, use
  ``analyzer::Analyzer::EnqueueConnEvent()`` instead.

- All ``val_mgr`` methods starting with "Get" are deprecated, use the new
  ``val_mgr`` methods that return ``IntrusivePtr``.

- ``Connection::BuildConnVal()`` is deprecated, use ``Connection::ConnVal()``.

- ``Analyzer::BuildConnVal()`` is deprecated, use ``Analyzer::ConnVal()``.

- ``BifEvent::generate_`` functions are deprecated, use ``zeek::BifEvent::enqueue_``.

- ``binpac::bytestring_to_val()`` is deprecated, use ``binpac::to_stringval()``.

- ``binpac::string_to_val()`` is deprecated, use ``StringVal`` constructor.

- Returning ``Val*`` from BIFs is deprecated, return ``IntrusivePtr`` instead.

- Various methods of converting protocol structures, like IP or packet headers,
  to associated ``Val`` type are now deprecated, the deprecation warning
  message will advise what new method to use instead.

- Various methods of ``Tag`` classes are deprecated with the warning
  message advising what new method to use instead.

- The ``utf16_bytestring_to_utf8_val()`` function is deprecated, use
  ``utf16_to_utf8_val()`` instead.

- ``RecordType::FieldType()`` is deprecated, use ``RecordType::GetFieldType()``

- ``BroType::HasField()`` and ``BroType::FieldType()`` are deprecated, use
  the methods of ``RecordType`` directly.

- ``BroType::YieldType()`` is deprecated, use ``BroType::Yield()``.

- ``ID::AsType()`` is deprecated, use ``ID::IsType()`` and ``ID::GetType()``.

- ``ID::Type()`` is deprecated, use ``ID::GetType()``.

- ``ID::ID_Val()`` is deprecated, use ``ID::GetVal()``.

- ``internal_type()`` is deprecated, use ``zeek::id::find_type()``.

- ``internal_val()`` and ``internal_const_val()`` are deprecated, use
  ``zeek::id::find_val()`` or ``zeek::id::find_const()``.

- ``internal_func()`` is deprecated, use ``zeek::id::find_func()``.

- ``opt_internal_val()`` is deprecated, use ``lookup_ID()`` or
  ``zeek::id::find_val()``.

- ``Val::Type()`` is deprecated, use ``Val::GetType``.

- Most global type/value pointers in NetVar.h are deprecated, but one can
  still always perform the lookup themselves.

- ``Scope::Lookup()`` is deprecated, use ``Scope::Find()``.

- All generated ``BroType*`` names in the ``BifType::`` namespaces are
  deprecated, but there's an equivalent name in ``zeek::BifType::`` of
  ``IntrusivePtr`` type to use instead.

- All generated ``BifConst::`` names are deprecated, but there's an
  equivalent name now in ``zeek::BifCont::``, and changed to ``IntrusivePtr``
  if the old name was some ``Val*`` type.

- Constructors for ``Val`` types that take a ``BroType*`` are all generally
  deprecated, with alternatives that instead take an ``IntrusivePtr`` argument.

- ``FuncType::Args()`` is deprecated, use ``FuncType::Params()``.

- ``FuncType::ArgTypes()`` is deprecated, use ``FuncType::ParamList()``.

- ``RecordVal::Assign(int, Val*)`` is deprecated, use the overload taking
  ``IntrusivePtr``.

- ``RecordVal::Lookup(int)`` is deprecated, use ``RecordVal::GetField(int)``.

- ``RecordVal::LookupWithDefault(int)`` is deprecated, use
  ``RecordVal::GetFieldOrDefault(int)``.

- ``RecordVal::Lookup(const char*, bool)`` is deprecated, use either
  ``RecordVal::GetField()`` or ``RecordVal::GetFieldOrDefault()``.

- ``TableVal::Assign`` methods taking raw ``Val*`` are deprecated, use the
  overloads taking ``IntrusivePtr``.

- ``TableVal::Lookup()`` is deprecated, use ``TableVal::Find()`` or
  ``TableVal::FindOrDefault()``.

- ``VectorVal::Assign`` and ``Insert`` methods taking raw ``Val*`` are
  deprecated, use the methods that take ``IntrusivePtr``.

- ``VectorVal::Lookup()`` is deprecated, use ``VectorVal::At()``.

- The file analysis/analyzer API has deprecated methods taking raw
  ``RecordVal*`` for analyzer arguments and replaced those with methods
  taking ``IntrusivePtr``.

- The ``Val(double, TypeTag)`` constructor is deprecated, use either
  ``IntervalVal()``, ``TimeVal()`` or ``DoubleVal()`` constructors.

- The "BroString.h" file is deprecated, use "ZeekString.h"

- The str_split() BIF is deprecated, use str_split_indices().  Note
  that the former returns a vector with indices starting at 1 while the
  later returns a vector with indices starting at 0.

- The ``icmp_conn`` parameter of ICMP events is deprecated, there's an
  alternate version with an ``icmp_info`` parameter to use instead.
  The ``icmp_conn`` record passed to ICMP events has always been re-used
  amongst all events within an ICMP "connection", so the
  ``itype``, ``icode``, ``len``, and ``hlim`` fields as inspected in
  handlers never appears to change even if the underlying packet data
  has different values for those fields.  However, it's not known if
  anyone relied on that behavior, so the new ``icmp_info`` record is
  introduced with the more-expected behavior of being created and
  populated for each new event.  It also removes the orig_h/resp_h
  fields since those are redundant with what's already available in
  the connection parameter.

- External plugins should include Zeek header files like
  ``#include <zeek/Foo.h>`` instead of ``#include <Foo.h>``.  The later
  style is considered deprecated.  Reliance on ``zeek-config --include_dir``
  to contain ``$prefix/include/zeek`` is also deprecated: its replacement
  output is expected to be just ``$prefix/include``, with it currently
  outputting both paths, delimited by a colon, during the deprecation period.

Zeek 3.1.0
==========

New Functionality
-----------------

- Add a new supervisor framework that enables Zeek to operate clusters
  of processes itself without any external help.

  The Supervisor framework provides an entirely new deployment mode
  for Zeek, one that supervises a set of Zeek processes that are meant
  to be persistent. A Supervisor automatically revives any process
  that dies or exits prematurely and also arranges for an ordered
  shutdown of the entire process tree upon its own termination. This
  Supervisor mode for Zeek provides the basic foundation for process
  configuration/management that could be used to deploy a Zeek cluster
  similar to what ZeekControl does, but is also simpler to integrate
  as a standard system service.

  This mode is still experimental and will evolve over time. The
  command-line argument of ``-j`` toggles Zeek to run in "Supervisor
  mode" to allow for creation and management of child processes. If
  you're going to test this, please note that you will need some
  custom script code to configure the processes you want Zeek to run.
  See the documentation for more information:
  https://docs.zeek.org/en/stable/frameworks/supervisor.html

- Add a new option, ``dpd_late_match_stop``, which can be used in conjunction
  with the option ``dpd_match_only_beginning`` and the new event
  ``protocol_late_match`` to help annotate the conn.log with a field
  to speculate on the protocol/service in cases where the DPD buffer
  was already exhausted and can't analyze the full connection anymore,
  but where there was still a late signature match.  A new script,
  ``policy/protocols/conn/speculative-service.zeek``, was added as an
  example of how to perform this tuning and add a "speculative_service"
  field to conn.log, but it's not loaded by default.

- There is now a new ``tcp_options`` event that is raised for each TCP header
  that contains options.

- Added a new option, ``Log::print_to_log`` that can be set to automatically
  redirect the output from "print" statements to a real log stream (e.g.
  instead of writing to stdout).

- There is now a new ``&on_change`` attribute that can be used to be notified
  of changes to tables and sets.

Changed Functionality
---------------------

- A C++17-capable compiler and CMake 3.0+ are now required to compile Zeek

- The backwards-compatibility wrappers & workarounds introduced in 3.0
  for the "Bro to Zeek rename" have either changed their operation, or in some
  cases been removed. Generally, anything that reported a
  naming-related warning in 3.0 now aborts with a corresponding error
  message. In cases where 3.0 silently continued to accept old names,
  3.1 now reports warnings. Most importantly, that's loading of
  scripts with ".bro" endings, which are now flagged and should be
  renamed.

- Broker has switched versions for the underlying CAF communication
  library from 0.16 to 0.17. CAF has changed its wireformat between
  those versions, which means that previous Broker and Zeek versions
  won't be able to connect to the new ones. In other words, all Zeek
  instances, as well as other Broker clients, need to upgrade at the
  same time. In case of version mismatches, Broker now reports better
  error messages to point out the problem.

- The key type of ``Known::service_store`` has changed to
  ``Known::AddrPortServTriplet`` and ``Known::services`` is now a table
  instead of just a set.

- The DNS class name for Hesiod in the ``DNS::classes`` table is now spelled
  correctly as "C_HESIOD" instead of "C_HESOD".  For reference, this
  class name string may appear in the dns.log file or in any custom
  script logic that inspects the ``qclass`` field of ``DNS::Info``
  after a ``dns_request`` event.

- The configuration input reader now ignores trailing spaces at the end of
  configuration lines.

- The tcp_option event is now correctly raised.

- The base scripts shipped with Zeek now use the new
  ``successful_connection_remove`` event instead of
  ``connection_state_remove`` where possible (when the logic doesn't
  pertain to unestablished TCP connections). There's a performance
  benefit to this switch, but it may potentially break custom scripts
  that depended on accessing or modifying state via specific
  ``&priority`` ordering of ``connection_state_remove`` event
  handlers. However, since most of Zeek's base scripts previously just
  used that event with the intention of writing a finalized log as the
  last thing executed for a given connection, and the new
  ``successful_connection_remove`` event handlers all run after
  ``connection_state_remove``, it's not likely this change to the base
  scripts causes any incompatibility with user scripts.

  There's also a new event called ``connection_successful`` and a new
  ``connection`` record field named "successful" to help indicate this
  new property of connections.

- The JSON output formatters now use the RapidJSON library. This
  improves their performance considerably over the library that was
  previously used. Output from the formatters remains nearly
  identical.

- The ``decompose_uri`` function no longer raises an error when parsing
  URIs with an empty port number (e.g. ``http://example.org:/``). Instead,
  the ``portnum`` component of the returned ``URI`` value is left
  uninitialized.

- Replace old ``select``-based IO loop with a new architecture that doesn't
  spin checking for active IO sources. The new architecture now waits for the
  the sources to actively notify it when activity occurs and only processes
  data once it's ready. This helps heavily reduce the CPU usage on idle
  network connections. This includes a couple of breaking changes:

  - Only a single packet source is allowed to be specified from the
    command-line now. If you pass combinations of multiple ``-r`` and/or
    ``-i`` flags, Zeek will return an error at startup.
  - The IOSource API changed fairly wildly. The ``GetFds()`` and
    ``NextTimestamp`` methods no longer exist. If you had previously
    implemented a custom IOSource, you will need to look at the new API
    and make changes to your code to accommodate it. This does not include
    packet sources, which should remain functional with little to no
    changes, since the entirety of the changes should be in ``PktSrc``.

- Remove a large number of headers from being included by various files across
  the entire code base, which leads to a sizeable build time improvement. This
  set of changes has the potential to cause plugins to not build anymore. The
  fixes for this potential breakage should just be a matter of including the
  necessary headers in the plugin code.

Removed Functionality
---------------------

- Removed the ``current_conns_extern`` field from the ConnStats record
  type. Zeek only maintains a single timer manager now, and without the
  manager tags that came with multiple timer managers, we don't track
  whether a connection is external anymore.

Deprecated Functionality
------------------------

- The C++ API typedefs for int{8,16,32,64} and uint{8,16,32,64} are deprecated
  in favor of the real <cstdint> types they alias.  E.g. use int8_t instead of
  int8.

- The C++ API functions "safe_snprintf" and "safe_vsnprintf" are deprecated.
  Use "snprintf" and "vsnprintf" instead.

Zeek 3.0.0
==========

New Functionality
-----------------

- Added support for DNSSEC resource records RRSIG, DNSKEY, DS, NSEC, and NSEC3.
  The associated events are:

  - dns_RRSIG
  - dns_DNSKEY
  - dns_DS
  - dns_NSEC
  - dns_NSEC3

- Added support for parsing and logging DNS SPF resource records.
  A new ``dns_SPF_reply`` event is also available.

- Zeek's Plugin framework now allows a patch version.  If a patch version is not
  provided, it will default to 0.  To specify this, modify the plugin
  Configuration class in your ``src/Plugin.cc`` and set
  ``config.version.patch``.  Note that the default plugin skeleton
  includes a unit test whose Baseline has the plugin version number in
  it and that will now fail due to the version number now including a
  patch number.  For those that want to keep the unit test, simply adapt
  the unit test/baseline to include the new plugin patch number.

- The default http.log not includes a field for the HTTP request Origin header.

- Support for decapsulating VXLAN tunnels.

- The for-loop syntax now allows for iterating over key-value pairs of tables.
  Previously, a separate lookup within the loop was required to obtain the
  value at a given index/key, but now this works::

      local t: table[count] of string = table();
      t[1] = "hello";
      t[55] = "goodbye";

      for ( key, value in t )
          print key, value;

- Added options for controlling the source path/prefix for Input and
  Intel framework files:

  - InputAscii::path_prefix
  - InputBinary::path_prefix
  - Intel::path_prefix

- Support for NFLOG link-layer type.

- Support for some SMB 3.x features

  - An ``smb2_transform_header`` event is raised after parsing
    TRANSFORM_HEADER structures associated with encrypted messages.

  - The ``SMB2::NegotiateResponse`` record now contains
    ``negotiate_context_count`` and ``negotiate_context_values`` fields
    containing capability information found in an SMB 3.1.1 dialect's
    negotiation message.

- Added a new hook, ``Intel::filter_item``, to assist in filtering and
  removal of intelligence items that are about to be inserted.

- Add support for SMB filenames in the intel framework.

- Added a new event for weirdness found via file analysis: ``file_weird``.

- The conn.log "history" field supports a new character 'G' or 'g'
  (capital for originator, lowercase responder) to indicate a content
  gap in the TCP stream.  These are recorded logarithmically.

- The ``ZEEK_DNS_RESOLVER`` environment variable now controls
  the DNS resolver to use by setting it to an IPv4 or IPv6 address.  If
  not set, then the first IPv4 address from /etc/resolv.conf gets used.

- The ``/<re>/i`` convenience syntax for case-insensitive patterns is now
  also allowed when specifying patterns used in signature files.

- New RDP functionality.

  - New events:
    - rdp_client_network_data
    - rdp_client_security_data
    - rdp_client_cluster_data
    - rdp_native_encrypted_data

  - Add a new "client_channels" field to rdp.log based on data parsed from
    the Client Network Data (TS_UD_CS_NET) packet.  The channel list is also
    available in the new ``rdp_client_network_data`` event.

- Add parsing support for TLS 1.3 pre-shared key extension.  This info
  is available in the events: ``ssl_extension_pre_shared_key_client_hello``
  and ``ssl_extension_pre_shared_key_server_hello``.

- Added/re-wrote support for NTP.

  - Parsing support for modes 1-7, with parsed structures available in
    the ``ntp_message`` event.

  - An ntp.log is produced by default, containing data extracted from
    NTP messages with modes 1-5.

- Add support for vector slicing operations.  For example::

    local v = vector(1, 2, 3, 4, 5);
    v[2:4] = vector(6, 7, 8);        # v is now [1, 2, 6, 7, 8, 5]
    print v[:4];                     # prints [1, 2, 6, 7]

- Add support for paraglob, a fairly quick data structure for matching a string
  against a large list of patterns. For example::

	local v1 = vector("*", "d?g", "*og", "d?", "d[!wl]g");
	local p1 = paraglob_init(v1);
	print paraglob_match(p1, "dog");

- An ``expire_func`` for a table with a multi-value-index will now unroll
  the index and take one argument for each index value. For example, for a
  ``table[string,string] of count`` the expire function signature is:

  function(t: table[string, string] of count, s: string, s2: string): interval

- Zeek's anonymous functions now capture their closures by reference.
  This means that they can use and modify variables from the scope
  that they were generated in. For example:

      local n = 3;
      local f = function() { n += 1; };
      f();
      print n; # prints 4

  These anonymous functions can also be serialized over Broker with
  their closures. In order to be serialized over Broker the receiving
  script needs to have an identical version of the function declared.
  For the above example, a receiving script would need to have
  declared a function

      local name = function() { n += 1; };

  to be able to receive the senders function over Broker.

  Functions with closures can still use the variables they have
  captured even after they have left the scope that they were declared
  in. For example, a simple generator function like the one below
  works as expected.

      local make_adder = function(n: count): function(m: count): count
          {
          return function (m: count): count
              {
              return n + m;
              };
          };

      print make_adder(3)(5); # prints 8

      local three = make_adder(3);
      print three(5); # prints 8

- Add ``LogAscii::enable_utf_8`` option to allow valid utf8 sequences
  to be written directly into the ASCII logs without any escaping.

- Add parsing, analysis, and logging support for MQTT protocol v3.1/v3.1.1.
  This is not enabled by default, use ``@load policy/protocols/mqtt`` to
  use the new MQTT analysis support.

- Zeek now supports duration thresholding on connections, similarly to how it supports
  byte and packet thresholds.

  - New events:
    - ConnThreshold::duration_threshold_crossed
    - conn_duration_threshold_crossed

  - New functions:
    - ConnThreshold::set_duration_threshold
    - ConnThreshold::delete_duration_threshold
    - set_current_conn_duration_threshold
    - get_current_conn_duration_threshold

Changed Functionality
---------------------

- The following executable names have changed (the old names will
  continue to work, but emit a deprecation warning):

  - ``bro`` is now ``zeek``

  - ``bro-config`` is now ``zeek-config``

  - ``broctl`` is now ``zeekctl``

  - ``bro-cut`` is now ``zeek-cut``

- BroControl has been completely renamed to ZeekControl.  Many installation
  directories and files with "broctl" in their name have been changed
  to use "zeekctl" instead.  It's expected this has been done in a way
  that's backwards compatible with previous Bro installations.  E.g.
  if you made customizations to the ``broctl.cfg`` file of a previous
  installation, installing the newer Zeek version over it will retain that
  file and even symlink the new ``zeekctl.cfg`` to it.

- The default install prefix is now ``/usr/local/zeek`` instead of
  ``/usr/local/bro``.  If you have an existing installation that used
  the previous default and are still using the new default when upgrading,
  we'll crate ``/usr/local/zeek`` as a symlink to ``/usr/local/bro``.
  Certain subdirectories will also get similar treatment: ``share/bro``,
  ``include/bro``, and ``lib/bro``.

- ``$prefix/share/bro/site/local.bro`` has been renamed to
  ``local.zeek``.  If you have a ``local.bro`` file from a previous
  installation, possibly with customizations made to it, the new
  version of Zeek will install a ``local.zeek`` file that is a symlink
  to the preexisting ``local.bro``.  In that case, you may want to
  just copy ``local.bro`` into the new ``local.zeek`` location to
  avoid confusion, but things are otherwise meant to work properly
  without intervention.

- All scripts ending in ``.bro`` that ship with the Zeek source tree have
  been renamed to ``.zeek``.

- The search logic for the ``@load`` script directive now prefers files
  ending in ``.zeek``, but will fallback to loading a ``.bro`` file if
  it exists.  E.g. ``@load foo`` will first check for a ``foo.zeek``
  file to load and then otherwise ``foo.bro``.  Note that
  ``@load foo.bro`` (with the explicit ``.bro`` file suffix) prefers
  in the opposite order: it first checks for ``foo.bro`` and then
  falls back to a ``foo.zeek``, if it exists.

- The for-loop index variable for vectors has been changed from
  'int' to 'count' type.  It's unlikely this would alter/break any
  script behavior unless they were explicitly inspecting the variable's
  type (and there's typically no reason to do that).

- The startup/initialization behavior has changed such that any errors
  encountered while processing the ``bro_init()`` event will cause the
  process to terminate rather than continue on the main run loop.

- The ``dns_state`` field within ``connection`` records has changed: the
  ``pending_queries`` and ``pending_replies`` fields are now ``&optional``,
  and there is a new field ``pending_query`` that is populated before
  ``pending_queries``.  If you have scripts that access the ``pending_queries``
  or ``pending_replies`` fields, they will need to be updated.
  This change was made to improve performance.

- The ternary operator ("<expr> ? <alt1> : <alt2>") now enforces that
  if "<alt1>" and "<alt2>" are both records, they are of the same
  type. It was always assumed that they were, but code might have
  still worked even if not.

- The "orig_fuids", "orig_filenames", "orig_mime_types" http.log fields
  as well as their "resp" counterparts are now limited to having
  "HTTP::max_files_orig" or "HTTP::max_files_resp" entries, which are 15
  by default.  The limit can also be ignored case-by-case via the
  "HTTP::max_files_policy" hook.

- The binpac library is now only compiled as a shared library by default.
  To revert back to compiling only a static library, there's the
  ``--enable-static-binpac`` configure option.

- The Broker C++ API has some breaking changes, see it's own NEWS file for
  details on how to migrate old code.

- Some Weirds associated with generic binpac parsing exceptions in analyzers
  that didn't otherwise handle them (like syslog, modbus, dnp3) are now
  a ProtocolViolation instead

- An "addl" parameter was added to the ``flow_weird`` and ``net_weird`` events
  for describing additional information about the weird.  The ``conn_weird``
  event already had such a parameter.

- Weird names that contained variable content and may result in an unbounded
  number of weird names have been renamed to remove the variable content
  (which has been made available in the "addl" field of ``conn_weird``,
   ``flow_weird``, or ``net_weird`` events):

    - "unknown_dce_rpc_auth_type_%d" -> unknown_dce_rpc_auth_type
    - "gtp_invalid_info_element_%d" -> gtp_invalid_info_element
    - "unknown_netbios_type:" 0x%x -> unknown_netbios_type
    - "excess_netbios_hdr_len" (%d > %d) -> excess_netbios_hdr_len
    - "deficit_netbios_hdr_len" (%d > %d) -> deficit_netbios_hdr_len
    - "bad_RPC_program (%d)" -> bad_RPC_program
    - "unknown_MOUNT_request(%u)" -> unknown_MOUNT_request
    - "unknown_NFS_request(%u)" -> unknown_NFS_request
    - "RPC resync: discard %d bytes\n" -> RPC_resync
    - "RPC_message_too_long (%d64)" -> RPC_message_too_long
    - "socks5_unsupported_authentication_method_%d" -> socks5_unsupported_authentication_method
    - "socks5_unsupported_authentication_%d_%d" -> socks5_unsupported_authentication
    - "ssh_unknown_kex_algorithm=%s" -> ssh_unknown_kex_algorithm
    - "Encountered unknown type in server name ssl extension: %d" -> ssl_ext_unknown_server_name_type
    - "UDP_datagram_length_mismatch(%d!=%d)" -> UDP_datagram_length_mismatch
    - "OPENSSL Could not parse OCSP request (fuid %s)" -> openssl_ocsp_request_parse_error
    - "OPENSSL Could not parse OCSP response (fuid %s)" -> openssl_ocsp_response_parse_error
    - "Could not parse X509 certificate (fuid %s)" -> x509_cert_parse_error
    - "Certificate with invalid BasicConstraint. fuid %s" -> x509_invalid_basic_constraint
    - "Could not parse subject alternative names. fuid %s" -> x509_san_parse_error
    - "DNS-field does not contain an IA5String. fuid %s" -> x509_san_non_string
    - "Weird IP address length %d in subject alternative name. fuid %s" -> x509_san_ip_length
    - "Could not parse time in X509 certificate (fuid %s) -- UTCTime has wrong length" -> x509_utc_length
    - "Could not parse UTC time in non-YY-format in X509 certificate (x509 %s)" -> x509_utc_format
    - "Could not parse time in X509 certificate (fuid %s) -- Generalized time has wrong length" -> x509_gen_time_length
    - "Invalid time type in X509 certificate (fuid %s)" -> x509_invalid_time_type
    - "Could not parse time in X509 certificate (fuid %s) -- additional char after time" -> x509_time_add_char
    - "Could not parse time in X509 certificate (fuid %s) -- not enough bytes remaining for offset" -> x509_time_offset_underflow
    - "Could not parse time in X509 certificate (fuid %s) -- unknown offset type" -> x509_time_offset_type
    - "X509::GetExtensionFromBIO: %s" -> x509_get_ext_from_bio
    - "unknown_mobility_type_%d" -> unknown_mobility_type
    - "unknown_routing_type_%d" -> unknown_routing_type
    - "unknown_protocol_%d" ->  unknown_protocol
    - "unknown_gre_version_%d" -> unknown_gre_version
    - "unknown_gre_protocol_%u16" -> unknown_gre_protocol

- The "missed_bytes" field of conn.log can be calculated slightly differently
  in some cases: ACKs that reveal a content gap, but also come at
  the end of a connection (in a FIN or RST) are considered unreliable
  and aren't counted as true gaps.

- The Broxygen component, which is used to generate our Doxygen-like
  scripting API documentation has been renamed to Zeekygen.  This likely has
  no breaking or visible changes for most users, except in the case one
  used it to generate their own documentation via the ``--broxygen`` flag,
  which is now named ``--zeekygen``.  Besides that, the various documentation
  in scripts has also been updated to replace Sphinx cross-referencing roles
  and directives like ":bro:see:" with ":zeek:see:".

- The catch-and-release and unified2 scripts are no longer loaded by
  default.  Because there was a performance impact simply from loading
  them and it's unlikely a majority of user make use of their features,
  they've been moved from the scripts/base/ directory into
  scripts/policy/ and must be manually loaded to use their
  functionality.  The "drop" action for the notice framework is likewise
  moved since it was implemented via catch-and-release.  As a result,
  the default notice.log no longer contains a "dropped" field.

  If you previously used the catch-and-release functionality add this:

      @load policy/frameworks/netcontrol/catch-and-release

  If you previously used Notice::ACTION_DROP add:

      @load policy/frameworks/notice/actions/drop

  If you previously used the Unified2 file analysis support add:

      @load policy/files/unified2

- The default value of ``peer_description`` has changed from "bro"
  to "zeek".  This won't effect most users, except for the fact that
  this value may appear in several log files, so any external plugins
  that have written unit tests that compare baselines of such log
  files may need to be updated.

- The "remote_ip" field of "addr" type was removed from radius.log and
  replaced with a field named "tunnel_client" of "string" type.  The
  reason for this is that the Tunnel-Client-Endpoint RADIUS attribute
  this data is derived from may also be a FQDN, not just an IP address.

- The ``ssl_server_hello`` event's ``server_random`` parameter has been
  changed to always include the full 32-byte field from the
  ServerHello.  Previously a 4-byte timestamp and 28-byte random data
  were parsed separately as some TLS protocol versions specified a
  separate timestamp field as part of the full 32-byte random sequence.

- The namespace used by all the builtin plugins that ship with Zeek have
  changed to use "Zeek::" instead of "Bro::".

- Any Broker topic names used in scripts shipped with Zeek that
  previously were prefixed with "bro/" are now prefixed with "zeek/"
  instead.

  In the case where external applications were using a "bro/" topic
  to send data into a Bro process, a Zeek process still subscribes
  to those topics in addition to the equivalently named "zeek/" topic.

  In the case where external applications were using a "bro/" topic
  to subscribe to remote messages or query data stores, there's no
  backwards compatibility and external applications must be changed
  to use the new "zeek/" topic.  The thought is this change will have
  low impact since most data published under "bro/" topic names is
  intended for use only as a detail of implementing cluster-enabled
  versions of various scripts.

  A list of the most relevant/common topic names that could potentially
  be used in external applications to consume/query remote data that
  one may need to change:

  - store names
    - bro/known/services
    - bro/known/hosts
    - bro/known/certs

  - cluster nodes
    - bro/cluster/<node type>
    - bro/cluster/node/<name>
    - bro/cluster/nodeid/<id>

  - logging
    - bro/logs/<stream>

- The ``resp_ref`` argument was removed from the ``ocsp_response_bytes``
  event. ``resp_ref`` was not used by anything in the codebase and could not be
  passed to any other functions for further processing. The remainder of the
  ``ocsp_response_bytes`` is unchanged.

- For performance reasons, processing of notices is now always
  performed by the node on which the notice is raised rather than
  the centralized Manager node.  This has potential incompatibilities
  for those that relied on global state for notice policy processing.
  It also introduces an expected race condition that may cause multiple
  notices of the same kind that are generated within a short timespan
  of each other on separate cluster nodes to all be logged rather
  than suppressed and de-duplicated into a single notice.


- to_json is now a bif, no longer a script. Loading base/utils/json.zeek is no
  longer necessary and has been deprecated. to_json should yield much better, always
  valid json. There are some small differences in output; unnecessary spaces are removed
  and port values are rendered differently, now including the port and the protocol.

- The output of the JSON logger now uses an external library to generate json. There
  are small changes to the output; most visibly double numbers are now rounded slightly
  differently. The way in which port values are rendered does _not_ change for JSON logs.

- The C++-layer List, Queue, and Dict types have changed from using macros to
  templates as well as some other API changes.

  - Range-based for-loops are now supported

  - The loop_over_queue macro is now removed

  - PList is now a template instead of a macro, so any "PList(T)" usages in
    external code should now use "PList<T>"

  - PDict is now a template instead of a macro, so any "PDict(T)" usages in
    external code should now use "PDict<T>"

  - Generally some methods used to assume containers were only using integer
    or pointer types, so semantics may now be slightly different to
    either avoid copying or unsafely returning arbitrary T types by value.
    E.g. List::remove_nth and List::get can no longer return a "null" value
    when the provided index is out of range, so they assert instead, and
    Queue::pop methods do not return a value at all (one must check for
    a non-empty container before removing an element).

- Google Perftools (tcmalloc) is no longer used by default on Linux
  systems if it's found during the configuration process.
  Use the --enable-perftools configuration flag to use tcmalloc.
  The --disable-perftools flag is also no longer provided since
  there's no longer any case in which tcmalloc will be used by default.

- There now is a maximum number of protocol violations that can be raised by an analyzer
  before it is disabled; the default is set to 5. This behavior is customizable using
  ``DPD::max_violations`` and ``DPD::ignore_violations``.

- The scan detection script, ``policy/misc/scan``, is no longer loaded by
  default in ``site/local.zeek`` due to it frequently causing performance issues.

Removed Functionality
---------------------

- A number of functions that were deprecated in version 2.6 or below and completely
  removed from this release. Most of the functions were used for the old communication
  code.

    - ``find_ip_addresses``
    - ``cat_string_array``
    - ``cat_string_array_n``
    - ``complete_handshake``
    - ``connect``
    - ``decode_base64_custom``
    - ``disconnect``
    - ``enable_communication``
    - ``encode_base64_custom``
    - ``get_event_peer``
    - ``get_local_event_peer``
    - ``join_string_array``
    - ``listen``
    - ``merge_pattern``
    - ``request_remote_events``
    - ``request_remote_logs``
    - ``request_remote_sync``
    - ``resume_state_updates``
    - ``send_capture_filter``
    - ``send_current_packet``
    - ``send_id``
    - ``send_ping``
    - ``set_accept_state``
    - ``set_compression_level``
    - ``sort_string_array``
    - ``split1``
    - ``split_all``
    - ``split``
    - ``suspend_state_updates``
    - ``terminate_communication``
    - ``split``
    - ``send_state``
    - ``checkpoint_state``
    - ``rescan_state``
    - ``log_file_name``
    - ``open_log_file``
    - ``disable_print_hook``

- The following events were deprecated in version 2.6 or below and are completely
  removed from this release:

    - ``ssl_server_curve``
    - ``dhcp_ack``
    - ``dhcp_decline``
    - ``dhcp_discover``
    - ``dhcp_inform``
    - ``dhcp_nak``
    - ``dhcp_offer``
    - ``dhcp_release``
    - ``dhcp_request``
    - ``remote_state_access_performed``
    - ``remote_state_inconsistency``
    - ``remote_connection_established``
    - ``remote_connection_closed``
    - ``remote_connection_handshake_done``
    - ``remote_event_registered``
    - ``remote_connection_error``
    - ``remote_capture_filter``
    - ``remote_log_peer``
    - ``remote_log``
    - ``finished_send_state``
    - ``remote_pong``
    - ``software_version_found``
    - ``software_unparsed_version_found``
    - ``software_parse_error``
    - ``print_hook``
    - ``interconn_stats``
    - ``interconn_remove_conn``
    - ``root_backdoor_signature_found``
    - ``napster_signature_found``
    - ``kazaa_signature_found``
    - ``gaobot_signature_found``
    - ``ftp_signature_found``
    - ``gnutella_signature_found``
    - ``http_signature_found``
    - ``irc_signature_found``
    - ``telnet_signature_found``
    - ``ssh_signature_found``
    - ``rlogin_signature_found``
    - ``smtp_signature_found``
    - ``http_proxy_signature_found``
    - ``backdoor_stats``
    - ``backdoor_remove_conn``
    - ``dns_full_request``
    - ``non_dns_request``

- The following types/records were deprecated in version 2.6 or below and are
  removed from this release:

    - ``peer_id``
    - ``event_peer``
    - ``packet``
    - ``software``
    - ``software_version``

- The following configuration options were deprecated in version 2.6 or below and are
  removed from this release:

    - ``max_remote_events_processed``
    - ``forward_remote_events``
    - ``forward_remote_state_changes``
    - ``enable_syslog``
    - ``remote_trace_sync_interval``
    - ``remote_trace_sync_peers``
    - ``remote_check_sync_consistency``
    - ``log_rotate_interval``
    - ``log_max_size``
    - ``log_encryption_key``
    - ``state_dir``
    - ``state_write_delay``
    - ``ssl_ca_certificate``
    - ``ssl_private_key``
    - ``ssl_passphrase``
    - ``suppress_local_output``
    - ``irc_servers``
    - ``interconn_min_interarrival``
    - ``interconn_max_interarrival``
    - ``interconn_max_keystroke_pkt_size``
    - ``interconn_default_pkt_size``
    - ``interconn_stat_period``
    - ``interconn_stat_backoff``
    - ``interconn_endp_stats``
    - ``backdoor_stat_period``
    - ``backdoor_stat_backoff``
    - ``backdoor_endp_stats``
    - ``chunked_io_buffer_soft_cap``

- The following constants were used as part of deprecated functionality in version 2.6
  or below and are removed from this release:

    - ``PEER_ID_NONE``
    - ``REMOTE_LOG_INFO``
    - ``REMOTE_SRC_CHILD``
    - ``REMOTE_SRC_PARENT``
    - ``REMOTE_SRC_SCRIPT``

- The deprecated script ``policy/protocols/smb/__load__.bro`` was removed.
  Instead of ``@load policy/protocols/smb`` use ``@load base/protocols/smb``.

- Broccoli, which had been deprecated in version 2.6 and was no longer built by default
  was removed from the source tree.

- Support for the &persistent, &synchronized, &mergeable, &encrypt, &rotate_interval,
  and &rotate_size attributes, which were deprecated in Bro 2.6, was removed. The ``-g``
  command-line option (dump-config) which relied on this functionality was also removed.

- Functionality for writing state updates for variables with the
  &synchronized attribute was removed. This entails the
  ``-x`` command-line option (print-state) as well as the
  ``capture_state_updates`` function.

- Removed the BroControl ``update`` command, which was deprecated in Bro 2.6.

- Functionality for writing/reading binary event streams was
  removed. This functionality relied on the old communication code
  and was basically untested. The ``-R`` command-line option (replay)
  as well as the ``capture_events`` function were removed.

- Removed p0f (passive OS fingerprinting) support. The version of
  p0f shipped with zeek was ancient, probably did not give
  any reliable support anymore and did not offer a clear
  upgrade path. The ``OS_version_found`` event as well as the
  ``generate_OS_version_event`` configuration option were removed.

- Removed the ``max_files_in_cache`` option and the associated
  "file caching" feature it's associated with. That feature allowed
  one to open many scripting-layer ``file`` objects and potentially
  bypass the operating system's resource limits for open files.
  This is typically not necessary and it's a problem that is more
  appropriately addressed at the system configuration level.

- Removed the InterConn analyzer.

- Removed the BackDoor analyzer.

- Removed ``List::sortedinsert`` from the C++ API.

Deprecated Functionality
------------------------

- The ``str_shell_escape`` function is now deprecated, use ``safe_shell_quote``
  instead.  The later will automatically return a value that is enclosed
  in double-quotes.

- The ``bro_init``, ``bro_done``, and ``bro_script_loaded`` events are now
  deprecated, use ``zeek_init``, ``zeek_done``, and
  ``zeek_script_loaded`` instead.  Any existing event handlers for
  the deprecated versions will automatically alias to the new events
  such that existing code will not break, but will emit a deprecation
  warning.

- The ``bro_is_terminating`` and ``bro_version`` function are deprecated and
  replaced by functions named ``zeek_is_terminating`` and ``zeek_version``.

- The ``List::insert`` method from the C++ API is deprecated, use
  ``List::push_front`` instead.

Bro 2.6
=======

New Functionality
-----------------

- Bro has switched to using the new Broker library for all its
  communication. Broker's API has been completely redesigned (compared
  to the version in 2.5), and much of its implementation has been
  redone. There's a new script-level "broker" framework that
  supersedes the old "communication" framework, which is now
  deprecated.  All scripts that ship with Bro have been ported to use
  Broker.  BroControl has likewise been ported to use Broker.

  For more about the new Broker framework, see
  https://www.bro.org/sphinx-git/frameworks/broker.html.  There's also
  a guide there for porting existing Bro scripts to Broker. For more
  about Broker itself, including its API for external applications,
  see https://bro-broker.readthedocs.io/en/stable

  When using BroControl, the function of proxies has changed with
  Broker. If you are upgrading and have configured more than one proxy
  currently, we recommend going back down to a single proxy node now.
  That should be fine unless you are using custom scripts doing
  significant data distribution through the new cluster framework.

  A side effect of the switch to using Broker is that each Bro node now runs
  as a single process instead of two.  Also, the number of file descriptors
  being polled in Bro's main event loop has been reduced (1 per worker
  versus 5).  This should increase the number of workers one can
  use before reaching the common 1024 file descriptor limitation of
  "select()".

- Bro now has new "is" and "as" script operators for dynamic
  type-checking and casting.

    - "v as T" casts a value v into a value of type T, assuming that's
      possible (if not, it triggers a runtime error).

    - "v is T" returns a boolean indicating whether value v can be
      casted into type T (i.e., if true then "v as T" will succeed).

    This casting supports three cases currently: (1) a value of
    declared type "any" can be casted to its actual underlying type;
    (2) Broker values can be casted to their corresponding script
    types; and (3) all values can be casted to their declared types
    (i.e., a no-op).

    Example for "any"::

        # cat a.bro
        function check(a: any)
            {
            local s: string = "default";

            if ( a is string )
                s = (a as string);

            print fmt("s=%s", s);
            }

        event bro_init()
            {
            check("Foo");
            check(1);
            }

        # bro a.bro
        s=Foo
        s=default

- The existing "switch" statement got extended to now also support switching by
  type rather than value. The new syntax supports two type-based versions
  of "case":

    - "case type T: ...": Take branch if operand can be casted to type T.

    - "case type T as x: ... ": Take branch if operand can be casted
      to type T, and make the casted value available through ID "x".

    Multiple types can be listed per branch, separated by commas.
    However, one cannot mix cases with expressions and types inside a
    single switch statement.

    Example::

        function switch_one(v: any)
            {
            switch (v) {
            case type string:
                    print "It's a string!";
                    break;

            case type count as c:
                    print "It's a count!", c;
                    break;

            case type bool, type addr:
                    print "It's a bool or address!";
                    break;

            default:
                    print "Something else!";
                    break;
            }
            }

- Bro now comes with a new "configuration framework" that allows
  updating script options dynamically at runtime. This functionality
  consists of three larger pieces working together:

  - Option variables: The new "option" keyword allows variables to be
    declared as runtime options. Such variables cannot be changed
    using normal assignments. Instead, they can be changed using the
    new function "Config::set_value".  This function will automatically
    apply the change to all nodes in a cluster.  Note that options can also
    be changed using the new function "Option::set", but this function will
    not send the change to any other nodes, so Config::set_value should
    typically be used instead of Option::set.

    Various redef-able constants in the standard Bro scripts have
    been converted to runtime options.  This change will not affect any
    user scripts because the initial value of runtime options can still be
    redefined with a "redef" declaration.  Example::

        option testvar = "old value";
        redef testvar = "new value";

    It is possible to "subscribe" to an option through
    "Option::set_change_handler", which will trigger a handler callback
    when an option changes. Change handlers can optionally modify
    values before they are applied by returning the desired value, or
    reject updates by returning the old value. Priorities can be
    specified if there are several handlers for one option.

    Example script::

        option testbool: bool = T;

        function option_changed(ID: string, new_value: bool): bool
            {
            print fmt("Value of %s changed from %s to %s", ID, testbool, new_value);
            return new_value;
            }

        event bro_init()
            {
            print "Old value", testbool;
            Option::set_change_handler("testbool", option_changed);
            Option::set("testbool", F);
            print "New value", testbool;
            }

  - Script-level configuration framework: The new script framework
    base/framework/config facilitates reading in new option values
    from external files at runtime. The format for these files looks
    like this::

        [option name][tab/spaces][new variable value]

    Configuration files to read can be specified by adding them to
    "Config::config_files".

    Usage example::

        redef Config::config_files += { "/path/to/config.dat" };

        module TestConfig;

        export {
            option testbool: bool = F;
        }

    The specified file will now be monitored continuously for changes, so
    that writing "TestConfig::testbool T" into ``/path/to/config.dat`` will
    automatically update the option's value accordingly.

    The configuration framework creates a ``config.log`` that shows all
    value changes that took place.

  - Config reader: Internally, the configuration framework uses a new
    type of input reader to read such configuration files into Bro.
    The reader uses the option name to look up the type that variable
    has, converts the read value to the correct type, and then updates
    the option's value. Example script use::

        type Idx: record {
            option_name: string;
        };

        type Val: record {
            option_val: string;
        };

        global currconfig: table[string] of string = table();

        event InputConfig::new_value(name: string, source: string, id: string, value: any)
            {
            print id, value;
            }

        event bro_init()
            {
            Input::add_table([$reader=Input::READER_CONFIG, $source="../configfile", $name="configuration", $idx=Idx, $val=Val, $destination=currconfig, $want_record=F]);
            }

- Support for OCSP and Signed Certificate Timestamp. This adds the
  following events and BIFs:

  - Events:

    - ocsp_request
    - ocsp_request_certificate
    - ocsp_response_status
    - ocsp_response_bytes
    - ocsp_response_certificate
    - ocsp_extension
    - x509_ocsp_ext_signed_certificate_timestamp
    - ssl_extension_signed_certificate_timestamp

  - Functions:

    - sct_verify
    - x509_subject_name_hash
    - x509_issuer_name_hash
    - x509_spki_hash

- The SSL scripts provide a new hook "ssl_finishing(c: connection)"
  to trigger actions after the handshake has concluded.

- New functionality has been added to the TLS parser, adding several
  events. These events mostly extract information from the server and client
  key exchange messages. The new events are:

  - ssl_ecdh_server_params
  - ssl_dh_server_params
  - ssl_server_signature
  - ssl_ecdh_client_params
  - ssl_dh_client_params
  - ssl_rsa_client_pms

  Since "ssl_ecdh_server_params" contains more information than the old
  "ssl_server_curve" event, "ssl_server_curve" is now marked as deprecated.

- The "ssl_application_data" event was retired and replaced with
  "ssl_plaintext_data".

- Some SSL events were changed and now provide additional data. These events
  are:

  - ssl_client_hello
  - ssl_server_hello
  - ssl_encrypted_data

  If you use these events, you can make your scripts work on old and new
  versions of Bro by wrapping the event definition in an "@if", for example::

    @if ( Version::at_least("2.6") || ( Version::number == 20500 && Version::info$commit >= 944 ) )
    event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
    @else
    event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec)
    @endif

- Functions for retrieving files by their ID have been added:

  - Files::file_exists
  - Files::lookup_File

- New functions in the logging API:

  - Log::get_filter_names
  - Log::enable_stream

- HTTP now recognizes and skips upgraded/websocket connections.  A new event,
  "http_connection_upgrade", is raised in such cases.

- A new hook, HTTP::sqli_policy, may be used to whitelist requests that
  could otherwise be counted as SQL injection attempts.

- Added a MOUNT3 protocol parser

  - This is not enabled by default (no ports are registered and no
    DPD signatures exist, so no connections will end up attaching the
    new Mount analyzer).  If it were to be activated by users, the
    following events are available:

    - mount_proc_null
    - mount_proc_mnt
    - mount_proc_umnt
    - mount_proc_umnt_all
    - mount_proc_not_implemented
    - mount_reply_status

- Added new NFS events:

  - nfs_proc_symlink
  - nfs_proc_link
  - nfs_proc_sattr

- The SMB scripts in ``policy/protocols/smb`` are now moved into
  ``base/protocols/smb`` and loaded/enabled by default.  If you previously
  loaded these scripts from their ``policy/`` location (in local.bro or
  other custom scripts) you may now remove/change those although they
  should still work since ``policy/protocols/smb`` is simply a placeholder
  script that redirects to the new ``base/`` location.

- Added new SMB events:

  - smb1_transaction_secondary_request
  - smb1_transaction2_secondary_request
  - smb1_transaction_response

- Bro can now decrypt Kerberos tickets, and retrieve the authentication from
  them, given a suitable keytab file.

- Added support for bitwise operations on "count" values.  '&', '|' and
  '^' are binary "and", "or" and "xor" operators, and '~' is a unary
  ones-complement operator.

- The '&' and '|' operators can apply to patterns, too.  p1 & p2 yields
  a pattern that represents matching p1 followed by p2, and p1 | p2 yields
  a pattern representing matching p1 or p2.  The p1 | p2 functionality was
  semi-present in previous versions of Bro, but required constants as
  its operands; now you can use any pattern-valued expressions.

- You can now specify that a pattern matches in a case-insensitive
  fashion by adding 'i' to the end of its specification.  So for example
  /fOO/i == "Foo" yields T, as does /fOO/i in "xFoObar".

  You can achieve the same functionality for a subpattern enclosed in
  parentheses by adding "?i:" to the open parenthesis.  So for example
  /foo|(?i:bar)/ will match "BaR", but not "FoO".

  For both ways of specifying case-insensitivity, characters enclosed in
  double quotes remain case-sensitive.  So for example /"foo"/i will not
  match "Foo", but it will match "foo".

- "make install" now installs Bro's include headers (and more) into
  "--prefix" so that compiling plugins no longer needs access to a
  source/build tree. For OS distributions, this also facilitates
  creating "bro-devel" packages providing all files necessary to build
  plugins.

- Bro now supports PPPoE over QinQ.

- Bro now supports OpenSSL 1.1.

- The new connection/conn.log history character 'W' indicates that
  the originator ('w' = responder) advertised a TCP zero window
  (instructing the peer to not send any data until receiving a
  non-zero window).

- The connection/conn.log history characters 'C' (checksum error seen),
  'T' (retransmission seen), and 'W' (zero window advertised) are now
  repeated in a logarithmic fashion upon seeing multiple instances
  of the corresponding behavior.  Thus a connection with 2 C's in its
  history means that the originator sent >= 10 packets with checksum
  errors; 3 C's means >= 100, etc.

- The above connection history behaviors occurring multiple times
  (i.e., starting at 10 instances, than again for 100 instances,
  etc.) generate corresponding events:

  - tcp_multiple_checksum_errors
  - udp_multiple_checksum_errors
  - tcp_multiple_zero_windows
  - tcp_multiple_retransmissions

  Each has the same form, e.g.::

      event tcp_multiple_retransmissions(c: connection, is_orig: bool,
                                         threshold: count);

- Added support for set union, intersection, difference, and comparison
  operations.  The corresponding operators for the first three are
  "s1 | s2", "s1 & s2", and "s1 - s2".  Relationals are in terms
  of subsets, so "s1 < s2" yields true if s1 is a proper subset of s2
  and "s1 == s2" if the two sets have exactly the same elements.
  "s1 <= s2" holds for subsets or equality, and similarly "s1 != s2",
  "s1 > s2", and "s1 >= s2" have the expected meanings in terms
  of non-equality, proper superset, and superset-or-equal.

- An expression of the form "v += e" will append the value of the expression
  "e" to the end of the vector "v" (of course assuming type-compatibility).
  "redef v += { a, b, c }" will similarly extend a vector previously declared
  with &redef by appending the result of expressions "a", "b", and "c" to
  the vector at initialization-time.

- A new "@deprecated" directive was added. It marks a script-file as
  deprecated.

Changed Functionality
---------------------

- All communication is now handled through Broker, requiring changes
  to existing scripts to port them over to the new API. The Broker
  framework documentation comes with a porting guide.

- The DHCP analyzer and its script-layer interface have been rewritten.

  - Supports more DHCP options than before.

  - The DHCP log now represents DHCP sessions based on transaction ID
    and works on Bro cluster deployments.

  - Removed the ``policy/protocols/dhcp/known-devices-and-hostnames.bro``
    script since it's generally less relevant now with the updated log.

  - Removed the ``base/protocols/dhcp/utils.bro`` script and thus the
    "reverse_ip" function.

  - Replaced all DHCP events with the single "dhcp_message" event.
    The list of removed events includes:

    - dhcp_discover
    - dhcp_offer
    - dhcp_request
    - dhcp_decline
    - dhcp_ack
    - dhcp_nak
    - dhcp_release
    - dhcp_inform

  - A new script, ``policy/protocols/dhcp/deprecated_events.bro``, may be
    loaded to aid those transitioning away from the list of "removed"
    events above.  The script provides definitions for the old events
    and automatically generates them from a "dhcp_message" handler, thus
    providing equivalent functionality to the previous Bro release.
    Such usage emits deprecation warnings.

- Removed ``policy/misc/known-devices.bro`` script and thus
  ``known_devices.log`` will no longer be created.

- The "--with-binpac" configure option has changed to mean "path
  to the binpac executable" instead of "path to binpac installation root".

- The MIME types used to identify X.509 certificates in SSL
  connections changed from "application/pkix-cert" to
  "application/x-x509-user-cert" for host certificates and
  "application/x-x509-ca-cert" for CA certificates.

- The "ssl_server_curve" event is considered deprecated and will be removed
  in the future.  See the new "ssl_ecdh_server_params" event for a
  replacement.

- The Socks analyzer no longer logs passwords by default. This
  brings its behavior in line with the FTP/HTTP analyzers which also
  do not log passwords by default.

  To restore the previous behavior and log Socks passwords, use::

      redef SOCKS::default_capture_password = T;

- The DNS base scripts no longer generate some noisy and annoying
  weirds:

  - dns_unmatched_msg
  - dns_unmatched_msg_quantity
  - dns_unmatched_reply

- The "tunnel_parents" field of ``conn.log`` is now marked ``&optional``, so,
  in the default configuration of logs, this field will show "-"
  instead of "(empty)" for connections that lack any tunneling.

- SMB event argument changes:

  - "smb1_transaction_request" now has two additional arguments, "parameters"
    and "data" strings

  - "smb1_transaction2_request" now has an additional "args" record argument

- The "SMB::write_cmd_log" option has been removed and the corresponding
  logic moving to ``policy/protocols/smb/log-cmds.bro`` which can simply
  be loaded to produce the same effect of toggling the old flag on.

- SSL event argument changes:

  - "ssl_server_signature" now has an additional argument
    "signature_and_hashalgorithm".

- The "dnp3_header_block" event no longer has the "start" parameter.

- The "string_to_pattern()" and now-deprecated "merge_pattern()"
  built-ins are no longer restricted to only be called at initialization time.

- GeoIP Legacy Database support has been replaced with GeoIP2 MaxMind DB
  format support.

  - This updates the "lookup_location" and "lookup_asn" BIFs to use
    libmaxminddb.  The motivation for this is that MaxMind is discontinuing
    GeoLite Legacy databases: no updates after April 1, 2018, no downloads
    after January 2, 2019.  It's also noted that all GeoIP Legacy databases
    may be discontinued as they are superseded by GeoIP2.

- "Weird" events are now generally suppressed/sampled by default according to
  some tunable parameters:

  - Weird::sampling_whitelist
  - Weird::sampling_threshold
  - Weird::sampling_rate
  - Weird::sampling_duration

  Those options can be changed if one needs the previous behavior of
  a "net_weird", "flow_weird", or "conn_weird" event being raised for
  every single event.

  The original ``weird.log`` may not differ much with these changes,
  except in the cases where a particular weird type exceeds the
  sampling threshold.

  Otherwise, there is a new ``weird_stats.log`` generated via
  ``policy/misc/weird-stats.bro`` which contains concise summaries
  of weird counts per type per time period.

- Improved DCE-RPC analysis via tracking of context identifier mappings

  - These DCE-RPC events now contain an additional context-id argument:

    - dce_rpc_bind
    - dce_rpc_request
    - dce_rpc_response

  - Added new events:

    - dce_rpc_alter_context
    - dce_rpc_alter_context_resp

- The default value of ``Pcap::snaplen`` changed from 8192 to 9216 bytes
  to better accommodate jumbo frames.

- Improvements to ``ntlm.log`` to fix incorrect reporting of login
  success/failure.  Also, the "status" field was removed and
  "server_nb_computer_name", "server_dns_computer_name", and
  "server_tree_name" fields added.

- BroControl: The output of the broctl "top" command has changed slightly.
  The "Proc" column has been removed from the output.  This column previously
  indicated whether each Bro process was the "parent" or "child", but this
  is no longer relevant because each Bro node now runs as a single process.

- The ``DNP3::function_codes`` name for request 0x21 has been corrected from
  "AUTHENTICATE_ERR" to "AUTHENTICATE_REQ_NR".

- The ``DNS::query_types`` names for resource records 41 and 100 have been
  corrected from "EDNS" to "OPT" and "DINFO" to "UINFO", respectively.

Removed Functionality
---------------------

- We no longer maintain any Bro plugins as part of the Bro
  distribution. Most of the plugins that used to be in aux/plugins have
  been moved over to use the Bro Package Manager instead. See
  https://packages.bro.org for a list of Bro packages currently
  available.

- The "ocsp_request" event no longer has "requestorName" parameter.

- The node-specific ``site/local-*.bro`` scripts have been removed.

- BroControl: The "IPv6Comm" and "ZoneID" options are no longer
  available (though Broker should be able to handle IPv6 automatically).

Deprecated Functionality
------------------------

- The old communication system is now deprecated and scheduled for
  removal with the next Bro release. This includes the "communication"
  framework, the ``&synchronized`` attributes, and the existing
  communication-related BiFs. Use Broker instead.

- The infrastructure for serializing Bro values into a binary
  representation is now deprecated and scheduled for removal with the
  next Bro release. This includes the ``&persistent`` attribute, as well
  as BIFs like "send_id()". Use Broker data stores and the new
  configuration framework instead.

- Mixing of scalars and vectors, such as "v + e" yielding a vector
  corresponding to the vector v with the scalar e added to each of
  its elements, has been deprecated.

- The built-in function "merge_pattern()" has been deprecated.  It will
  be replaced by the '&' operator for patterns.

- The undocumented feature of using "&&" and "||" operators for patterns
  has been deprecated.

- BroControl: The "update" command is deprecated and scheduled for
  removal with the next Bro release. Bro's new configuration framework
  is taking its place.

Bro 2.5.5
=========

Bro 2.5.5 primarily addresses security issues.

- Fix array bounds checking in BinPAC: for arrays that are fields within
  a record, the bounds check was based on a pointer to the start of the
  record rather than the start of the array field, potentially resulting
  in a buffer over-read.

- Fix SMTP command string comparisons: the number of bytes compared was
  based on the user-supplied string length and can lead to incorrect
  matches.  e.g. giving a command of "X" incorrectly matched
  "X-ANONYMOUSTLS" (and an empty commands match anything).

The following changes address potential vectors for Denial of Service
reported by Christian Titze & Jan Grashöfer of Karlsruhe Institute of
Technology:

- "Weird" events are now generally suppressed/sampled by default according
   to some tunable parameters:

  - Weird::sampling_whitelist
  - Weird::sampling_threshold
  - Weird::sampling_rate
  - Weird::sampling_duration

  Those options can be changed if one needs the previous behavior of
  a "net_weird", "flow_weird", or "conn_weird" event being raised for
  every single event.  Otherwise, there is a new weird_stats.log which
  contains concise summaries of weird counts per type per time period
  and the original weird.log may not differ much either, except in
  the cases where a particular weird type exceeds the sampling threshold.
  These changes help improve performance issues resulting from excessive
  numbers of weird events.

- Improved handling of empty lines in several text protocol analyzers
  that can cause performance issues when seen in long sequences.

- Add 'smtp_excessive_pending_cmds' weird which serves as a notification
  for when the "pending command" queue has reached an upper limit and
  been cleared to prevent one from attempting to slowly exhaust memory.

Bro 2.5.4
=========

Bro 2.5.4 primarily fixes security issues:

- Multiple fixes and improvements to BinPAC generated code related to
  array parsing, with potential impact to all Bro's BinPAC-generated
  analyzers in the form of buffer over-reads or other invalid memory
  accesses depending on whether a particular analyzer incorrectly
  assumed that the evaluated-array-length expression is actually the
  number of elements that were parsed out from the input.

- The NCP analyzer (not enabled by default and also updated to actually
  work with newer Bro APIs in the release) performed a memory allocation
  based directly on a field in the input packet and using signed integer
  storage.  This could result in a signed integer overflow and memory
  allocations of negative or very large size, leading to a crash or
  memory exhaustion.  The new NCP::max_frame_size tuning option now
  limits the maximum amount of memory that can be allocated.

There's also the following bug fixes:

- A memory leak in the SMBv1 analyzer.

- The MySQL analyzer was generally not working as intended, for example,
  it now is able to parse responses that contain multiple results/rows.

Bro 2.5.3
=========

Bro 2.5.3 fixes a security issue in Binpac generated code. In some cases
the code generated by binpac could lead to an integer overflow which can
lead to out of bound reads and allow a remote attacker to crash Bro; there
is also a possibility that this can be exploited in other ways.

Bro 2.5.2
=========

Bro 2.5.2 fixes a security issue in the ContentLine analyzer. In rare cases
a bug in the ContentLine analyzer can lead to an out of bound write of a single
byte. This allows a remote attacker to crash Bro; there also is a possibility
this can be exploited in other ways. CVE-2017-1000458 has been assigned to this
issue.

Bro 2.5.1
=========

New Functionality
-----------------

- Bro now includes bifs for rename, unlink, and rmdir.

- Bro now includes events for two extensions used by TLS 1.3:
  ssl_extension_supported_versions and ssl_extension_psk_key_exchange_modes

- Bro now includes hooks that can be used to interact with log processing
  on the C++ level.

- Bro now supports ERSPAN. Currently this ignores the ethernet header that is
  carried over the tunnel; if a MAC is logged currently only the outer MAC
  is returned.

- Added a new BroControl option CrashExpireInterval to enable
  "broctl cron" to remove crash directories that are older than the
  specified number of days (the default value is 0, which means crash
  directories never expire).

- Added a new BroControl option MailReceivingPackets to control
  whether or not "broctl cron" will mail a warning when it notices
  that no packets were seen on an interface.

- There is a new broctl command-line option "--version" which outputs
  the BroControl version.

Changed Functionality
---------------------

- The input framework's Ascii reader is now more resilient. If an input
  is marked to reread a file when it changes and the file didn't exist
  during a check Bro would stop watching the file in previous versions.
  The same could happen with bad data in a line of a file.  These
  situations do not cause Bro to stop watching input files anymore. The
  old behavior is available through settings in the Ascii reader.

- The RADIUS scripts have been reworked. Requests are now logged even if
  there is no response. The new framed_addr field in the log indicates
  if the radius server is hinting at an address for the client. The ttl
  field indicates how quickly the server is replying to the network access
  server.

- With the introduction of the Bro package manager, the Bro plugin repository
  is considered deprecated. The af_packet, postgresql, and tcprs plugins have
  already been removed and are available via bro-pkg.

Bro 2.5
=======

New Dependencies
----------------

- Bro now requires a compiler with C++11 support for building the
  source code.

- Bro now requires Python instead of Perl to compile the source code.

- When enabling Broker (which is disabled by default), Bro now requires
  version 0.14 of the C++ Actor Framework.

New Functionality
-----------------

- SMB analyzer. This is the rewrite that has been in development for
  several years. The scripts are currently not loaded by default and
  must be loaded manually by loading policy/protocols/smb. The next
  release will load the smb scripts by default.

   - Implements SMB1+2.
   - Fully integrated with the file analysis framework so that files
     transferred over SMB can be analyzed.
   - Includes GSSAPI and NTLM analyzer and reimplements the DCE-RPC
     analyzer.
   - New logs: smb_cmd.log, smb_files.log, smb_mapping.log, ntlm.log,
     and dce_rpc.log
   - Not every possible SMB command or functionality is implemented, but
     generally, file handling should work whenever files are transferred.
     Please speak up on the mailing list if there is an obvious oversight.

- Bro now includes the NetControl framework. The framework allows for easy
  interaction of Bro with hard- and software switches, firewalls, etc.
  New log files: netcontrol.log, netcontrol_catch_release.log,
  netcontrol_drop.log, and netcontrol_shunt.log.

- Bro now includes the OpenFlow framework which exposes the data structures
  necessary to interface to OpenFlow capable hardware.

- Bro's Intelligence Framework was refactored and new functionality
  has been added:

  - The framework now supports the new indicator type Intel::SUBNET.
    As subnets are matched against seen addresses, the new field 'matched'
    in intel.log was introduced to indicate which indicator type(s) caused
    the hit.

  - The new function remove() allows to delete intelligence items.

  - The intel framework now supports expiration of intelligence items.
    Expiration can be configured using the new Intel::item_expiration constant
    and can be handled by using the item_expired() hook. The new script
    do_expire.bro removes expired items.

  - The new hook extend_match() allows extending the framework. The new
    policy script whitelist.bro uses the hook to implement whitelisting.

  - Intel notices are now suppressible and mails for intel notices now
    list the identified services as well as the intel source.

- There is a new file entropy analyzer for files.

- Bro now supports the remote framebuffer protocol (RFB) that is used by
  VNC servers for remote graphical displays.  New log file: rfb.log.

- Bro now supports the Radiotap header for 802.11 frames.

- Bro now has rudimentary IMAP and XMPP analyzers examining the initial
  phases of the protocol. Right now these analyzers only identify
  STARTTLS sessions, handing them over to TLS analysis. These analyzers
  do not yet analyze any further IMAP/XMPP content.

- New functionality has been added to the SSL/TLS analyzer:

  - Bro now supports (draft) TLS 1.3.

  - The new event ssl_extension_signature_algorithm() allows access to the
    TLS signature_algorithms extension that lists client supported signature
    and hash algorithm pairs.

  - The new event ssl_extension_key_share gives access to the supported named
    groups in TLS 1.3.

  - The new event ssl_application_data gives information about application data
    that is exchanged before encryption fully starts. This is used to detect
    when encryption starts in TLS 1.3.

- Bro now tracks VLAN IDs. To record them inside the connection log,
  load protocols/conn/vlan-logging.bro.

- A new dns_CAA_reply() event gives access to DNS Certification Authority
  Authorization replies.

- A new per-packet event raw_packet() provides access to layer 2
  information. Use with care, generating events per packet is
  expensive.

- A new built-in function, decode_base64_conn() for Base64 decoding.
  It works like decode_base64() but receives an additional connection
  argument that will be used for decoding errors into weird.log
  (instead of reporter.log).

- A new get_current_packet_header() bif returns the headers of the current
  packet.

- Three new built-in functions for handling set[subnet] and table[subnet]:

  - check_subnet(subnet, table) checks if a specific subnet is a member
    of a set/table. This is different from the "in" operator, which always
    performs a longest prefix match.

  - matching_subnets(subnet, table) returns all subnets of the set or table
    that contain the given subnet.

  - filter_subnet_table(subnet, table) works like matching_subnets, but returns
    a table containing all matching entries.

- Several built-in functions for handling IP addresses and subnets were added:

  - is_v4_subnet(subnet) checks whether a subnet specification is IPv4.

  - is_v6_subnet(subnet) checks whether a subnet specification is IPv6.

  - addr_to_subnet(addr) converts an IP address to a /32 subnet.

  - subnet_to_addr(subnet) returns the IP address part of a subnet.

  - subnet_width(subnet) returns the width of a subnet.

- The IRC analyzer now recognizes StartTLS sessions and enables the SSL
  analyzer for them.

- The misc/stats.bro script is now loaded by default and logs more Bro
  execution statistics to the stats.log file than it did previously. It
  now also uses the standard Bro log format.

- A set of new built-in functions for gathering execution statistics:

      get_net_stats(), get_conn_stats(), get_proc_stats(),
      get_event_stats(), get_reassembler_stats(), get_dns_stats(),
      get_timer_stats(), get_file_analysis_stats(), get_thread_stats(),
      get_gap_stats(), get_matcher_stats()

- Two new functions haversine_distance() and haversine_distance_ip()
  for calculating geographic distances. The latter function requires that Bro
  be built with libgeoip.

- Table expiration timeout expressions are evaluated dynamically as
  timestamps are updated.

- The pcap buffer size can be set through the new option Pcap::bufsize.

- Input framework readers stream types Table and Event can now define a custom
  event (specified by the new "error_ev" field) to receive error messages
  emitted by the input stream. This can, e.g., be used to raise notices in
  case errors occur when reading an important input source.

- The logging framework now supports user-defined record separators,
  renaming of column names, as well as extension data columns that can
  be added to specific or all logfiles (e.g., to add new names).

- The new "bro-config" script can be used to determine the Bro installation
  paths.

- New BroControl functionality in aux/broctl:

  - There is a new node type "logger" that can be specified in
    node.cfg (that file has a commented-out example).  The purpose of
    this new node type is to receive logs from all nodes in a cluster
    in order to reduce the load on the manager node.  However, if
    there is no "logger" node, then the manager node will handle
    logging as usual.

  - The post-terminate script will send email if it fails to archive
    any log files.  These mails can be turned off by changing the
    value of the new BroControl option MailArchiveLogFail.

  - Added the ability for "broctl deploy" to reload the BroControl
    configuration (both broctl.cfg and node.cfg).  This happens
    automatically if broctl detects any changes to those config files
    since the last time the config was loaded.  Note that this feature
    is relevant only when using the BroControl shell interactively.

  - The BroControl plugin API has a new function "broctl_config".
    This gives plugin authors the ability to add their own script code
    to the autogenerated broctl-config.bro script.

  - There is a new BroControl plugin for custom load balancing.  This
    plugin can be used by setting "lb_method=custom" for your worker
    nodes in node.cfg.  To support packet source plugins, it allows
    configuration of a prefix and suffix for the interface name.

- New Bro plugins in aux/plugins:

    - af_packet: Native AF_PACKET support.
    - kafka : Log writer interfacing to Kafka.
    - myricom: Native Myricom SNF v3 support.
    - pf_ring: Native PF_RING support.
    - postgresql: A PostgreSQL reader/writer.
    - redis: An experimental log writer for Redis.
    - tcprs: A TCP-level analyzer detecting retransmissions, reordering, and more.

Changed Functionality
---------------------

- Log changes:

    - Connections

        The 'history' field gains two new flags: '^' indicates that
        Bro heuristically flipped the direction of the connection.
        't/T' indicates the first TCP payload retransmission from
        originator or responder, respectively.

    - Intelligence

        New field 'matched' to indicate which indicator type(s) caused the hit.

    - DNS

        New 'rtt' field to indicate the round trip time between when a
        request was sent and when a reply started.

    - SMTP

        New 'cc' field which includes the 'Cc' header from MIME
        messages sent over SMTP.

        Changes in 'mailfrom' and 'rcptto' fields to remove some
        non-address cruft that will tend to be found.  The main
        example is the change from ``"<user@domain>"`` to
        ``"user@domain.com"``.

    - HTTP

        Removed 'filename' field (which was seldom used).

        New 'orig_filenames' and 'resp_filenames' fields which each
        contain a vector of filenames seen in entities transferred.

    - stats.log

        The following fields have been added: active_tcp_conns,
        active_udp_conns, active_icmp_conns, tcp_conns, udp_conns,
        icmp_conns, timers, active_timers, files, active_files, dns_requests,
        active_dns_requests, reassem_tcp_size, reassem_file_size,
        reassem_frag_size, reassem_unknown_size.

        The following fields have been renamed: lag -> pkt_lag.

        The following fields have been removed: pkts_recv.

- The BrokerComm and BrokerStore namespaces were renamed to Broker.
  The Broker "print()" function was renamed to Broker::send_print(), and
  the "event()" function was renamed to Broker::send_event().

- The constant ``SSH::skip_processing_after_detection`` was removed. The
  functionality was replaced by the new constant
  ``SSH::disable_analyzer_after_detection``.

- The ``net_stats()`` and ``resource_usage()`` functions have been
  removed, and their functionality is now provided by the new execution
  statistics functions (see above).

- Some script-level identifiers have changed their names:

      - snaplen                  -> Pcap::snaplen
      - precompile_pcap_filter() -> Pcap::precompile_pcap_filter()
      - install_pcap_filter()    -> Pcap::install_pcap_filter()
      - pcap_error()             -> Pcap::error()

- TCP analysis was changed to process connections without the initial
  SYN packet. In the past, connections without a full handshake were
  treated as partial, meaning that most application-layer analyzers
  would refuse to inspect the payload. Now, Bro will consider these
  connections as complete and all analyzers will process them normally.

- The ``policy/misc/capture-loss.bro`` script is now loaded by default.

- The traceroute detection script package ``policy/misc/detect-traceroute``
  is no longer loaded by default.

- Changed BroControl functionality in aux/broctl:

  - The networks.cfg file now contains private IP space 172.16.0.0/12
    by default.

  - Upon startup, if broctl can't get IP addresses from the "ifconfig"
    command for any reason, then broctl will now also try to use the
    "ip" command.

  - BroControl will now automatically search the Bro plugin directory
    for BroControl plugins (in addition to all the other places where
    BroControl searches).  This enables automatic loading of
    BroControl plugins that are provided by a Bro plugin.

  - Changed the default value of the StatusCmdShowAll option so that
    the "broctl status" command runs faster.  This also means that
    there is no longer a "Peers" column in the status output by
    default.

  - Users can now specify a more granular log expiration interval. The
    BroControl option LogExpireInterval can be set to an arbitrary
    time interval instead of just an integer number of days.  The time
    interval is specified as an integer followed by a time unit:
    "day", "hr", or "min".  For backward compatibility, an integer
    value without a time unit is still interpreted as a number of
    days.

  - Changed the text of crash report emails.  Now crash reports tell
    the user to forward the mail to the Bro team only when a backtrace
    is included in the crash report.  If there is no backtrace, then
    the crash report includes instructions on how to get backtraces
    included in future crash reports.

  - There is a new option SitePolicyScripts that replaces SitePolicyStandalone
    (the old option is still available, but will be removed in the next
    release).

Removed Functionality
---------------------

- The app-stats scripts have been removed because they weren't
  being maintained and they were becoming inaccurate (as a result, the
  app_stats.log is also gone). They were also prone to needing more regular
  updates as the internet changed and will likely be more relevant if
  maintained externally.

- The event ack_above_hole() has been removed, as it was a subset
  of content_gap() and led to plenty of noise.

- The command line options ``--analyze``, ``--set-seed``, and
  ``--md5-hashkey`` have been removed.

- The packaging scripts pkg/make-\*-packages are gone. They aren't
  used anymore for the binary Bro packages that the project
  distributes; haven't been supported in a while; and have
  problems.

Deprecated Functionality
------------------------

- The built-in functions decode_base64_custom() and
  encode_base64_custom() are no longer needed and will be removed
  in the future. Their functionality is now provided directly by
  decode_base64() and encode_base64(), which take an optional
  parameter to change the Base64 alphabet.

Bro 2.4
=======

New Functionality
-----------------

- Bro now has support for external plugins that can extend its core
  functionality, like protocol/file analysis, via shared libraries.
  Plugins can be developed and distributed externally, and will be
  pulled in dynamically at startup (the environment variables
  BRO_PLUGIN_PATH and BRO_PLUGIN_ACTIVATE can be used to specify the
  locations and names of plugins to activate). Currently, a plugin
  can provide custom protocol analyzers, file analyzers, log writers,
  input readers, packet sources and dumpers, and new built-in functions.
  A plugin can furthermore hook into Bro's processing at a number of
  places to add custom logic.

  See https://www.bro.org/sphinx-git/devel/plugins.html for more
  information on writing plugins.

- Bro now has support for the MySQL wire protocol. Activity gets
  logged into mysql.log.

- Bro now parses DTLS traffic. Activity gets logged into ssl.log.

- Bro now has support for the Kerberos KRB5 protocol over TCP and
  UDP. Activity gets logged into kerberos.log.

- Bro now has an RDP analyzer. Activity gets logged into rdp.log.

- Bro now has a file analyzer for Portable Executables. Activity gets
  logged into pe.log.

- Bro now has support for the SIP protocol over UDP. Activity gets
  logged into sip.log.

- Bro now features a completely rewritten, enhanced SSH analyzer.  The
  new analyzer is able to determine if logins failed or succeeded in
  most circumstances, logs a lot more information about SSH
  sessions, supports v1, and introduces the intelligence type
  ``Intel::PUBKEY_HASH`` and location ``SSH::IN_SERVER_HOST_KEY``. The
  analyzer also generates a set of additional events
  (``ssh_auth_successful``, ``ssh_auth_failed``, ``ssh_auth_attempted``,
  ``ssh_auth_result``, ``ssh_capabilities``, ``ssh2_server_host_key``,
  ``ssh1_server_host_key``, ``ssh_encrypted_packet``,
  ``ssh2_dh_server_params``, ``ssh2_gss_error``, ``ssh2_ecc_key``). See
  next section for incompatible SSH changes.

- Bro's file analysis now supports reassembly of files that are not
  transferred/seen sequentially.  The default file reassembly buffer
  size is set with the ``Files::reassembly_buffer_size`` variable.

- Bro's file type identification has been greatly improved (new file types,
  bug fixes, and performance improvements).

- Bro's scripting language now has a ``while`` statement::

        while ( i < 5 )
            print ++i;

  ``next`` and ``break`` can be used inside the loop's body just like
  with ``for`` loops.

- Bro now integrates Broker, a new communication library. See
  aux/broker/README for more information on Broker, and
  doc/frameworks/broker.rst for the corresponding Bro script API.

  With Broker, Bro has the similar capabilities of exchanging events and
  logs with remote peers (either another Bro process or some other
  application that uses Broker).  It also includes a key-value store
  API that can be used to share state between peers and optionally
  allow data to persist on disk for longer-term storage.

  Broker support is by default off for now; it can be enabled at
  configure time with --enable-broker. It requires CAF version 0.13+
  (https://github.com/actor-framework/actor-framework) as well as a
  C++11 compiler (e.g. GCC 4.8+ or Clang 3.3+).

  Broker will become a mandatory dependency in future Bro versions and
  replace the current communication and serialization system.

- Add --enable-c++11 configure flag to compile Bro's source code in
  C++11 mode with a corresponding compiler. Note that 2.4 will be the
  last version of Bro that compiles without C++11 support.

- The SSL analysis now alerts when encountering SSL connections with
  old protocol versions or unsafe cipher suites. It also gained
  extended reporting of weak keys, caching of already validated
  certificates, and full support for TLS record defragmentation. SSL generally
  became much more robust and added several fields to ssl.log (while
  removing some others).

- A new icmp_sent_payload event provides access to ICMP payload.

- The input framework's raw reader now supports seeking by adding an
  option "offset" to the config map. Positive offsets are interpreted
  to be from the beginning of the file, negative from the end of the
  file (-1 is end of file).

- One can now raise events when a connection crosses a given size
  threshold in terms of packets or bytes. The primary API for that
  functionality is in base/protocols/conn/thresholds.bro.

- There is a new command-line option -Q/--time that prints Bro's execution
  time and memory usage to stderr.

- BroControl now has a new command "deploy" which is equivalent to running
  the "check", "install", "stop", and "start" commands (in that order).

- BroControl now has a new option "StatusCmdShowAll" that controls whether
  or not the broctl "status" command gathers all of the status information.
  This option can be used to make the "status" command run significantly
  faster (in this case, the "Peers" column will not be shown in the output).

- BroControl now has a new option "StatsLogEnable" that controls whether
  or not broctl will record information to the "stats.log" file.  This option
  can be used to make the "broctl cron" command run slightly faster (in this
  case, "broctl cron" will also no longer send email about not seeing any
  packets on the monitoring interfaces).

- BroControl now has a new option "MailHostUpDown" which controls whether or
  not the "broctl cron" command will send email when it notices that a host
  in the cluster is up or down.

- BroControl now has a new option "CommandTimeout" which specifies the number
  of seconds to wait for a command that broctl ran to return results.

Changed Functionality
---------------------

- bro-cut has been rewritten in C, and is hence much faster.

- File analysis

    * Removed ``fa_file`` record's ``mime_type`` and ``mime_types``
      fields.  The event ``file_sniff`` has been added which provides
      the same information.  The ``mime_type`` field of ``Files::Info``
      also still has this info.

    * The earliest point that new mime type information is available is
      in the ``file_sniff`` event which comes after the ``file_new`` and
      ``file_over_new_connection`` events.  Scripts which inspected mime
      type info within those events will need to be adapted.  (Note: for
      users that worked w/ versions of Bro from git, for a while there was
      also an event called ``file_mime_type`` which is now replaced with
      the ``file_sniff`` event).

    * Removed ``Files::add_analyzers_for_mime_type`` function.

    * Removed ``offset`` parameter of the ``file_extraction_limit``
      event.  Since file extraction now internally depends on file
      reassembly for non-sequential files, "offset" can be obtained
      with other information already available -- adding together
      ``seen_bytes`` and ``missed_bytes`` fields of the ``fa_file``
      record gives how many bytes have been written so far (i.e.
      the "offset").

- The SSH changes come with a few incompatibilities. The following
  events have been renamed:

    * ``SSH::heuristic_failed_login`` to ``ssh_auth_failed``
    * ``SSH::heuristic_successful_login`` to ``ssh_auth_successful``

  The ``SSH::Info`` status field has been removed and replaced with
  the ``auth_success`` field.  This field has been changed from a
  string that was previously ``success``, ``failure`` or
  ``undetermined`` to a boolean. a boolean that is ``T``, ``F``, or
  unset.

- The has_valid_octets function now uses a string_vec parameter instead of
  string_array.

- conn.log gained a new field local_resp that works like local_orig,
  just for the responder address of the connection.

- GRE tunnels are now identified as ``Tunnel::GRE`` instead of
  ``Tunnel::IP``.

- The default name for extracted files changed from extract-protocol-id
  to extract-timestamp-protocol-id.

- The weird named "unmatched_HTTP_reply" has been removed since it can
  be detected at the script-layer and is handled correctly by the
  default HTTP scripts.

- When adding a logging filter to a stream, the filter can now inherit
  a default ``path`` field from the associated ``Log::Stream`` record.

- When adding a logging filter to a stream, the
  ``Log::default_path_func`` is now only automatically added to the
  filter if it has neither a ``path`` nor a ``path_func`` already
  explicitly set.  Before, the default path function would always be set
  for all filters which didn't specify their own ``path_func``.

- BroControl now establishes only one ssh connection from the manager to
  each remote host in a cluster configuration (previously, there would be
  one ssh connection per remote Bro process).

- BroControl now uses SQLite to record state information instead of a
  plain text file (the file "spool/broctl.dat" is no longer used).
  On FreeBSD, this means that there is a new dependency on the package
  "py27-sqlite3".

- BroControl now records the expected running state of each Bro node right
  before each start or stop.  The "broctl cron" command uses this info to
  either start or stop Bro nodes as needed so that the actual state matches
  the expected state (previously, "broctl cron" could only start nodes in
  the "crashed" state, and could never stop a node).

- BroControl now sends all normal command output (i.e., not error messages)
  to stdout.  Error messages are still sent to stderr, however.

- The capability of processing NetFlow input has been removed for the
  time being.  Therefore, the -y/--flowfile and -Y/--netflow command-line
  options have been removed, and the netflow_v5_header and netflow_v5_record
  events have been removed.

- The -D/--dfa-size command-line option has been removed.

- The -L/--rule-benchmark command-line option has been removed.

- The -O/--optimize command-line option has been removed.

- The deprecated fields "hot" and "addl" have been removed from the
  connection record. Likewise, the functions append_addl() and
  append_addl_marker() have been removed.

- Log files now escape non-printable characters consistently as "\xXX'.
  Furthermore, backslashes are escaped as "\\", making the
  representation fully reversible.

Deprecated Functionality
------------------------

- The split* family of functions are to be replaced with alternate
  versions that return a vector of strings rather than a table of
  strings. This also allows deprecation for some related string
  concatenation/extraction functions. Note that the new functions use
  0-based indexing, rather than 1-based.

  The full list of now deprecated functions is:

    * split: use split_string instead.

    * split1: use split_string1 instead.

    * split_all: use split_string_all instead.

    * split_n: use split_string_n instead.

    * cat_string_array: see join_string_vec instead.

    * cat_string_array_n: see join_string_vec instead.

    * join_string_array: see join_string_vec instead.

    * sort_string_array: use sort instead.

    * find_ip_addresses: use extract_ip_addresses instead.

Bro 2.3
=======

Dependencies
------------

- Libmagic is no longer a dependency.

New Functionality
-----------------

- Support for GRE tunnel decapsulation, including enhanced GRE
  headers. GRE tunnels are treated just like IP-in-IP tunnels by
  parsing past the GRE header in between the delivery and payload IP
  packets.

- The DNS analyzer now actually generates the dns_SRV_reply() event.
  It had been documented before, yet was never raised.

- Bro now uses "file magic signatures" to identify file types. These
  are defined via two new constructs in the signature rule parsing
  grammar: "file-magic" gives a regular expression to match against,
  and "file-mime" gives the MIME type string of content that matches
  the magic and an optional strength value for the match. (See also
  "Changed Functionality" below for changes due to switching from
  using libmagic to such signatures.)

- A new built-in function, "file_magic", can be used to get all file
  magic matches and their corresponding strength against a given chunk
  of data.

- The SSL analyzer now supports heartbeats as well as a few
  extensions, including server_name, alpn, and ec-curves.

- The SSL analyzer comes with Heartbleed detector script in
  protocols/ssl/heartbleed.bro.  Note that loading this script changes
  the default value of "SSL::disable_analyzer_after_detection" from true
  to false to prevent encrypted heartbeats from being ignored.

- StartTLS is now supported for SMTP and POP3.

- The X509 analyzer can now perform OCSP validation.

- Bro now has analyzers for SNMP and Radius, which produce corresponding
  snmp.log and radius.log output (as well as various events of course).

- BroControl has a new option "BroPort" which allows a user to specify
  the starting port number for Bro.

- BroControl has a new option "StatsLogExpireInterval" which allows a
  user to specify when entries in the stats.log file expire.

- BroControl has a new option "PFRINGClusterType" which allows a user
  to specify a PF_RING cluster type.

- BroControl now supports PF_RING+DNA.  There is also a new option
  "PFRINGFirstAppInstance" that allows a user to specify the starting
  application instance number for processes running on a DNA cluster.
  See the BroControl documentation for more details.

- BroControl now warns a user to run "broctl install" if Bro has
  been upgraded or if the broctl or node configuration has changed
  since the most recent install.

Changed Functionality
---------------------

- string slices now exclude the end index (e.g., "123"[1:2] returns
  "2"). Generally, Bro's string slices now behave similar to Python.

- ssl_client_hello() now receives a vector of ciphers, instead of a
  set, to preserve their order.

- Notice::end_suppression() has been removed.

- Bro now parses X.509 extensions headers and, as a result, the
  corresponding event got a new signature:

      event x509_extension(c: connection, is_orig: bool, cert: X509, ext: X509_extension_info);

- In addition, there are several new, more specialized events for a
  number of x509 extensions.

- Generally, all x509 events and handling functions have changed their
  signatures.

- X509 certificate verification now returns the complete certificate
  chain that was used for verification.

- Bro no longer special-cases SYN/FIN/RST-filtered traces by not
  reporting missing data. Instead, if Bro never sees any data segments
  for analyzed TCP connections, the new
  base/misc/find-filtered-trace.bro script will log a warning in
  reporter.log and to stderr.  The old behavior can be reverted by
  redef'ing "detect_filtered_trace".

- We have removed the packet sorter component.

- Bro no longer uses libmagic to identify file types but instead now
  comes with its own signature library (which initially is still
  derived from libmagic's database). This leads to a number of further
  changes with regards to MIME types:

    * The second parameter of the "identify_data" built-in function
      can no longer be used to get verbose file type descriptions,
      though it can still be used to get the strongest matching file
      magic signature.

    * The "file_transferred" event's "descr" parameter no longer
      contains verbose file type descriptions.

    * The BROMAGIC environment variable no longer changes any behavior
      in Bro as magic databases are no longer used/installed.

    * Removed "binary" and "octet-stream" mime type detections. They
      don't provide any more information than an uninitialized
      mime_type field.

    * The "fa_file" record now contains a "mime_types" field that
      contains all magic signatures that matched the file content
      (where the "mime_type" field is just a shortcut for the
      strongest match).

- dns_TXT_reply() now supports more than one string entry by receiving
  a vector of strings.

- BroControl now runs the "exec" and "df" broctl commands only once
  per host, instead of once per Bro node.  The output of these
  commands has been changed slightly to include both the host and
  node names.

- Several performance improvements were made.  Particular emphasis
  was put on the File Analysis system, which generally will now emit
  far fewer file handle request events due to protocol analyzers now
  caching that information internally.

Bro 2.2
=======

New Functionality
-----------------

- A completely overhauled intelligence framework for consuming
  external intelligence data. It provides an abstracted mechanism
  for feeding data into the framework to be matched against the
  data available. It also provides a function named ``Intel::match``
  which makes any hits on intelligence data available to the
  scripting language.

  Using input framework, the intel framework can load data from
  text files. It can also update and add data if changes are
  made to the file being monitored. Files to monitor for
  intelligence can be provided by redef-ing the
  ``Intel::read_files`` variable.

  The intel framework is cluster-ready. On a cluster, the
  manager is the only node that needs to load in data from disk,
  the cluster support will distribute the data across a cluster
  automatically.

  Scripts are provided at ``policy/frameworks/intel/seen`` that
  provide a broad set of sources of data to feed into the intel
  framework to be matched.

- A new file analysis framework moves most of the processing of file
  content from script-land into the core, where it belongs. See
  ``doc/file-analysis.rst``, or the online documentation, for more
  information.

  Much of this is an internal change, but the framework also comes
  with the following user-visible functionality (some of that was
  already available before but is done differently, and more
  efficiently, now):

      - HTTP:

        * Identify MIME type of messages.
        * Extract messages to disk.
        * Compute MD5 for messages.

      - SMTP:

        * Identify MIME type of messages.
        * Extract messages to disk.
        * Compute MD5 for messages.
        * Provide access to start of entity data.

      - FTP data transfers:

        * Identify MIME types of data.
        * Record to disk.

      - IRC DCC transfers: Record to disk.

      - Support for analyzing data transferred via HTTP range requests.

      - A binary input reader interfaces the input framework with the
        file analysis, allowing to inject files on disk into Bro's
        content processing.

- A new framework for computing a wide array of summary statistics,
  such as counters and thresholds checks, standard deviation and mean,
  set cardinality, top K, and more. The framework operates in
  real-time, independent of the underlying data, and can aggregate
  information from many independent monitoring points (including
  clusters). It provides a transparent, easy-to-use user interface,
  and can optionally deploy a set of probabilistic data structures for
  memory-efficient operation. The framework is located in
  ``scripts/base/frameworks/sumstats``.

  A number of new applications now ship with Bro that are built on top
  of the summary statistics framework:

    * Scan detection: Detectors for port and address scans. See
      ``policy/misc/scan.bro`` (these scan detectors used to exist in
      Bro versions <2.0; it's now back, but quite different).

    * Tracerouter detector: ``policy/misc/detect-traceroute.bro``

    * Web application detection/measurement:
      ``policy/misc/app-stats/*``

    * FTP and SSH brute-forcing detector:
      ``policy/protocols/ftp/detect-bruteforcing.bro``,
      ``policy/protocols/ssh/detect-bruteforcing.bro``

    * HTTP-based SQL injection detector:
      ``policy/protocols/http/detect-sqli.bro`` (existed before, but
      now ported to the new framework)

- GridFTP support. This is an extension to the standard FTP analyzer
  and includes:

      - An analyzer for the GSI mechanism of GSSAPI FTP AUTH method.
        GSI authentication involves an encoded TLS/SSL handshake over
        the FTP control session. For FTP sessions that attempt GSI
        authentication, the ``service`` field of the connection log
        will include ``gridftp`` (as well as also ``ftp`` and
        ``ssl``).

      - An example of a GridFTP data channel detection script. It
        relies on the heuristics of GridFTP data channels commonly
        default to SSL mutual authentication with a NULL bulk cipher
        and that they usually transfer large datasets (default
        threshold of script is 1 GB). For identified GridFTP data
        channels, the ``services`` fields of the connection log will
        include ``gridftp-data``.

- Modbus and DNP3 support. Script-level support is only basic at this
  point but see ``src/analyzer/protocol/{modbus,dnp3}/events.bif``, or
  the online documentation, for the events Bro generates. For Modbus,
  there are also some example policies in
  ``policy/protocols/modbus/*``.

- The documentation now includes a new introduction to writing Bro
  scripts. See ``doc/scripting/index.rst`` or, much better, the online
  version. There's also the beginning of a chapter on "Using Bro" in
  ``doc/using/index.rst``.

- GPRS Tunnelling Protocol (GTPv1) decapsulation.

- The scripting language now provide "hooks", a new flavor of
  functions that share characteristics of both standard functions and
  events. They are like events in that multiple bodies can be defined
  for the same hook identifier. They are more like functions in the
  way they are invoked/called, because, unlike events, their execution
  is immediate and they do not get scheduled through an event queue.
  Also, a unique feature of a hook is that a given hook handler body
  can short-circuit the execution of remaining hook handlers simply by
  exiting from the body as a result of a ``break`` statement (as
  opposed to a ``return`` or just reaching the end of the body). See
  ``doc/scripts/builtins.rst``, or the online documentation, for more
  information.

- Bro's language now has a working ``switch`` statement that generally
  behaves like C-style switches (except that case labels can be
  comprised of multiple literal constants delimited by commas).  Only
  atomic types are allowed for now.  Case label bodies that don't
  execute a ``return`` or ``break`` statement will fall through to
  subsequent cases. A ``default`` case label is supported.

- Bro's language now has a new set of types ``opaque of X``. Opaque
  values can be passed around like other values but they can only be
  manipulated with BiF functions, not with other operators. Currently,
  the following opaque types are supported::

        opaque of md5
        opaque of sha1
        opaque of sha256
        opaque of cardinality
        opaque of topk
        opaque of bloomfilter

  These go along with the corresponding BiF functions ``md5_*``,
  ``sha1_*``, ``sha256_*``, ``entropy_*``, etc. . Note that where
  these functions existed before, they have changed their signatures
  to work with opaques types rather than global state.

- The scripting language now supports constructing sets, tables,
  vectors, and records by name::

        type MyRecordType: record {
            c: count;
            s: string &optional;
        };

        global r: MyRecordType = record($c = 7);

        type MySet: set[MyRec];
        global s = MySet([$c=1], [$c=2]);

- Strings now support the subscript operator to extract individual
  characters and substrings (e.g., ``s[4]``, ``s[1:5]``). The index
  expression can take up to two indices for the start and end index of
  the substring to return (e.g. ``mystring[1:3]``).

- Functions now support default parameters, e.g.::

      global foo: function(s: string, t: string &default="abc", u: count &default=0);

- Scripts can now use two new "magic constants" ``@DIR`` and
  ``@FILENAME`` that expand to the directory path of the current
  script and just the script file name without path, respectively.

- ``ssl.log`` now also records the subject client and issuer
  certificates.

- The ASCII writer can now output CSV files on a per filter basis.

- New SQLite reader and writer plugins for the logging framework allow
  to read/write persistent data from on disk SQLite databases.

- A new packet filter framework supports BPF-based load-balancing,
  shunting, and sampling; plus plugin support to customize filters
  dynamically.

- Bro now provides Bloom filters of two kinds: basic Bloom filters
  supporting membership tests, and counting Bloom filters that track
  the frequency of elements. The corresponding functions are::

    bloomfilter_basic_init(fp: double, capacity: count, name: string &default=""): opaque of bloomfilter
    bloomfilter_basic_init2(k: count, cells: count, name: string &default=""): opaque of bloomfilter
    bloomfilter_counting_init(k: count, cells: count, max: count, name: string &default=""): opaque of bloomfilter
    bloomfilter_add(bf: opaque of bloomfilter, x: any)
    bloomfilter_lookup(bf: opaque of bloomfilter, x: any): count
    bloomfilter_merge(bf1: opaque of bloomfilter, bf2: opaque of bloomfilter): opaque of bloomfilter
    bloomfilter_clear(bf: opaque of bloomfilter)

  See ``src/probabilistic/bloom-filter.bif``, or the online
  documentation, for full documentation.

- Bro now provides a probabilistic data structure for computing
  "top k" elements. The corresponding functions are::

    topk_init(size: count): opaque of topk
    topk_add(handle: opaque of topk, value: any)
    topk_get_top(handle: opaque of topk, k: count)
    topk_count(handle: opaque of topk, value: any): count
    topk_epsilon(handle: opaque of topk, value: any): count
    topk_size(handle: opaque of topk): count
    topk_sum(handle: opaque of topk): count
    topk_merge(handle1: opaque of topk, handle2: opaque of topk)
    topk_merge_prune(handle1: opaque of topk, handle2: opaque of topk)

  See ``src/probabilistic/top-k.bif``, or the online documentation,
  for full documentation.

- Bro now provides a probabilistic data structure for computing set
  cardinality, using the HyperLogLog algorithm.  The corresponding
  functions are::

    hll_cardinality_init(err: double, confidence: double): opaque of cardinality
    hll_cardinality_add(handle: opaque of cardinality, elem: any): bool
    hll_cardinality_merge_into(handle1: opaque of cardinality, handle2: opaque of cardinality): bool
    hll_cardinality_estimate(handle: opaque of cardinality): double
    hll_cardinality_copy(handle: opaque of cardinality): opaque of cardinality

  See ``src/probabilistic/cardinality-counter.bif``, or the online
  documentation, for full documentation.

- ``base/utils/exec.bro`` provides a module to start external
  processes asynchronously and retrieve their output on termination.
  ``base/utils/dir.bro`` uses it to monitor a directory for changes,
  and ``base/utils/active-http.bro`` for providing an interface for
  querying remote web servers.

- BroControl can now pin Bro processes to CPUs on supported platforms:
  To use CPU pinning, a new per-node option ``pin_cpus`` can be
  specified in node.cfg if the OS is either Linux or FreeBSD.

- BroControl now returns useful exit codes.  Most BroControl commands
  return 0 if everything was OK, and 1 otherwise.  However, there are
  a few exceptions.  The "status" and "top" commands return 0 if all Bro
  nodes are running, and 1 if not all nodes are running.  The "cron"
  command always returns 0 (but it still sends email if there were any
  problems).  Any command provided by a plugin always returns 0.

- BroControl now has an option "env_vars" to set Bro environment variables.
  The value of this option is a comma-separated list of environment variable
  assignments (e.g., "VAR1=value, VAR2=another").  The "env_vars" option
  can apply to all Bro nodes (by setting it in broctl.cfg), or can be
  node-specific (by setting it in node.cfg).  Environment variables in
  node.cfg have priority over any specified in broctl.cfg.

- BroControl now supports load balancing with PF_RING while sniffing
  multiple interfaces.  Rather than assigning the same PF_RING cluster ID
  to all workers on a host, cluster ID assignment is now based on which
  interface a worker is sniffing (i.e., all workers on a host that sniff
  the same interface will share a cluster ID).  This is handled by
  BroControl automatically.

- BroControl has several new options:  MailConnectionSummary (for
  disabling the sending of connection summary report emails),
  MailAlarmsInterval (for specifying a different interval to send alarm
  summary emails), CompressCmd (if archived log files will be compressed,
  this specifies the command that will be used to compress them),
  CompressExtension (if archived log files will be compressed, this
  specifies the file extension to use).

- BroControl comes with its own test-suite now. ``make test`` in
  ``aux/broctl`` will run it.

In addition to these, Bro 2.2 comes with a large set of smaller
extensions, tweaks, and fixes across the whole code base, including
most submodules.

Changed Functionality
---------------------

- Previous versions of ``$prefix/share/bro/site/local.bro`` (where
  "$prefix" indicates the installation prefix of Bro), aren't compatible
  with Bro 2.2.  This file won't be overwritten when installing over a
  previous Bro installation to prevent clobbering users' modifications,
  but an example of the new version is located in
  ``$prefix/share/bro/site/local.bro.example``.  So if no modification
  has been done to the previous local.bro, just copy the new example
  version over it, else merge in the differences.  For reference,
  a common error message when attempting to use an outdated local.bro
  looks like::

    fatal error in /usr/local/bro/share/bro/policy/frameworks/software/vulnerable.bro, line 41: BroType::AsRecordType (table/record) (set[record { min:record { major:count; minor:count; minor2:count; minor3:count; addl:string; }; max:record { major:count; minor:count; minor2:count; minor3:count; addl:string; }; }])

- The type of ``Software::vulnerable_versions`` changed to allow
  more flexibility and range specifications.  An example usage:

  .. code:: bro

        const java_1_6_vuln = Software::VulnerableVersionRange(
            $max = Software::Version($major = 1, $minor = 6, $minor2 = 0, $minor3 = 44)
        );

        const java_1_7_vuln = Software::VulnerableVersionRange(
            $min = Software::Version($major = 1, $minor = 7),
            $max = Software::Version($major = 1, $minor = 7, $minor2 = 0, $minor3 = 20)
        );

        redef Software::vulnerable_versions += {
            ["Java"] = set(java_1_6_vuln, java_1_7_vuln)
        };

- The interface to extracting content from application-layer protocols
  (including HTTP, SMTP, FTP) has changed significantly due to the
  introduction of the new file analysis framework (see above).

- Removed the following, already deprecated, functionality:

    * Scripting language:
        - ``&disable_print_hook attribute``.

    * BiF functions:
        - ``parse_dotted_addr()``, ``dump_config()``,
          ``make_connection_persistent()``, ``generate_idmef()``,
          ``split_complete()``

        - ``md5_*``, ``sha1_*``, ``sha256_*``, and ``entropy_*`` have
          all changed their signatures to work with opaque types (see
          above).

- Removed a now unused argument from ``do_split`` helper function.

- ``this`` is no longer a reserved keyword.

- The Input Framework's ``update_finished`` event has been renamed to
  ``end_of_data``. It will now not only fire after table-reads have
  been completed, but also after the last event of a whole-file-read
  (or whole-db-read, etc.).

- Renamed the option defining the frequency of alarm summary mails to
  ``Logging::default_alarm_mail_interval``. When using BroControl, the
  value can now be set with the new broctl.cfg option
  ``MailAlarmsInterval``.

- We have completely rewritten the ``notice_policy`` mechanism. It now
  no longer uses a record of policy items but a ``hook``, a new
  language element that's roughly equivalent to a function with
  multiple bodies (see above). For existing code, the two main changes
  are:

    - What used to be a ``redef`` of ``Notice::policy`` now becomes a
      hook implementation. Example:

      Old::

        redef Notice::policy += {
            [$pred(n: Notice::Info) = {
                return n$note == SSH::Login && n$id$resp_h == 10.0.0.1;
                },
            $action = Notice::ACTION_EMAIL]
            };

      New::

        hook Notice::policy(n: Notice::Info)
            {
            if ( n$note == SSH::Login && n$id$resp_h == 10.0.0.1 )
                add n$actions[Notice::ACTION_EMAIL];
            }

    - notice() is now likewise a hook, no longer an event. If you
      have handlers for that event, you'll likely just need to change
      the type accordingly. Example:

      Old::

        event notice(n: Notice::Info) { ... }

      New::

        hook notice(n: Notice::Info) { ... }

- The ``notice_policy.log`` is gone. That's a result of the new notice
  policy setup.

- Removed the ``byte_len()`` and ``length()`` bif functions. Use the
  ``|...|`` operator instead.

- The ``SSH::Login`` notice has been superseded by an corresponding
  intelligence framework observation (``SSH::SUCCESSFUL_LOGIN``).

- ``PacketFilter::all_packets`` has been replaced with
  ``PacketFilter::enable_auto_protocol_capture_filters``.

- We removed the BitTorrent DPD signatures pending further updates to
  that analyzer.

- In previous versions of BroControl, running "broctl cron" would create
  a file ``$prefix/logs/stats/www`` (where "$prefix" indicates the
  installation prefix of Bro).  Now, it is created as a directory.
  Therefore, if you perform an upgrade install and you're using BroControl,
  then you may see an email (generated by "broctl cron") containing an
  error message:  "error running update-stats".  To fix this problem,
  either remove that file (it is not needed) or rename it.

- Due to lack of maintenance the Ruby bindings for Broccoli are now
  deprecated, and the build process no longer includes them by
  default. For the time being, they can still be enabled by
  configuring with ``--enable-ruby``, however we plan to remove
  Broccoli's Ruby support with the next Bro release.

Bro 2.1
=======

New Functionality
-----------------

- Bro now comes with extensive IPv6 support. Past versions offered
  only basic IPv6 functionality that was rarely used in practice as it
  had to be enabled explicitly. IPv6 support is now fully integrated
  into all parts of Bro including protocol analysis and the scripting
  language. It's on by default and no longer requires any special
  configuration.

  Some of the most significant enhancements include support for IPv6
  fragment reassembly, support for following IPv6 extension header
  chains, and support for tunnel decapsulation (6to4 and Teredo). The
  DNS analyzer now handles AAAA records properly, and DNS lookups that
  Bro itself performs now include AAAA queries, so that, for example,
  the result returned by script-level lookups is a set that can
  contain both IPv4 and IPv6 addresses. Support for the most common
  ICMPv6 message types has been added. Also, the FTP EPSV and EPRT
  commands are now handled properly. Internally, the way IP addresses
  are stored has been improved, so Bro can handle both IPv4
  and IPv6 by default without any special configuration.

  In addition to Bro itself, the other Bro components have also been
  made IPv6-aware by default. In particular, significant changes were
  made to trace-summary, PySubnetTree, and Broccoli to support IPv6.

- Bro now decapsulates tunnels via its new tunnel framework located in
  scripts/base/frameworks/tunnels. It currently supports Teredo,
  AYIYA, IP-in-IP (both IPv4 and IPv6), and SOCKS. For all these, it
  logs the outer tunnel connections in both conn.log and tunnel.log,
  and then proceeds to analyze the inner payload as if it were not
  tunneled, including also logging that session in conn.log. For
  SOCKS, it generates a new socks.log in addition with more
  information.

- Bro now features a flexible input framework that allows users to
  integrate external information in real-time into Bro while it's
  processing network traffic. The most direct use-case at the moment
  is reading data from ASCII files into Bro tables, with updates
  picked up automatically when the file changes during runtime. See
  doc/input.rst for more information.

  Internally, the input framework is structured around the notion of
  "reader plugins" that make it easy to interface to different data
  sources. We will add more in the future.

- BroControl now has built-in support for host-based load-balancing
  when using either PF_RING, Myricom cards, or individual interfaces.
  Instead of adding a separate worker entry in node.cfg for each Bro
  worker process on each worker host, it is now possible to just
  specify the number of worker processes on each host and BroControl
  configures everything correctly (including any necessary environment
  variables for the balancers).

  This change adds three new keywords to the node.cfg file (to be used
  with worker entries): lb_procs (specifies number of workers on a
  host), lb_method (specifies what type of load balancing to use:
  pf_ring, myricom, or interfaces), and lb_interfaces (used only with
  "lb_method=interfaces" to specify which interfaces to load-balance
  on).

- Bro's default ASCII log format is not exactly the most efficient way
  for storing and searching large volumes of data. An alternatives,
  Bro now comes with experimental support for two alternative output
  formats:

    * DataSeries: an efficient binary format for recording structured
      bulk data. DataSeries is developed and maintained at HP Labs.
      See doc/logging-dataseries for more information.

    * ElasticSearch: a distributed RESTful, storage engine and search
      engine built on top of Apache Lucene. It scales very well, both
      for distributed indexing and distributed searching. See
      doc/logging-elasticsearch.rst for more information.

  Note that at this point, we consider Bro's support for these two
  formats as prototypes for collecting experience with alternative
  outputs. We do not yet recommend them for production (but welcome
  feedback!)


Changed Functionality
---------------------

The following summarizes the most important differences in existing
functionality. Note that this list is not complete, see CHANGES for
the full set.

- Changes in dependencies:

    * Bro now requires CMake >= 2.6.3.

    * On Linux, Bro now links in tcmalloc (part of Google perftools)
      if found at configure time. Doing so can significantly improve
      memory and CPU use.

      On the other platforms, the new configure option
      --enable-perftools can be used to enable linking to tcmalloc.
      (Note that perftools's support for non-Linux platforms may be
      less reliable).

- The configure switch --enable-brov6 is gone.

- DNS name lookups performed by Bro now also query AAAA records. The
  results of the A and AAAA queries for a given hostname are combined
  such that at the scripting layer, the name resolution can yield a
  set with both IPv4 and IPv6 addresses.

- The connection compressor was already deprecated in 2.0 and has now
  been removed from the code base.

- We removed the "match" statement, which was no longer used by any of
  the default scripts, nor was it likely to be used by anybody anytime
  soon. With that, "match" and "using" are no longer reserved keywords.

- The syntax for IPv6 literals changed from "2607:f8b0:4009:802::1012"
  to "[2607:f8b0:4009:802::1012]". When an IP address variable or IP
  address literal is enclosed in pipes (for example,
  ``|[fe80::db15]|``) the result is now the size of the address in
  bits (32 for IPv4 and 128 for IPv6).

- Bro now spawns threads for doing its logging. From a user's
  perspective not much should change, except that the OS may now show
  a bunch of Bro threads.

- We renamed the configure option --enable-perftools to
  --enable-perftools-debug to indicate that the switch is only relevant
  for debugging the heap.

- Bro's ICMP analyzer now handles both IPv4 and IPv6 messages with a
  joint set of events.  The `icmp_conn` record got a new boolean field
  'v6' that indicates whether the ICMP message is v4 or v6.

- Log postprocessor scripts get an additional argument indicating the
  type of the log writer in use (e.g., "ascii").

- BroControl's make-archive-name script also receives the writer
  type, but as its 2nd(!) argument. If you're using a custom version
  of that script, you need to adapt it. See the shipped version for
  details.

- Signature files can now be loaded via the new "@load-sigs"
  directive. In contrast to the existing (and still supported)
  signature_files constant, this can be used to load signatures
  relative to the current script (e.g., "@load-sigs ./foo.sig").

- The options "tunnel_port" and "parse_udp_tunnels" have been removed.
  Bro now supports decapsulating tunnels directly for protocols it
  understands.

- ASCII logs now record the time when they were opened/closed at the
  beginning and end of the file, respectively (wall clock). The
  options LogAscii::header_prefix and LogAscii::include_header have
  been renamed to LogAscii::meta_prefix and LogAscii::include_meta,
  respectively.

- The ASCII writers "header_*" options have been renamed to "meta_*"
  (because there's now also a footer).

- Some built-in functions have been removed: "addr_to_count" (use
  "addr_to_counts" instead), "bro_has_ipv6" (this is no longer
  relevant because Bro now always supports IPv6), "active_connection"
  (use "connection_exists" instead), and "connection_record" (use
  "lookup_connection" instead).

- The "NFS3::mode2string" built-in function has been renamed to
  "file_mode".

- Some built-in functions have been changed: "exit" (now takes the
  exit code as a parameter), "to_port" (now takes a string as
  parameter instead of a count and transport protocol, but
  "count_to_port" is still available), "connect" (now takes an
  additional string parameter specifying the zone of a non-global IPv6
  address), and "listen" (now takes three additional parameters to
  enable listening on IPv6 addresses).

- Some Bro script variables have been renamed:
  "LogAscii::header_prefix" has been renamed to
  "LogAscii::meta_prefix", "LogAscii::include_header" has been renamed
  to "LogAscii::include_meta".

- Some Bro script variables have been removed: "tunnel_port",
  "parse_udp_tunnels", "use_connection_compressor",
  "cc_handle_resets", "cc_handle_only_syns", and
  "cc_instantiate_on_data".

- A couple events have changed: the "icmp_redirect" event now includes
  the target and destination addresses and any Neighbor Discovery
  options in the message, and the last parameter of the
  "dns_AAAA_reply" event has been removed because it was unused.

- The format of the ASCII log files has changed very slightly.  Two
  new lines are automatically added, one to record the time when the
  log was opened, and the other to record the time when the log was
  closed.

- In BroControl, the option (in broctl.cfg) "CFlowAddr" was renamed to
  "CFlowAddress".


Bro 2.0
=======

As the version number jump from 1.5 suggests, Bro 2.0 is a major
upgrade and lots of things have changed. Most importantly, we have
rewritten almost all of Bro's default scripts from scratch, using
quite different structure now and focusing more on operational
deployment. The result is a system that works much better "out of the
box", even without much initial site-specific configuration. The
down-side is that 1.x configurations will need to be adapted to work
with the new version. The two rules of thumb are:

    (1) If you have written your own Bro scripts
        that do not depend on any of the standard scripts formerly
        found in ``policy/``, they will most likely just keep working
        (although you might want to adapt them to use some of the new
        features, like the new logging framework; see below).

    (2) If you have custom code that depends on specifics of 1.x
        default scripts (including most configuration tuning), that is
        unlikely to work with 2.x. We recommend to start by using just
        the new scripts first, and then port over any customizations
        incrementally as necessary (they may be much easier to do now,
        or even unnecessary). Send mail to the Bro user mailing list
        if you need help.

Below we summarize changes from 1.x to 2.x in more detail. This list
isn't complete, see the ``CHANGES`` file in the distribution.
for the full story.

Script Organization
-------------------

In versions before 2.0, Bro scripts were all maintained in a flat
directory called ``policy/`` in the source tree.  This directory is now
renamed to ``scripts/`` and contains major subdirectories ``base/``,
``policy/``, and ``site/``, each of which may also be subdivided
further.

The contents of the new ``scripts/`` directory, like the old/flat
``policy/`` still gets installed under the ``share/bro``
subdirectory of the installation prefix path just like previous
versions.  For example, if Bro was compiled like ``./configure
--prefix=/usr/local/bro && make && make install``, then the script
hierarchy can be found in ``/usr/local/bro/share/bro``.

The main
subdirectories of that hierarchy are as follows:

- ``base/`` contains all scripts that are loaded by Bro by default
  (unless the ``-b`` command line option is used to run Bro in a
  minimal configuration). Note that is a major conceptual change:
  rather than not loading anything by default, Bro now uses an
  extensive set of default scripts out of the box.

  The scripts under this directory generally either accumulate/log
  useful state/protocol information for monitored traffic, configure a
  default/recommended mode of operation, or provide extra Bro
  scripting-layer functionality that has no significant performance cost.

- ``policy/`` contains all scripts that a user will need to explicitly
  tell Bro to load.  These are scripts that implement
  functionality/analysis that not all users may want to use and may have
  more significant performance costs. For a new installation, you
  should go through these and see what appears useful to load.

- ``site/`` remains a directory that can be used to store locally
  developed scripts. It now comes with some preinstalled example
  scripts that contain recommended default configurations going beyond
  the ``base/`` setup. E.g. ``local.bro`` loads extra scripts from
  ``policy/`` and does extra tuning. These files can be customized in
  place without being overwritten by upgrades/reinstalls, unlike
  scripts in other directories.

With version 2.0, the default ``BROPATH`` is set to automatically
search for scripts in ``policy/``, ``site/`` and their parent
directory, but **not** ``base/``.  Generally, everything under
``base/`` is loaded automatically, but for users of the ``-b`` option,
it's important to know that loading a script in that directory
requires the extra ``base/`` path qualification.  For example, the
following two scripts:

* ``$PREFIX/share/bro/base/protocols/ssl/main.bro``
* ``$PREFIX/share/bro/policy/protocols/ssl/validate-certs.bro``

are referenced from another Bro script like:

.. code:: bro

    @load base/protocols/ssl/main
    @load protocols/ssl/validate-certs

Notice how ``policy/`` can be omitted as a convenience in the second
case. ``@load`` can now also use relative path, e.g., ``@load
../main``.


Logging Framework
-----------------

- The logs generated by scripts that ship with Bro are entirely redone
  to use a standardized, machine parsable format via the new logging
  framework. Generally, the log content has been restructured towards
  making it more directly useful to operations. Also, several
  analyzers have been significantly extended and thus now log more
  information. Take a look at ``ssl.log``.

  * A particular format change that may be useful to note is that the
    ``conn.log`` ``service`` field is derived from DPD instead of
    well-known ports (while that was already possible in 1.5, it was
    not the default).

  * Also, ``conn.log`` now reports raw number of packets/bytes per
    endpoint.

- The new logging framework makes it possible to extend, customize,
  and filter logs very easily.

- A common pattern found in the new scripts is to store logging stream
  records for protocols inside the ``connection`` records so that
  state can be collected until enough is seen to log a coherent unit
  of information regarding the activity of that connection.  This
  state is now frequently seen/accessible in event handlers, for
  example, like ``c$<protocol>`` where ``<protocol>`` is replaced by
  the name of the protocol.  This field is added to the ``connection``
  record by ``redef``'ing it in a
  ``base/protocols/<protocol>/main.bro`` script.

- The logging code has been rewritten internally, with script-level
  interface and output backend now clearly separated. While ASCII
  logging is still the default, we will add further output types in
  the future (binary format, direct database logging).


Notice Framework
----------------

The way users interact with "notices" has changed significantly in order
to make it easier to define a site policy and more extensible for adding
customized actions.


New Default Settings
--------------------

- Dynamic Protocol Detection (DPD) is now enabled/loaded by default.

- The default packet filter now examines all packets instead of
  dynamically building a filter based on which protocol analysis scripts
  are loaded. See ``PacketFilter::all_packets`` for how to revert to old
  behavior.

API Changes
-----------

- The ``@prefixes`` directive works differently now.
  Any added prefixes are now searched for and loaded *after* all input
  files have been parsed.  After all input files are parsed, Bro
  searches ``BROPATH`` for prefixed, flattened versions of all of the
  parsed input files.  For example, if ``lcl`` is in ``@prefixes``, and
  ``site.bro`` is loaded, then a file named ``lcl.site.bro`` that's in
  ``BROPATH`` would end up being automatically loaded as well.  Packages
  work similarly, e.g. loading ``protocols/http`` means a file named
  ``lcl.protocols.http.bro`` in ``BROPATH`` gets loaded automatically.

- The ``make_addr`` BIF now returns a ``subnet`` versus an ``addr``


Variable Naming
---------------

- ``Module`` is more widely used for namespacing. E.g. the new
  ``site.bro`` exports the ``local_nets`` identifier (among other
  things) into the ``Site`` module.

- Identifiers may have been renamed to conform to new `scripting
  conventions
  <http://www.bro.org/development/howtos/script-conventions.html>`_


Removed Functionality
---------------------

We have remove a bunch of functionality that was rarely used and/or
had not been maintained for a while already:

    - The ``net`` script data type.
    - The ``alarm`` statement; use the notice framework instead.
    - Trace rewriting.
    - DFA state expiration in regexp engine.
    - Active mapping.
    - Native DAG support (may come back eventually)
    - ClamAV support.
    - The connection compressor is now disabled by default, and will
      be removed in the future.

BroControl Changes
------------------

BroControl looks pretty much similar to the version coming with Bro 1.x,
but has been cleaned up and streamlined significantly internally.

BroControl has a new ``process`` command to process a trace on disk
offline using a similar configuration to what BroControl installs for
live analysis.

BroControl now has an extensive plugin interface for adding new
commands and options. Note that this is still considered experimental.

We have removed the ``analysis`` command, and BroControl currently
does not send daily alarm summaries anymore (this may be restored
later).

Development Infrastructure
--------------------------

Bro development has moved from using SVN to Git for revision control.
Users that want to use the latest Bro development snapshot by checking it out
from the source repositories should see the `development process
<http://www.bro.org/development/process.html>`_. Note that all the various
sub-components now reside in their own repositories. However, the
top-level Bro repository includes them as git submodules so it's easy
to check them all out simultaneously.

Bro now uses `CMake <http://www.cmake.org>`_ for its build system so
that is a new required dependency when building from source.

Bro now comes with a growing suite of regression tests in
``testing/``.
