Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/topic/robin/socket-comm'
Browse files Browse the repository at this point in the history
* origin/topic/robin/socket-comm:
  Support attaching interactive console to a running agent.
  Reformat Zeek scripts with `zeek-script`.
  Fix help message.
  Fix return value of scheduler loop.
  Bump `spdlog`.
  Bump `fmt`.
  • Loading branch information
rsmmr committed Jan 8, 2024
2 parents 7a03127 + f8a284d commit 9a503f3
Show file tree
Hide file tree
Showing 37 changed files with 1,383 additions and 263 deletions.
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Checks: 'bugprone-*,
readability-*,
-bugprone-easily-swappable-parameters,
-bugprone-unchecked-optional-access,
-cert-err58-cpp,
-clang-analyzer-cplusplus.NewDeleteLeaks,
-clang-diagnostic-c++2a-designator,
Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/fmt
Submodule fmt updated 97 files
+8 −0 .github/dependabot.yml
+6 −0 .github/issue_template.md
+3 −2 .github/pull_request_template.md
+30 −0 .github/workflows/cifuzz.yml
+12 −1 .github/workflows/doc.yml
+26 −0 .github/workflows/lint.yml
+42 −10 .github/workflows/linux.yml
+20 −2 .github/workflows/macos.yml
+65 −0 .github/workflows/scorecard.yml
+61 −21 .github/workflows/windows.yml
+13 −26 .gitignore
+120 −77 CMakeLists.txt
+5,533 −0 ChangeLog.md
+0 −4,364 ChangeLog.rst
+1 −1 LICENSE
+490 −0 README.md
+0 −528 README.rst
+11 −2 doc/CMakeLists.txt
+6 −6 doc/_static/bootstrap.min.js
+315 −193 doc/api.rst
+15 −7 doc/build.py
+2 −2 doc/index.rst
+176 −15 doc/syntax.rst
+38 −0 doc/usage.rst
+11 −20 include/fmt/args.h
+635 −394 include/fmt/chrono.h
+142 −137 include/fmt/color.h
+66 −173 include/fmt/compile.h
+1,093 −1,331 include/fmt/core.h
+851 −1,810 include/fmt/format-inl.h
+2,391 −977 include/fmt/format.h
+0 −2 include/fmt/locale.h
+84 −156 include/fmt/os.h
+164 −52 include/fmt/ostream.h
+211 −193 include/fmt/printf.h
+413 −417 include/fmt/ranges.h
+537 −0 include/fmt/std.h
+97 −74 include/fmt/xchar.h
+39 −30 src/fmt.cc
+15 −96 src/format.cc
+121 −80 src/os.cc
+1 −1 support/AndroidManifest.xml
+3 −3 support/Vagrantfile
+0 −43 support/appveyor-build.py
+0 −31 support/appveyor.yml
+0 −1 support/bazel/.bazelrc
+1 −1 support/bazel/.bazelversion
+1 −2 support/bazel/BUILD.bazel
+5 −4 support/bazel/README.md
+1 −1 support/build.gradle
+0 −70 support/cmake/cxx14.cmake
+4 −1 support/cmake/fmt-config.cmake.in
+55 −23 support/manage.py
+1 −1 support/printable.py
+0 −159 support/rst2md.py
+41 −41 test/CMakeLists.txt
+1 −1 test/add-subdirectory-test/CMakeLists.txt
+23 −23 test/args-test.cc
+583 −172 test/chrono-test.cc
+6 −0 test/color-test.cc
+207 −51 test/compile-error-test/CMakeLists.txt
+2 −1 test/compile-fp-test.cc
+40 −39 test/compile-test.cc
+168 −232 test/core-test.cc
+18 −0 test/detect-stdfs.cc
+2 −0 test/enforce-checks-test.cc
+1 −1 test/find-package-test/CMakeLists.txt
+0 −856 test/format
+258 −159 test/format-impl-test.cc
+901 −794 test/format-test.cc
+1 −1 test/fuzzing/CMakeLists.txt
+2 −2 test/fuzzing/one-arg.cc
+2 −2 test/fuzzing/two-args.cc
+4 −2 test/gtest-extra-test.cc
+3 −3 test/gtest-extra.cc
+3 −8 test/gtest-extra.h
+1 −0 test/gtest/CMakeLists.txt
+3 −3 test/gtest/gmock-gtest-all.cc
+2 −2 test/mock-allocator.h
+36 −96 test/module-test.cc
+18 −0 test/noexception-test.cc
+24 −69 test/os-test.cc
+92 −80 test/ostream-test.cc
+3 −90 test/posix-mock-test.cc
+4 −6 test/posix-mock.h
+16 −50 test/printf-test.cc
+266 −53 test/ranges-test.cc
+103 −31 test/scan-test.cc
+560 −135 test/scan.h
+1 −1 test/static-export-test/CMakeLists.txt
+0 −161 test/std-format-test.cc
+306 −0 test/std-test.cc
+2 −3 test/test-main.cc
+4 −4 test/unicode-test.cc
+6 −2 test/util.cc
+15 −17 test/util.h
+246 −119 test/xchar-test.cc
2 changes: 1 addition & 1 deletion 3rdparty/spdlog
Submodule spdlog updated 107 files
34 changes: 34 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
2.3.0-dev.78 | 2024-01-08 10:25:51 +0100

* GH-8: Support attaching interactive console to a running agent.

By default, an agent now creates a UNIX socket for its console that an
external client can connect to. To connect to an already running
agent, execute `zeek-agent -r` on the same machine (note that client
and server must be running as the same user, probably `root`). Client
and server can specify a different socket path through `-s <PATH>`.
The environment variable `ZEEK_AGENT_SOCKET` can be set to specify the
path as well.

Remote consoles aren't support on Windows yet.

Internally, we switch the classic local console over to the same IPC
mechanism we now use for remote consoles, so that there's only one
implementation. For Windows, where actual IPC isn't implemented yet,
we provide a dummy implementation for this purpose that just forwards
data inside the main (and only) process.

Note: This has a known issue on Windows where the local console
stops taking input after the first command. That remains to be
fixed.

* Reformat Zeek scripts with `zeek-script`.

* Fix help message.

* Fix return value of scheduler loop.

* Bump `spdlog`.

* Bump `fmt`.

2.3.0-dev.71 | 2023-12-20 12:11:13 +0100

* Notarization updates and fixes. We now use Apple's new
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.3.0-dev.71
2.3.0-dev.78
47 changes: 38 additions & 9 deletions src/core/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,46 @@
#include <toml++/toml.h>

#ifndef NDEBUG
#define LOG_LEVEL_HELP "info,warning,error,critical"
#else
#define LOG_LEVEL_HELP "trace,debug,info,warning,error,critical"
#else
#define LOG_LEVEL_HELP "info,warning,error,critical"
#endif

using namespace zeek::agent;

options::LogLevel options::default_log_level = options::LogLevel::info;
options::LogType options::default_log_type = options::LogType::Stdout;
filesystem::path options::default_log_path = {};
filesystem::path options::default_socket_file_name = "zeek-agent.$$.sock";

static struct option long_driver_options[] = {
// clang-format off
{"autodoc", no_argument, nullptr, 'D'},
{"config", required_argument, nullptr, 'c'},
{"execute", required_argument, nullptr, 'e'},
{"help", no_argument, nullptr, 'h'},
{"interactive", no_argument, nullptr, 'i'},
{"log-level", required_argument, nullptr, 'L'},
{"autodoc", no_argument, nullptr, 'D'},
{"remote", no_argument, nullptr, 'r'},
{"socket", no_argument, nullptr, 's'},
{"terminate-on-disconnect", no_argument, nullptr, 'N'},
{"test", no_argument, nullptr, 'T'},
{"use-mock-data", no_argument, nullptr, 'M'},
{"terminate-on-disconnect", no_argument, nullptr, 'N'},
{"zeek", required_argument, nullptr, 'z'},
{"version", no_argument, nullptr, 'v'},
{"zeek", required_argument, nullptr, 'z'},
{nullptr, 0, nullptr, 0}
// clang-format on
};

static void usage(const filesystem::path& name) {
auto cfg = platform::configurationFile() ? platform::configurationFile()->string() : std::string("n/a");

auto options = Options::default_();
std::string socket = "n/a";

if ( options.socket )
socket = options.socket->string();

// clang-format off
std::cerr << "\nUsage: " << name.filename().string() << frmt(
" [options]\n"
Expand All @@ -74,12 +83,14 @@ static void usage(const filesystem::path& name) {
" -N | --terminate-on-disconnect Terminate when remote side disconnects (for testing)\n"
" -T | --test Run unit tests and exit\n"
" -c | --config <FILE> Load configuration from file [default: {}]\n"
" -e | --execute <STMT> SQL statement to execute immediately, then quit"
" -e | --execute <STMT> SQL statement to execute immediately, then quit\n"
" -h | --help Show usage information\n"
" -i | --interactive Spawn interactive console\n"
" -r | --remote Connect interactive console to already running agent\n"
" -s | --socket <FILE> Specify socket to use for console communication [default: {}]\n"
" -v | --version Print version information\n"
" -z | --zeek <host>[:port] Connect to Zeek at given address\n"
"\n", cfg);
"\n", cfg, socket);
// clang-format on
}

Expand All @@ -101,8 +112,8 @@ Result<Nothing> Options::parseArgv(const std::vector<std::string>& argv) {
#endif

while ( true ) {
int c =
getopt_long(static_cast<int>(argv_.size()), argv_.data(), "DL:MNTc:e:hivz:", long_driver_options, nullptr);
int c = getopt_long(static_cast<int>(argv_.size()), argv_.data(), "DL:MNTc:e:hirs:vz:", long_driver_options,
nullptr);
if ( c < 0 )
return Nothing();

Expand All @@ -129,6 +140,8 @@ Result<Nothing> Options::parseArgv(const std::vector<std::string>& argv) {
case 'c': config_file = optarg; break;
case 'e': execute = optarg; break;
case 'i': interactive = true; break;
case 'r': mode = options::Mode::RemoteConsole; break;
case 's': socket = filesystem::path(optarg); break;
case 'z': zeek_destinations.emplace_back(optarg); break;

case 'v': std::cerr << "Zeek Agent v" << VersionLong << std::endl; exit(0);
Expand All @@ -152,6 +165,7 @@ void Options::debugDump() const {
(log_level ? options::to_string(*log_level) : "<not set>"));
ZEEK_AGENT_DEBUG("configuration", "[option] log.type: {}", (log_type ? to_string(*log_type) : "<not set>"));
ZEEK_AGENT_DEBUG("configuration", "[option] log.path: {}", (log_path ? log_path->string() : "<not set>"));
ZEEK_AGENT_DEBUG("configuration", "[option] socket: {}", (socket ? socket->string() : "<not set>"));
ZEEK_AGENT_DEBUG("configuration", "[option] use-mock-data: {}", use_mock_data);
ZEEK_AGENT_DEBUG("configuration", "[option] terminate-on-disconnect: {}", terminate_on_disconnect);
ZEEK_AGENT_DEBUG("configuration", "[option] zeek.groups: {}", join(zeek_groups, ", "));
Expand Down Expand Up @@ -240,6 +254,21 @@ Options Options::default_() {
if ( path && filesystem::is_regular_file(*path) )
options.config_file = *path;

#ifndef HAVE_WINDOWS
if ( ! options.socket ) {
const char* env = getenv("ZEEK_AGENT_SOCKET");
if ( env && *env )
options.socket = env;
else {
filesystem::path socket_dir = "/tmp";
if ( auto d = platform::dataDirectory() )
socket_dir = *d;

options.socket = socket_dir / replace(options::default_socket_file_name, "$$", frmt("{}", getuid()));
}
}
#endif

return options;
}

Expand Down
21 changes: 17 additions & 4 deletions src/core/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ namespace options {
* couple of special modes beyond normal operation.
**/
enum class Mode {
Standard, /**< normal operation */
Test, /**< run unit tests and exit */
AutoDoc /**< print out JSON describing table schemas and exit */
Standard, /**< normal operation */
RemoteConsole, /**< connect to remote agent */
Test, /**< run unit tests and exit */
AutoDoc /**< print out JSON describing table schemas and exit */
};

inline std::string to_string(options::Mode mode) {
switch ( mode ) {
case options::Mode::RemoteConsole: return "remote console";
case options::Mode::Standard: return "standard";
case options::Mode::Test: return "test";
case options::Mode::AutoDoc: return "autodoc";
Expand Down Expand Up @@ -87,6 +89,7 @@ inline Result<LogType> from_str(const std::string_view& t) {
extern LogLevel default_log_level;
extern LogType default_log_type;
extern filesystem::path default_log_path;
extern filesystem::path default_socket_file_name;

} // namespace options

Expand Down Expand Up @@ -123,9 +126,16 @@ struct Options {
/** Console statement/command to execute at startup, and then terminate */
std::string execute;

/** True to spawn the interactive console */
/** True to spawn the interactive console locally. */
bool interactive = false;

/**
* Set to a socket name to spawn the interactive console connecting to a
* remote agent. If set to an empty path, expect remote at default socket
* location.
*/
std::optional<filesystem::path> interactive_remote;

/** The agent's level of logging. Default is `warn` and worse. */
std::optional<options::LogLevel> log_level;

Expand All @@ -135,6 +145,9 @@ struct Options {
/** File path associated with logger, if current type needs one. */
std::optional<filesystem::path> log_path = {};

/** Default socket for remote console. */
std::optional<filesystem::path> socket;

/** True to have any tables only report mock data for testing. */
bool use_mock_data = false;

Expand Down
2 changes: 1 addition & 1 deletion src/core/scheduler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool Scheduler::Implementation::loop() {
}

advance(std::chrono::system_clock::now());
return _terminating;
return ! _terminating;
}

Scheduler::Scheduler() { ZEEK_AGENT_DEBUG("scheduler", "creating instance"); }
Expand Down
7 changes: 7 additions & 0 deletions src/core/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,3 +552,10 @@ inline auto ValueVectorCompare = [](const std::vector<Value>& a, const std::vect
extern std::pair<Value, value::Type> stringToValue(const std::string& str, value::Type type);

} // namespace zeek::agent

template<>
struct fmt::formatter<zeek::agent::value::Type> : fmt::formatter<std::string> {
auto format(const zeek::agent::value::Type& t, format_context& ctx) const -> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "{}", to_string(t));
}
};
Loading

0 comments on commit 9a503f3

Please sign in to comment.