)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"f87dcdbd7db457ba45927a834d04ada9a4197018","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":12,"id":"34641ad7_2aab783b","updated":"2026-09-08 08:54:18.000000000","message":"This patch adds `tls_wrap_oob_standalone` and the corresponding `tls_pre_decrypt_lite` path, but does not test them. What do you think about adding round-trip tests analogous to `test_generate_reset_packet_plain` and `test_generate_reset_packet_tls_auth` that wrap an OOB payload, pass it through tls_pre_decrypt_lite, and verify the verdict, session ID, and recovered payload? Ideally the tls-crypt mode should be covered as well.","commit_id":"a5e4c6c7420d0a40fd560f4b51a5e3796d101fec"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"e66a4823f3d14e641ead7eaac31ac1e0290014b1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"dc2a3f10_a952c46c","in_reply_to":"34641ad7_2aab783b","updated":"2026-09-09 07:28:14.000000000","message":"Done, added test_oob_standalone_plain/_tls_auth/_tls_crypt, all sharing a helper: \n\n - wrap a payload with tls_wrap_oob_standalone\n - run through tls_pre_decrypt_lite\n - check the verdict\n - recover session-id and payload bytes\n - for authenticated modes flip bytes and require VERDICT_INVALID","commit_id":"a5e4c6c7420d0a40fd560f4b51a5e3796d101fec"}],"src/openvpn/mudp.c":[{"author":{"_account_id":1000001,"name":"Frank Lichtenheld","display_name":"Frank Lichtenheld","email":"frank@lichtenheld.com","username":"flichtenheld","status":"OpenVPN Inc."},"change_message_id":"073c089dabb067d89a6b6d02e5a89aade9e04d9e","unresolved":true,"context_lines":[{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        /* Rate-limit replies, as the reset path does, so an unauthenticated"},{"line_number":249,"context_line":"         * probe flood (no tls-auth/tls-crypt) cannot use us as a reflector. */"},{"line_number":250,"context_line":"        if (!reflect_filter_rate_limit_check(m-\u003einitial_rate_limiter))"},{"line_number":251,"context_line":"        {"},{"line_number":252,"context_line":"            return false;"},{"line_number":253,"context_line":"        }"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"20c220e3_79e91dfd","line":250,"updated":"2026-07-22 15:43:20.000000000","message":"Why did you move this check here instead of just extending the if condition above?","commit_id":"c615b953bdde58c49ce0609f5f8ca62efdbe1460"},{"author":{"_account_id":1000003,"name":"Arne Schwabe","display_name":"Arne Schwabe","email":"arne-openvpn@rfc2549.org","username":"plaisthos"},"change_message_id":"8781c6c8d43bdf17bbd6271871b012bd36bb0e48","unresolved":true,"context_lines":[{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        /* Rate-limit replies, as the reset path does, so an unauthenticated"},{"line_number":249,"context_line":"         * probe flood (no tls-auth/tls-crypt) cannot use us as a reflector. */"},{"line_number":250,"context_line":"        if (!reflect_filter_rate_limit_check(m-\u003einitial_rate_limiter))"},{"line_number":251,"context_line":"        {"},{"line_number":252,"context_line":"            return false;"},{"line_number":253,"context_line":"        }"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"ee3d505b_49eb3095","line":250,"in_reply_to":"20c220e3_79e91dfd","updated":"2026-07-26 02:06:40.000000000","message":"I agree since the oob reply is an extended server_reset reply in many ways it should follow the same code paths.","commit_id":"c615b953bdde58c49ce0609f5f8ca62efdbe1460"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"b19baff41b9ee3fce184924a760c8ce1772ab57e","unresolved":false,"context_lines":[{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        /* Rate-limit replies, as the reset path does, so an unauthenticated"},{"line_number":249,"context_line":"         * probe flood (no tls-auth/tls-crypt) cannot use us as a reflector. */"},{"line_number":250,"context_line":"        if (!reflect_filter_rate_limit_check(m-\u003einitial_rate_limiter))"},{"line_number":251,"context_line":"        {"},{"line_number":252,"context_line":"            return false;"},{"line_number":253,"context_line":"        }"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"841f748c_3aaf5892","line":250,"in_reply_to":"ee3d505b_49eb3095","updated":"2026-07-28 15:05:05.000000000","message":"It was never moved - it was written inside the OOB branch from the start. But\nagreed, better to have the rate-limit check in one place; the shared condition\nnow covers VERDICT_VALID_OOB_V1.","commit_id":"c615b953bdde58c49ce0609f5f8ca62efdbe1460"},{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"f87dcdbd7db457ba45927a834d04ada9a4197018","unresolved":true,"context_lines":[{"line_number":238,"context_line":"        /* Out-of-band server probe. state-\u003enewbuf points at the TLV payload"},{"line_number":239,"context_line":"         * (read_control_auth has stripped the opcode, session id and any"},{"line_number":240,"context_line":"         * tls-auth/tls-crypt wrapping). Answer it without creating a session. */"},{"line_number":241,"context_line":"        struct oob_probe_reply reply;"},{"line_number":242,"context_line":"        if (!oob_build_probe_reply(\u0026state-\u003enewbuf, (uint64_t)now, (uint64_t)handwindow,"},{"line_number":243,"context_line":"                                   \u0026state-\u003epeer_session_id, \u0026reply))"},{"line_number":244,"context_line":"        {"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"21ca661c_cddb43dc","line":241,"updated":"2026-09-08 08:54:18.000000000","message":"This would potentially send stack garbage. Even though it is fixed by a later patch, this commit should be correct independently so I\u0027d add ` \u003d {0}` here.","commit_id":"a5e4c6c7420d0a40fd560f4b51a5e3796d101fec"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"e66a4823f3d14e641ead7eaac31ac1e0290014b1","unresolved":false,"context_lines":[{"line_number":238,"context_line":"        /* Out-of-band server probe. state-\u003enewbuf points at the TLV payload"},{"line_number":239,"context_line":"         * (read_control_auth has stripped the opcode, session id and any"},{"line_number":240,"context_line":"         * tls-auth/tls-crypt wrapping). Answer it without creating a session. */"},{"line_number":241,"context_line":"        struct oob_probe_reply reply;"},{"line_number":242,"context_line":"        if (!oob_build_probe_reply(\u0026state-\u003enewbuf, (uint64_t)now, (uint64_t)handwindow,"},{"line_number":243,"context_line":"                                   \u0026state-\u003epeer_session_id, \u0026reply))"},{"line_number":244,"context_line":"        {"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"e7c23e64_92f1bbef","line":241,"in_reply_to":"21ca661c_cddb43dc","updated":"2026-09-09 07:28:14.000000000","message":"Done. This is now\n\nstruct oob_probe_reply reply \u003d { .peer_session_id \u003d state-\u003epeer_session_id };\n\nand later patches add their fields to that initializer.","commit_id":"a5e4c6c7420d0a40fd560f4b51a5e3796d101fec"},{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"821be8b789213c6f3f14f5d7db3959f347fcdbd4","unresolved":true,"context_lines":[{"line_number":135,"context_line":"    int handwindow \u003d m-\u003etop.options.handshake_window;"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    if (verdict \u003d\u003d VERDICT_VALID_RESET_V3 || verdict \u003d\u003d VERDICT_VALID_RESET_V2"},{"line_number":138,"context_line":"        || verdict \u003d\u003d VERDICT_VALID_OOB_V1)"},{"line_number":139,"context_line":"    {"},{"line_number":140,"context_line":"        /* Check if we are still below our limit for sending out"},{"line_number":141,"context_line":"         * responses */"}],"source_content_type":"text/x-csrc","patch_set":16,"id":"985b183c_a9d3a6ac","line":138,"updated":"2026-09-17 13:12:43.000000000","message":"By including OOB packets here, `initial_rate_limiter` is charged before `oob_server_probe_check` classifies the payload. Malformed probes and stale probes rejected by `stale_probe_limiter` therefore consume the shared reset-response allowance even though no reply is sent.","commit_id":"010736ef7f721f4841eb67570de51563739399a5"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"a3514ef0a123133df83c80384b822c93880d8521","unresolved":false,"context_lines":[{"line_number":135,"context_line":"    int handwindow \u003d m-\u003etop.options.handshake_window;"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    if (verdict \u003d\u003d VERDICT_VALID_RESET_V3 || verdict \u003d\u003d VERDICT_VALID_RESET_V2"},{"line_number":138,"context_line":"        || verdict \u003d\u003d VERDICT_VALID_OOB_V1)"},{"line_number":139,"context_line":"    {"},{"line_number":140,"context_line":"        /* Check if we are still below our limit for sending out"},{"line_number":141,"context_line":"         * responses */"}],"source_content_type":"text/x-csrc","patch_set":16,"id":"4145263e_2e5614fb","line":138,"in_reply_to":"985b183c_a9d3a6ac","updated":"2026-09-18 12:53:08.000000000","message":"Right. The shared check is back to reset packets only; the OOB path charges the same limiter right before sending the reply, after the malformed and stale checks. Dropped probes are no longer charged.","commit_id":"010736ef7f721f4841eb67570de51563739399a5"},{"author":{"_account_id":1000053,"name":"Răzvan Cojocaru","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"29c4536ad37e0077a22075e61a5fbe8e1615b876","unresolved":true,"context_lines":[{"line_number":232,"context_line":""},{"line_number":233,"context_line":"        return ret;"},{"line_number":234,"context_line":"    }"},{"line_number":235,"context_line":"    else if (verdict \u003d\u003d VERDICT_VALID_OOB_V1)"},{"line_number":236,"context_line":"    {"},{"line_number":237,"context_line":"        /* Out-of-band server probe. state-\u003enewbuf points at the OOB message"},{"line_number":238,"context_line":"         * (read_control_auth has stripped the opcode, session id and any"}],"source_content_type":"text/x-csrc","patch_set":20,"id":"87c486d8_64fb5311","line":235,"updated":"2026-09-30 10:33:43.000000000","message":"Do we want to also gate the following logic on some option being enabled? This looks like any valid `P_CONTROL_OOB_V1` will trigger a server response, which is basically an unauthenticated reply path.","commit_id":"0160c1f0066118d78f9fcc46420134293de271b1"}],"src/openvpn/reflect_filter.h":[{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"821be8b789213c6f3f14f5d7db3959f347fcdbd4","unresolved":true,"context_lines":[{"line_number":46,"context_line":"    bool warning_displayed;"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    /* drop silently: no per-period warning or summary in the log */"},{"line_number":49,"context_line":"    bool quiet;"},{"line_number":50,"context_line":"};"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""}],"source_content_type":"text/x-csrc","patch_set":16,"id":"c55a7f5b_aca29375","line":49,"updated":"2026-09-17 13:12:43.000000000","message":"`quiet` is not initialized by `initial_rate_limit_init`, which uses `ALLOC_OBJ` rather than zero-initialized allocation. The stale-probe limiter sets it to true, but the normal initial-rate limiter leaves it indeterminate and may therefore randomly suppress warnings.\n\n`warning_displayed` is also left uninitialized.","commit_id":"010736ef7f721f4841eb67570de51563739399a5"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"a3514ef0a123133df83c80384b822c93880d8521","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    bool warning_displayed;"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    /* drop silently: no per-period warning or summary in the log */"},{"line_number":49,"context_line":"    bool quiet;"},{"line_number":50,"context_line":"};"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""}],"source_content_type":"text/x-csrc","patch_set":16,"id":"ea53f1b8_fc1c2ab3","line":49,"in_reply_to":"c55a7f5b_aca29375","updated":"2026-09-18 12:53:08.000000000","message":"good catch, fixed","commit_id":"010736ef7f721f4841eb67570de51563739399a5"}]}
