diff --git a/Cargo.lock b/Cargo.lock index 4a2dbe45d9f..a2ec5c0abf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1232,47 +1232,6 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" -[[package]] -name = "datadog-live-debugger" -version = "0.0.1" -dependencies = [ - "anyhow", - "bytes", - "constcat", - "futures", - "http 1.4.2", - "libdd-capabilities", - "libdd-capabilities-impl", - "libdd-common", - "libdd-data-pipeline", - "libdd-remote-config", - "percent-encoding", - "serde", - "serde_json", - "smallvec", - "strum", - "strum_macros", - "sys-info", - "tokio", - "uuid", -] - -[[package]] -name = "datadog-live-debugger-ffi" -version = "0.0.1" -dependencies = [ - "build_common", - "datadog-live-debugger", - "libdd-common", - "libdd-common-ffi", - "log", - "percent-encoding", - "serde_json", - "tokio", - "tokio-util", - "uuid", -] - [[package]] name = "datadog-php" version = "0.0.1" @@ -1289,8 +1248,6 @@ dependencies = [ "criterion-perf-events", "crossbeam-channel", "dashmap", - "datadog-live-debugger", - "datadog-live-debugger-ffi", "datadog-sidecar", "datadog-sidecar-ffi", "ddtrace-sidecar", @@ -1311,6 +1268,8 @@ dependencies = [ "libdd-ipc", "libdd-library-config", "libdd-library-config-ffi", + "libdd-live-debugger", + "libdd-live-debugger-ffi", "libdd-profiling", "libdd-remote-config", "libdd-telemetry", @@ -1355,7 +1314,6 @@ dependencies = [ "chrono", "console-subscriber", "crossbeam-utils", - "datadog-live-debugger", "datadog-sidecar-macros", "futures", "http 1.4.2", @@ -1373,6 +1331,7 @@ dependencies = [ "libdd-ffe", "libdd-ipc", "libdd-ipc-macros", + "libdd-live-debugger", "libdd-remote-config", "libdd-telemetry", "libdd-tinybytes", @@ -1384,7 +1343,7 @@ dependencies = [ "nix 0.29.0", "prctl", "priority-queue", - "rand 0.8.5", + "rand 0.8.8", "rmp-serde", "sendfd", "serde", @@ -1410,7 +1369,6 @@ dependencies = [ name = "datadog-sidecar-ffi" version = "0.0.1" dependencies = [ - "datadog-live-debugger", "datadog-sidecar", "http 1.4.2", "libc 0.2.186", @@ -1420,6 +1378,7 @@ dependencies = [ "libdd-crashtracker-ffi", "libdd-dogstatsd-client", "libdd-ipc", + "libdd-live-debugger", "libdd-remote-config", "libdd-telemetry", "libdd-telemetry-ffi", @@ -2040,9 +1999,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -2859,7 +2818,7 @@ dependencies = [ [[package]] name = "libdd-capabilities" -version = "3.0.0" +version = "3.0.1" dependencies = [ "anyhow", "bytes", @@ -2871,7 +2830,7 @@ dependencies = [ [[package]] name = "libdd-capabilities-impl" -version = "4.0.0" +version = "5.0.0" dependencies = [ "anyhow", "bytes", @@ -2885,7 +2844,7 @@ dependencies = [ [[package]] name = "libdd-common" -version = "5.2.0" +version = "6.0.0" dependencies = [ "anyhow", "bytes", @@ -2911,7 +2870,7 @@ dependencies = [ "nix 0.29.0", "pin-project", "proptest", - "rand 0.8.5", + "rand 0.8.8", "regex", "regex-lite", "reqwest 0.13.2", @@ -2947,7 +2906,7 @@ dependencies = [ [[package]] name = "libdd-crashtracker" -version = "2.0.1" +version = "3.0.0" dependencies = [ "anyhow", "blazesym", @@ -2972,7 +2931,7 @@ dependencies = [ "os_info", "page_size", "portable-atomic", - "rand 0.8.5", + "rand 0.8.8", "schemars", "serde", "serde_json", @@ -3006,7 +2965,7 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" -version = "9.0.0" +version = "10.0.0" dependencies = [ "anyhow", "arc-swap", @@ -3040,7 +2999,7 @@ dependencies = [ "libdd-trace-stats", "libdd-trace-utils", "prost", - "rand 0.8.5", + "rand 0.8.8", "regex", "rmp-serde", "serde", @@ -3082,13 +3041,13 @@ dependencies = [ "prost", "prost-build", "protoc-bin-vendored", - "rand 0.8.5", + "rand 0.8.8", "rand_chacha 0.3.1", ] [[package]] name = "libdd-dogstatsd-client" -version = "5.0.0" +version = "6.0.0" dependencies = [ "anyhow", "async-trait", @@ -3103,7 +3062,7 @@ dependencies = [ [[package]] name = "libdd-ffe" -version = "1.0.0" +version = "2.0.0" dependencies = [ "bincode", "chrono", @@ -3141,7 +3100,7 @@ dependencies = [ [[package]] name = "libdd-ipc" -version = "1.0.0" +version = "2.0.0" dependencies = [ "anyhow", "bincode", @@ -3174,7 +3133,7 @@ dependencies = [ [[package]] name = "libdd-ipc-macros" -version = "1.0.0" +version = "1.0.1" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3191,7 +3150,7 @@ dependencies = [ "libdd-trace-protobuf", "memfd", "prost", - "rand 0.8.5", + "rand 0.8.8", "rmp", "rmp-serde", "serde", @@ -3224,6 +3183,47 @@ dependencies = [ "paste", ] +[[package]] +name = "libdd-live-debugger" +version = "1.0.0" +dependencies = [ + "anyhow", + "bytes", + "constcat", + "futures", + "http 1.4.2", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", + "libdd-data-pipeline", + "libdd-remote-config", + "percent-encoding", + "serde", + "serde_json", + "smallvec", + "strum", + "strum_macros", + "sys-info", + "tokio", + "uuid", +] + +[[package]] +name = "libdd-live-debugger-ffi" +version = "0.0.1" +dependencies = [ + "build_common", + "libdd-common", + "libdd-common-ffi", + "libdd-live-debugger", + "log", + "percent-encoding", + "serde_json", + "tokio", + "tokio-util", + "uuid", +] + [[package]] name = "libdd-log" version = "1.0.0" @@ -3265,7 +3265,7 @@ dependencies = [ "parking_lot", "proptest", "prost", - "rand 0.8.5", + "rand 0.8.8", "reqwest 0.13.2", "rustc-hash 2.1.3", "rustls", @@ -3293,7 +3293,7 @@ dependencies = [ [[package]] name = "libdd-remote-config" -version = "4.0.0" +version = "5.0.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -3315,7 +3315,7 @@ dependencies = [ "libdd-tuf", "manual_future", "prost", - "rand 0.8.5", + "rand 0.8.8", "ring", "serde", "serde_json", @@ -3333,7 +3333,7 @@ dependencies = [ [[package]] name = "libdd-shared-runtime" -version = "3.0.0" +version = "4.0.0" dependencies = [ "async-trait", "futures", @@ -3349,7 +3349,7 @@ dependencies = [ [[package]] name = "libdd-telemetry" -version = "7.0.0" +version = "8.0.0" dependencies = [ "anyhow", "async-trait", @@ -3398,7 +3398,7 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.2" +version = "1.1.3" dependencies = [ "libdd-tinybytes", "once_cell", @@ -3419,12 +3419,12 @@ dependencies = [ "criterion", "duplicate 0.4.1", "libdd-trace-protobuf", - "rand 0.8.5", + "rand 0.8.8", ] [[package]] name = "libdd-trace-obfuscation" -version = "7.0.0" +version = "8.0.0" dependencies = [ "anyhow", "criterion", @@ -3456,7 +3456,7 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "8.0.0" +version = "9.0.0" dependencies = [ "anyhow", "arc-swap", @@ -3476,7 +3476,7 @@ dependencies = [ "libdd-trace-obfuscation", "libdd-trace-protobuf", "libdd-trace-utils", - "rand 0.8.5", + "rand 0.8.8", "rmp-serde", "serde", "tokio", @@ -3487,7 +3487,7 @@ dependencies = [ [[package]] name = "libdd-trace-utils" -version = "11.0.0" +version = "12.0.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -3515,7 +3515,7 @@ dependencies = [ "libdd-trace-protobuf", "libdd-trace-utils", "prost", - "rand 0.8.5", + "rand 0.8.8", "rmp", "rmp-serde", "rmpv", @@ -4266,7 +4266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d43f3220d96e0080cc9ea234978ccd80d904eafb17be31bb0f76daaea6493082" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand 0.8.8", ] [[package]] @@ -4518,7 +4518,7 @@ dependencies = [ "bitflags 2.13.0", "lazy_static", "num-traits", - "rand 0.8.5", + "rand 0.8.8", "rand_chacha 0.3.1", "rand_xorshift", "regex-syntax", @@ -4729,9 +4729,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc 0.2.186", "rand_chacha 0.3.1", diff --git a/Cargo.toml b/Cargo.toml index b84f097489c..535898d16f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,8 +51,8 @@ libdd-common = { path = "libdatadog/libdd-common", features = ["cgroup_testing"] libdd-common-ffi = { path = "libdatadog/libdd-common-ffi", default-features = false } libdd-telemetry = { path = "libdatadog/libdd-telemetry" } libdd-telemetry-ffi = { path = "libdatadog/libdd-telemetry-ffi", default-features = false } -datadog-live-debugger = { path = "libdatadog/datadog-live-debugger" } -datadog-live-debugger-ffi = { path = "libdatadog/datadog-live-debugger-ffi", default-features = false } +datadog-live-debugger = { package = "libdd-live-debugger", path = "libdatadog/libdd-live-debugger" } +datadog-live-debugger-ffi = { package = "libdd-live-debugger-ffi", path = "libdatadog/libdd-live-debugger-ffi", default-features = false } libdd-ipc = { path = "libdatadog/libdd-ipc" } datadog-ffe = { package = "libdd-ffe", path = "libdatadog/libdd-ffe" } libdd-remote-config = { path = "libdatadog/libdd-remote-config" } diff --git a/appsec/src/extension/commands/client_init.c b/appsec/src/extension/commands/client_init.c index 7bce7ee3792..8b84dd68ce3 100644 --- a/appsec/src/extension/commands/client_init.c +++ b/appsec/src/extension/commands/client_init.c @@ -29,6 +29,7 @@ static const dd_command_spec _spec = { .name = "client_init", .name_len = sizeof("client_init") - 1, .num_args = 8, + .reconnect_sidecar = true, .outgoing_cb = _pack_command, .incoming_cb = _process_response, .config_features_cb = dd_command_process_config_features_unexpected, diff --git a/appsec/src/extension/commands/client_shutdown.c b/appsec/src/extension/commands/client_shutdown.c index e23572e6a14..d8123bd675b 100644 --- a/appsec/src/extension/commands/client_shutdown.c +++ b/appsec/src/extension/commands/client_shutdown.c @@ -19,6 +19,7 @@ static const dd_command_spec _spec = { .name = "client_shutdown", .name_len = sizeof("client_shutdown") - 1, .num_args = 1, + .reconnect_sidecar = false, .outgoing_cb = _pack_command, .incoming_cb = _process_response, .config_features_cb = dd_command_process_config_features_unexpected, diff --git a/appsec/src/extension/commands/config_sync.c b/appsec/src/extension/commands/config_sync.c index 1deed8de41b..685c1316e90 100644 --- a/appsec/src/extension/commands/config_sync.c +++ b/appsec/src/extension/commands/config_sync.c @@ -21,6 +21,7 @@ static const dd_command_spec _spec = { .name = "config_sync", .name_len = sizeof("config_sync") - 1, .num_args = 2, + .reconnect_sidecar = true, .outgoing_cb = _request_pack, .incoming_cb = dd_command_process_config_sync, .config_features_cb = dd_command_process_config_features, diff --git a/appsec/src/extension/commands/request_exec.c b/appsec/src/extension/commands/request_exec.c index aa781d23158..829dcfa6720 100644 --- a/appsec/src/extension/commands/request_exec.c +++ b/appsec/src/extension/commands/request_exec.c @@ -29,6 +29,7 @@ static const dd_command_spec _spec = { .name = "request_exec", .name_len = sizeof("request_exec") - 1, .num_args = 2, + .reconnect_sidecar = true, .outgoing_cb = _pack_command, .incoming_cb = dd_command_proc_resp_verd_span_data, .config_features_cb = dd_command_process_config_features_unexpected, diff --git a/appsec/src/extension/commands/request_init.c b/appsec/src/extension/commands/request_init.c index 7d0124fb10b..adac950b49a 100644 --- a/appsec/src/extension/commands/request_init.c +++ b/appsec/src/extension/commands/request_init.c @@ -37,6 +37,7 @@ static const dd_command_spec _spec = { .name = "request_init", .name_len = sizeof("request_init") - 1, .num_args = 1, // a single map + .reconnect_sidecar = true, .outgoing_cb = _request_pack, .incoming_cb = dd_command_proc_resp_verd_span_data, .config_features_cb = dd_command_process_config_features, diff --git a/appsec/src/extension/commands/request_shutdown.c b/appsec/src/extension/commands/request_shutdown.c index 9b0d2a66f59..1a648d602fe 100644 --- a/appsec/src/extension/commands/request_shutdown.c +++ b/appsec/src/extension/commands/request_shutdown.c @@ -31,6 +31,7 @@ static const dd_command_spec _spec = { .name_len = sizeof("request_shutdown") - 1, .num_args = 4, // a map, api sec sampling key, sidecar queue id, input_truncated + .reconnect_sidecar = false, .outgoing_cb = _request_pack, .incoming_cb = dd_command_proc_resp_verd_span_data, .config_features_cb = dd_command_process_config_features_unexpected, diff --git a/appsec/src/extension/commands_helpers.c b/appsec/src/extension/commands_helpers.c index 60dcbcdc1c9..a92e7fa2ce3 100644 --- a/appsec/src/extension/commands_helpers.c +++ b/appsec/src/extension/commands_helpers.c @@ -41,7 +41,8 @@ typedef struct _dd_imsg { // if and only if this returns success, _imsg_destroy must be called static dd_result ATTR_WARN_UNUSED _imsg_recv(dd_imsg *nonnull imsg, - dd_conn *nonnull conn, dd_mpack_buffer *nonnull buffer); + dd_conn *nonnull conn, dd_mpack_buffer *nonnull buffer, + bool reconnect_sidecar); static inline ATTR_WARN_UNUSED mpack_error_t _imsg_destroy( dd_imsg *nonnull imsg); @@ -84,7 +85,7 @@ static dd_result _dd_command_exec(dd_conn *nonnull conn, } dd_imsg imsg = {0}; - res = _imsg_recv(&imsg, conn, &omsg.buffer); + res = _imsg_recv(&imsg, conn, &omsg.buffer, spec->reconnect_sidecar); _dump_out_msg(dd_log_trace, &omsg.buffer); _omsg_destroy(&omsg); if (res) { @@ -240,12 +241,13 @@ static inline void _omsg_destroy(dd_omsg *nonnull omsg) // incoming static ATTR_WARN_UNUSED dd_result _imsg_recv(dd_imsg *nonnull imsg, - dd_conn *nonnull conn, dd_mpack_buffer *nonnull buffer) + dd_conn *nonnull conn, dd_mpack_buffer *nonnull buffer, + bool reconnect_sidecar) { mlog(dd_log_debug, "Will exchange message with helper"); - dd_result res = dd_conn_roundtrip( - conn, buffer->data, buffer->final_msg_size, &imsg->_response); + dd_result res = dd_conn_roundtrip(conn, buffer->data, + buffer->final_msg_size, reconnect_sidecar, &imsg->_response); if (res) { return res; } diff --git a/appsec/src/extension/commands_helpers.h b/appsec/src/extension/commands_helpers.h index c24f18468bc..3fc60956840 100644 --- a/appsec/src/extension/commands_helpers.h +++ b/appsec/src/extension/commands_helpers.h @@ -15,6 +15,8 @@ typedef struct _dd_command_spec { const char *nonnull name; size_t name_len; size_t num_args; // outgoing args + // Whether a failed exchange may reconnect to the sidecar and try again. + bool reconnect_sidecar; dd_result (*nonnull outgoing_cb)( mpack_writer_t *nonnull writer, void *unspecnull ctx); dd_result (*nonnull incoming_cb)(mpack_node_t root, void *unspecnull ctx); diff --git a/appsec/src/extension/ddappsec.c b/appsec/src/extension/ddappsec.c index 6690028b032..672f6f7d416 100644 --- a/appsec/src/extension/ddappsec.c +++ b/appsec/src/extension/ddappsec.c @@ -605,6 +605,7 @@ static PHP_FUNCTION(datadog_appsec_testing_send_invalid_command) .name = "invalid_command", .name_len = sizeof("invalid_command") - 1, .num_args = 1, + .reconnect_sidecar = true, .outgoing_cb = _pack_invalid_command, .incoming_cb = _process_invalid_response, .config_features_cb = dd_command_process_config_features_unexpected, diff --git a/appsec/src/extension/ddtrace.c b/appsec/src/extension/ddtrace.c index c9435ce7677..c55e3b21e82 100644 --- a/appsec/src/extension/ddtrace.c +++ b/appsec/src/extension/ddtrace.c @@ -77,6 +77,10 @@ static zend_string *(*nullable _ddtrace_guess_endpoint_from_url)( static ddog_AppsecCResponse (*nullable _ddog_sidecar_send_appsec_message)( ddog_SidecarTransport *nonnull *nonnull transport, uint64_t client_id, ddog_CharSlice data); +static ddog_AppsecCResponse ( + *nullable _datadog_sidecar_send_appsec_message_without_reconnect)( + ddog_SidecarTransport *nonnull *nonnull transport, uint64_t client_id, + ddog_CharSlice data); static void (*nullable _ddog_sidecar_appsec_response_drop)( ddog_AppsecCResponse response); @@ -132,6 +136,8 @@ static void dd_trace_load_symbols(zend_module_entry *module) _ddtrace_guess_endpoint_from_url, "ddtrace_guess_endpoint_from_url"); ASSIGN_DLSYM( _ddog_sidecar_send_appsec_message, "ddog_sidecar_send_appsec_message"); + ASSIGN_DLSYM(_datadog_sidecar_send_appsec_message_without_reconnect, + "datadog_sidecar_send_appsec_message_without_reconnect"); ASSIGN_DLSYM(_ddog_sidecar_appsec_response_drop, "ddog_sidecar_appsec_response_drop"); } @@ -395,10 +401,11 @@ uint64_t dd_trace_get_sidecar_queue_id(void) #ifdef ZTS ddog_AppsecCResponse dd_trace_send_appsec_message(uint64_t client_id, - void *nullable tsrm_ls, const uint8_t *nonnull request, size_t request_len) + void *nullable tsrm_ls, const uint8_t *nonnull request, size_t request_len, + bool reconnect_sidecar) #else -ddog_AppsecCResponse dd_trace_send_appsec_message( - uint64_t client_id, const uint8_t *nonnull request, size_t request_len) +ddog_AppsecCResponse dd_trace_send_appsec_message(uint64_t client_id, + const uint8_t *nonnull request, size_t request_len, bool reconnect_sidecar) #endif { #ifdef TESTING @@ -412,6 +419,7 @@ ddog_AppsecCResponse dd_trace_send_appsec_message( #endif if (!_ddtrace_get_sidecar_transport || !_ddog_sidecar_send_appsec_message || + !_datadog_sidecar_send_appsec_message_without_reconnect || !_ddog_sidecar_appsec_response_drop) { mlog_once(dd_log_error, "Could not communicate with the helper. Some symbols are missing"); @@ -436,7 +444,11 @@ ddog_AppsecCResponse dd_trace_send_appsec_message( .len = request_len, }; - return _ddog_sidecar_send_appsec_message( + if (reconnect_sidecar) { + return _ddog_sidecar_send_appsec_message( + &sidecar, client_id, request_slice); + } + return _datadog_sidecar_send_appsec_message_without_reconnect( &sidecar, client_id, request_slice); } diff --git a/appsec/src/extension/ddtrace.h b/appsec/src/extension/ddtrace.h index 82257346df1..632837a4d90 100644 --- a/appsec/src/extension/ddtrace.h +++ b/appsec/src/extension/ddtrace.h @@ -68,12 +68,12 @@ zend_string *nullable dd_trace_get_formatted_runtime_id(bool persistent); uint64_t dd_trace_get_sidecar_queue_id(void); #ifdef ZTS -ddog_AppsecCResponse dd_trace_send_appsec_message( - uint64_t client_id, void *nullable tsrm_ls, - const uint8_t *nonnull request, size_t request_len); +ddog_AppsecCResponse dd_trace_send_appsec_message(uint64_t client_id, + void *nullable tsrm_ls, const uint8_t *nonnull request, size_t request_len, + bool reconnect_sidecar); #else -ddog_AppsecCResponse dd_trace_send_appsec_message( - uint64_t client_id, const uint8_t *nonnull request, size_t request_len); +ddog_AppsecCResponse dd_trace_send_appsec_message(uint64_t client_id, + const uint8_t *nonnull request, size_t request_len, bool reconnect_sidecar); #endif void dd_trace_free_appsec_message_response(ddog_AppsecCResponse response); diff --git a/appsec/src/extension/network.c b/appsec/src/extension/network.c index fe2ec96be26..966c5001d01 100644 --- a/appsec/src/extension/network.c +++ b/appsec/src/extension/network.c @@ -37,7 +37,8 @@ void dd_conn_init(dd_conn *nonnull conn) } dd_result dd_conn_roundtrip(dd_conn *nonnull conn, char *nonnull request, - size_t request_len, dd_helper_response *nonnull response_out) + size_t request_len, bool reconnect_sidecar, + dd_helper_response *nonnull response_out) { if (conn == NULL) { return dd_error; @@ -65,10 +66,11 @@ dd_result dd_conn_roundtrip(dd_conn *nonnull conn, char *nonnull request, #ifdef ZTS ddog_AppsecCResponse response = dd_trace_send_appsec_message(conn->client_id, DDAPPSEC_G(ts_ls_cache), - (const uint8_t *)request, request_len); + (const uint8_t *)request, request_len, reconnect_sidecar); #else - ddog_AppsecCResponse response = dd_trace_send_appsec_message( - conn->client_id, (const uint8_t *)request, request_len); + ddog_AppsecCResponse response = + dd_trace_send_appsec_message(conn->client_id, (const uint8_t *)request, + request_len, reconnect_sidecar); #endif dd_result ret; diff --git a/appsec/src/extension/network.h b/appsec/src/extension/network.h index ff92e150abc..e8b15dfbce4 100644 --- a/appsec/src/extension/network.h +++ b/appsec/src/extension/network.h @@ -30,7 +30,8 @@ typedef struct _dd_helper_response { enum { DD_CONN_REQUEST_HEADER_SIZE = 8 }; dd_result dd_conn_roundtrip(dd_conn *nonnull conn, char *nonnull request, - size_t request_len, dd_helper_response *nonnull response_out); + size_t request_len, bool reconnect_sidecar, + dd_helper_response *nonnull response_out); void dd_helper_response_destroy(dd_helper_response *nonnull response); // for helper_process diff --git a/components-rs/common.h b/components-rs/common.h index 4418cd0df38..c75214c4bea 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -1374,7 +1374,7 @@ typedef struct ddog_SenderParameters { } ddog_SenderParameters; /** - * Raw AppSec response returned by `ddog_sidecar_send_appsec_message`. + * Raw AppSec response returned by the AppSec message functions. * * When `ptr` is non-null, the response must be freed by calling * `ddog_sidecar_appsec_response_drop`. diff --git a/components-rs/datadog.h b/components-rs/datadog.h index adb559831d7..199aa03224a 100644 --- a/components-rs/datadog.h +++ b/components-rs/datadog.h @@ -271,6 +271,8 @@ bool datadog_sidecar_reconnect(struct ddog_SidecarTransport **transport, void datadog_sidecar_set_reconnect_fn(struct ddog_SidecarTransport **transport, struct ddog_SidecarTransport *(*factory)(void)); +void datadog_sidecar_clear_reconnect_fn(struct ddog_SidecarTransport **transport); + bool ddog_shm_limiter_inc(const struct ddog_MaybeShmLimiter *limiter, uint32_t limit); bool ddog_exception_hash_limiter_inc(struct ddog_SidecarTransport *connection, diff --git a/components-rs/libdatadog-php-unix.sym b/components-rs/libdatadog-php-unix.sym index 33f201b1ca4..c0952d3781a 100644 --- a/components-rs/libdatadog-php-unix.sym +++ b/components-rs/libdatadog-php-unix.sym @@ -1,4 +1,5 @@ ddog_crashtracker_entry_point ddtrace_sidecar_entry_point ddog_sidecar_send_appsec_message +datadog_sidecar_send_appsec_message_without_reconnect ddog_sidecar_appsec_response_drop diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index b23ac30a17b..a2413af792a 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -517,7 +517,19 @@ struct ddog_AppsecCResponse ddog_sidecar_send_appsec_message(struct ddog_Sidecar ddog_CharSlice data); /** - * Frees an `AppsecCResponse` that was returned by `ddog_sidecar_send_appsec_message`. + * Sends an AppSec message once, without reconnecting the sidecar on failure. + * + * The response is allocated by the sidecar and must be freed with + * `ddog_sidecar_appsec_response_drop` when the caller is done with it. + * + * Returns a zeroed `ddog_AppsecCResponse` (null ptr) on transport errors. + */ +struct ddog_AppsecCResponse datadog_sidecar_send_appsec_message_without_reconnect(struct ddog_SidecarTransport **transport, + uint64_t client_id, + ddog_CharSlice data); + +/** + * Frees an `AppsecCResponse` returned by an AppSec message function. */ void ddog_sidecar_appsec_response_drop(struct ddog_AppsecCResponse response); diff --git a/components-rs/sidecar.rs b/components-rs/sidecar.rs index 438f92b8a0f..28d76a29b45 100644 --- a/components-rs/sidecar.rs +++ b/components-rs/sidecar.rs @@ -285,6 +285,11 @@ pub extern "C" fn datadog_sidecar_set_reconnect_fn( transport.reconnect_fn = Some(Box::new(move || unsafe { factory() })); } +#[no_mangle] +pub extern "C" fn datadog_sidecar_clear_reconnect_fn(transport: &mut Box) { + transport.reconnect_fn = None; +} + lazy_static! { pub static ref SHM_LIMITER: Option> = ShmLimiterMemory::open(&shm_limiter_path()).map_or_else( diff --git a/ext/sidecar.c b/ext/sidecar.c index 728e2dd15d9..ca9706133fd 100644 --- a/ext/sidecar.c +++ b/ext/sidecar.c @@ -549,8 +549,28 @@ void datadog_sidecar_handle_fork(void) { #endif } +// Reconnect factory for subprocess mode: creates a fresh transport and immediately +// re-registers per-request state (service tags, env, etc.) via dd_sidecar_on_reconnect, +// which ddog_sidecar_connect_php alone would not do for a caller-initiated reconnect. +static ddog_SidecarTransport *dd_sidecar_subprocess_reconnect(void) { + ddog_SidecarTransport *transport = datadog_sidecar_connect(false); + if (transport) { + dd_sidecar_on_reconnect(transport); + } + return transport; +} + void datadog_sidecar_ensure_active(void) { if (DATADOG_G(sidecar)) { + // Restore reconnect_fn cleared during the previous RSHUTDOWN so that automatic + // reconnects work again for this request. + if (datadog_sidecar_active_mode == DD_SIDECAR_CONNECTION_SUBPROCESS) { + // Subprocess mode: the reconnect_fn must call dd_sidecar_on_reconnect to + // re-register per-request universal service tags on the new transport. + datadog_sidecar_set_reconnect_fn(&DATADOG_G(sidecar), dd_sidecar_subprocess_reconnect); + } else { + datadog_sidecar_set_reconnect_fn(&DATADOG_G(sidecar), datadog_sidecar_connect_callback); + } datadog_sidecar_reconnect(&DATADOG_G(sidecar), datadog_sidecar_connect_callback); } else if (datadog_endpoint) { // First RINIT on this thread: the process-level setup already ran (endpoint is @@ -567,6 +587,10 @@ void datadog_sidecar_finalize(bool clear_id) { return; } + // Prevent reconnect during shutdown: avoid spawning a new sidecar just to deliver + // goodbye messages. Reconnect is restored at the start of the next RINIT. + datadog_sidecar_clear_reconnect_fn(&DATADOG_G(sidecar)); + if (get_global_DD_INSTRUMENTATION_TELEMETRY_ENABLED()) { datadog_telemetry_finalize(); } @@ -583,6 +607,10 @@ void datadog_sidecar_finalize(bool clear_id) { } void datadog_sidecar_shutdown(void) { + // Prevent reconnect from firing during shutdown-phase sidecar calls. + if (DATADOG_G(sidecar)) { + datadog_sidecar_clear_reconnect_fn(&DATADOG_G(sidecar)); + } datadog_sidecar_for_signal = NULL; // In thread mode, drop the main thread's connection before shutting down the @@ -870,6 +898,8 @@ void datadog_sidecar_rshutdown(void) { void datadog_sidecar_gshutdown(zend_datadog_globals *datadog_globals) { if (datadog_globals->sidecar) { + datadog_sidecar_clear_reconnect_fn(&datadog_globals->sidecar); + if (datadog_globals->sidecar == datadog_sidecar_for_signal) { datadog_sidecar_for_signal = NULL; } diff --git a/libdatadog b/libdatadog index 8134078c4d4..b3813948bfe 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 8134078c4d4301029aed608acc0fa88c5f2b2cf2 +Subproject commit b3813948bfe1c12223a5dbcafe10cff83857780e