)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1000001,"name":"Frank Lichtenheld","display_name":"Frank Lichtenheld","email":"frank@lichtenheld.com","username":"flichtenheld","status":"OpenVPN Inc."},"change_message_id":"a573a069919e2973cad08b54878ba0c194689a13","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"c4204409_1ed6b30f","updated":"2026-07-20 13:51:28.000000000","message":"nitpicks","commit_id":"341208223ac405eb0e06a049255f4923dac766bd"}],"src/openvpn/oob.c":[{"author":{"_account_id":1000001,"name":"Frank Lichtenheld","display_name":"Frank Lichtenheld","email":"frank@lichtenheld.com","username":"flichtenheld","status":"OpenVPN Inc."},"change_message_id":"a573a069919e2973cad08b54878ba0c194689a13","unresolved":true,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"    /* A TLV header is 4 bytes (type + length). Loop until we either find the"},{"line_number":186,"context_line":"     * probe_parameter or run out of well-formed TLVs. */"},{"line_number":187,"context_line":"    while (BLEN(payload) \u003e\u003d 4)"},{"line_number":188,"context_line":"    {"},{"line_number":189,"context_line":"        uint16_t type;"},{"line_number":190,"context_line":"        bool optional;"}],"source_content_type":"text/x-csrc","patch_set":7,"id":"bbc91768_1d8bca0a","line":187,"updated":"2026-07-20 13:51:28.000000000","message":"Instead of hardcoding that 4 why not do `while(oob_tlv_read_header(...))`?","commit_id":"341208223ac405eb0e06a049255f4923dac766bd"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"37d9c614c8b19ced6eec5f57befae065c5308e44","unresolved":false,"context_lines":[{"line_number":184,"context_line":""},{"line_number":185,"context_line":"    /* A TLV header is 4 bytes (type + length). Loop until we either find the"},{"line_number":186,"context_line":"     * probe_parameter or run out of well-formed TLVs. */"},{"line_number":187,"context_line":"    while (BLEN(payload) \u003e\u003d 4)"},{"line_number":188,"context_line":"    {"},{"line_number":189,"context_line":"        uint16_t type;"},{"line_number":190,"context_line":"        bool optional;"}],"source_content_type":"text/x-csrc","patch_set":7,"id":"2e88f7a7_bfed1fb6","line":187,"in_reply_to":"bbc91768_1d8bca0a","updated":"2026-07-21 12:36:43.000000000","message":"Fixed.","commit_id":"341208223ac405eb0e06a049255f4923dac766bd"},{"author":{"_account_id":1000001,"name":"Frank Lichtenheld","display_name":"Frank Lichtenheld","email":"frank@lichtenheld.com","username":"flichtenheld","status":"OpenVPN Inc."},"change_message_id":"a573a069919e2973cad08b54878ba0c194689a13","unresolved":true,"context_lines":[{"line_number":229,"context_line":"        return false;"},{"line_number":230,"context_line":"    }"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    memset(reply, 0, sizeof(*reply));"},{"line_number":233,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"},{"line_number":234,"context_line":"    /* priority/weight/connect_lifetime/flags left at 0 for now */"},{"line_number":235,"context_line":"    return true;"}],"source_content_type":"text/x-csrc","patch_set":7,"id":"03e61d54_edfd82ef","line":232,"updated":"2026-07-20 13:51:28.000000000","message":"Should probably use CLEAR() macro","commit_id":"341208223ac405eb0e06a049255f4923dac766bd"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"37d9c614c8b19ced6eec5f57befae065c5308e44","unresolved":false,"context_lines":[{"line_number":229,"context_line":"        return false;"},{"line_number":230,"context_line":"    }"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"    memset(reply, 0, sizeof(*reply));"},{"line_number":233,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"},{"line_number":234,"context_line":"    /* priority/weight/connect_lifetime/flags left at 0 for now */"},{"line_number":235,"context_line":"    return true;"}],"source_content_type":"text/x-csrc","patch_set":7,"id":"74431fcd_2182b6c0","line":232,"in_reply_to":"03e61d54_edfd82ef","updated":"2026-07-21 12:36:43.000000000","message":"Fixed.","commit_id":"341208223ac405eb0e06a049255f4923dac766bd"},{"author":{"_account_id":1000003,"name":"Arne Schwabe","display_name":"Arne Schwabe","email":"arne-openvpn@rfc2549.org","username":"plaisthos"},"change_message_id":"6e8c4e1838349fb788d907545584fc8b8bde2453","unresolved":true,"context_lines":[{"line_number":223,"context_line":"    if (!oob_timestamp_in_window(param.timestamp, now, window_secs))"},{"line_number":224,"context_line":"    {"},{"line_number":225,"context_line":"        return false;"},{"line_number":226,"context_line":"    }"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    CLEAR(*reply);"},{"line_number":229,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"c2c75c09_6a659319","line":226,"updated":"2026-07-26 01:07:19.000000000","message":"I think this is harmful if we drop them uncondionally. We should probably still accept them but maybe at a much lower rate than ones with correct time.\n\nOtherwise the goal to eventually be able to replace the reset packet with these new packets will never work.","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000003,"name":"Arne Schwabe","display_name":"Arne Schwabe","email":"arne-openvpn@rfc2549.org","username":"plaisthos"},"change_message_id":"2671663d4597fb025f3f841967a88db414410439","unresolved":true,"context_lines":[{"line_number":223,"context_line":"    if (!oob_timestamp_in_window(param.timestamp, now, window_secs))"},{"line_number":224,"context_line":"    {"},{"line_number":225,"context_line":"        return false;"},{"line_number":226,"context_line":"    }"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    CLEAR(*reply);"},{"line_number":229,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"4ed90f3b_759c0b71","line":226,"in_reply_to":"1554b53d_267d712a","updated":"2026-09-16 23:20:47.000000000","message":"The spec got changed/revised after the first draft and now explicitly states that the server should accept this. \n\nIf you disagree lets discuss that on the PR of the spec rather than in gerrit.","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"3219708e817f340c3c2cc4ed5f01a3747e56aff5","unresolved":false,"context_lines":[{"line_number":223,"context_line":"    if (!oob_timestamp_in_window(param.timestamp, now, window_secs))"},{"line_number":224,"context_line":"    {"},{"line_number":225,"context_line":"        return false;"},{"line_number":226,"context_line":"    }"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    CLEAR(*reply);"},{"line_number":229,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"ac62c5a2_e2a74462","line":226,"in_reply_to":"4ed90f3b_759c0b71","updated":"2026-09-17 07:01:30.000000000","message":"Done. The server now classifies a probe as invalid, stale or ok; a stale one (timestamp more than --hand-window off) is still answered within a small server-wide budget, 1/20 of --connect-freq-initial per period, i.e. 5 per 10 s by default, the spec\u0027s own example. It reuses the initial-packet rate limiter with a new quiet flag, since a replayed probe hitting the limit is not worth the --connect-freq-initial warning. Implemented in 1743, man pages updated in 1747 and 1752.","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"4807ca7e1391cab6f3162de4a3247ebc870ed0c5","unresolved":true,"context_lines":[{"line_number":223,"context_line":"    if (!oob_timestamp_in_window(param.timestamp, now, window_secs))"},{"line_number":224,"context_line":"    {"},{"line_number":225,"context_line":"        return false;"},{"line_number":226,"context_line":"    }"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    CLEAR(*reply);"},{"line_number":229,"context_line":"    reply-\u003epeer_session_id \u003d *peer_sid;"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"1554b53d_267d712a","line":226,"in_reply_to":"c2c75c09_6a659319","updated":"2026-07-28 15:04:42.000000000","message":"Is this needed for the clients with the wrong timestamp?\n\nAt the moment the window is picked as --hand-window which is 60s default. I would say the implementation is in accordance to the spec:\n\n\u003e Any OOB SERVER_PROBE MUST include this TLV. The timestamp allows a server to silently drop any request that is not in an acceptable window of time to reduce the attack surface for replay attacks.","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"eb7be9d12d920c8882a4bdc299f0a798f7bffb82","unresolved":true,"context_lines":[{"line_number":113,"context_line":"}"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"bool"},{"line_number":116,"context_line":"oob_build_probe_reply(struct buffer *probe_payload, uint64_t now, uint64_t window_secs,"},{"line_number":117,"context_line":"                      const struct session_id *peer_sid, struct oob_probe_reply *reply)"},{"line_number":118,"context_line":"{"},{"line_number":119,"context_line":"    struct oob_probe_parameter param;"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"44707784_9348a384","line":116,"updated":"2026-09-08 08:12:04.000000000","message":"I find this function a bit confusing. Despite being named `_build`, it does not actually build the reply. It validates the request and fills exactly 1 member of a caller-populated object. In the immediately following patch the caller declares `struct oob_probe_reply reply` and relies on this function, which initializes only `peer_session_id`; the other reply fields are consequently uninitialized until a later patch changes the caller.\n\nPersonally, I\u0027d name this function something like `_valid` and avoid modifying `reply` here. In fact, `peer_session_id` can be pre-populated by the caller like the other `reply` fields.","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"eabfa7ab9856ee4348f35a25977db9d9313ac5ca","unresolved":false,"context_lines":[{"line_number":113,"context_line":"}"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"bool"},{"line_number":116,"context_line":"oob_build_probe_reply(struct buffer *probe_payload, uint64_t now, uint64_t window_secs,"},{"line_number":117,"context_line":"                      const struct session_id *peer_sid, struct oob_probe_reply *reply)"},{"line_number":118,"context_line":"{"},{"line_number":119,"context_line":"    struct oob_probe_parameter param;"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"f35666c8_a66e6fc3","line":116,"in_reply_to":"44707784_9348a384","updated":"2026-09-09 07:27:42.000000000","message":"Agreed, and done. It is now oob_server_probe_accept() -\u003e bool and touches nothing but the payload it reads. The caller in the next patch builds the reply.","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"}],"src/openvpn/oob.h":[{"author":{"_account_id":1000003,"name":"Arne Schwabe","display_name":"Arne Schwabe","email":"arne-openvpn@rfc2549.org","username":"plaisthos"},"change_message_id":"6e8c4e1838349fb788d907545584fc8b8bde2453","unresolved":true,"context_lines":[{"line_number":158,"context_line":"/**"},{"line_number":159,"context_line":" * Read a received OOB SERVER_PROBE: verify its message-type header, then scan"},{"line_number":160,"context_line":" * for the probe_parameter TLV. TLV types other than probe_parameter are"},{"line_number":161,"context_line":" * skipped, so the scan tolerates additional/future TLVs. @p payload is consumed"},{"line_number":162,"context_line":" * as it is read."},{"line_number":163,"context_line":" *"},{"line_number":164,"context_line":" * @param payload  buffer positioned at the start of the OOB message payload"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"901d01eb_60ff6821","line":161,"updated":"2026-07-26 01:07:19.000000000","message":"the scan?","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"4807ca7e1391cab6f3162de4a3247ebc870ed0c5","unresolved":false,"context_lines":[{"line_number":158,"context_line":"/**"},{"line_number":159,"context_line":" * Read a received OOB SERVER_PROBE: verify its message-type header, then scan"},{"line_number":160,"context_line":" * for the probe_parameter TLV. TLV types other than probe_parameter are"},{"line_number":161,"context_line":" * skipped, so the scan tolerates additional/future TLVs. @p payload is consumed"},{"line_number":162,"context_line":" * as it is read."},{"line_number":163,"context_line":" *"},{"line_number":164,"context_line":" * @param payload  buffer positioned at the start of the OOB message payload"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"c9972fc4_8a4889bf","line":161,"in_reply_to":"901d01eb_60ff6821","updated":"2026-07-28 15:04:42.000000000","message":"Let\u0027s just leave \"other than probe_parameters are skipped\".","commit_id":"2e79a47e4bad09cf3952c4df0be13742908f2437"},{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"eb7be9d12d920c8882a4bdc299f0a798f7bffb82","unresolved":true,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"/**"},{"line_number":117,"context_line":" * Read a received OOB SERVER_PROBE: verify its message-type header, then scan"},{"line_number":118,"context_line":" * for the probe_parameter TLV. TLV types other than probe_parameter are"},{"line_number":119,"context_line":" * skipped. payload is consumed as it is read."},{"line_number":120,"context_line":" *"},{"line_number":121,"context_line":" * @param payload  buffer positioned at the start of the OOB message payload"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"bb56292d_ff09ac5a","line":118,"updated":"2026-09-08 08:12:04.000000000","message":"nit: only unknown optional TLVs are skipped; unknown mandatory TLVs are rejected","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"eabfa7ab9856ee4348f35a25977db9d9313ac5ca","unresolved":false,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"/**"},{"line_number":117,"context_line":" * Read a received OOB SERVER_PROBE: verify its message-type header, then scan"},{"line_number":118,"context_line":" * for the probe_parameter TLV. TLV types other than probe_parameter are"},{"line_number":119,"context_line":" * skipped. payload is consumed as it is read."},{"line_number":120,"context_line":" *"},{"line_number":121,"context_line":" * @param payload  buffer positioned at the start of the OOB message payload"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"fd4f68ea_bd0d1921","line":118,"in_reply_to":"bb56292d_ff09ac5a","updated":"2026-09-09 07:27:42.000000000","message":"Again outdated comment. Fixed.","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"}],"tests/unit_tests/openvpn/test_oob.c":[{"author":{"_account_id":1000041,"name":"Ralf Lici","display_name":"Ralf Lici","email":"ralf@mandelbit.com","username":"ralf_lici"},"change_message_id":"eb7be9d12d920c8882a4bdc299f0a798f7bffb82","unresolved":true,"context_lines":[{"line_number":416,"context_line":"    memcpy(peer.id, \"PEER1234\", SID_SIZE);"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    /* left as the caller set them: the function only fills the session id */"},{"line_number":419,"context_line":"    struct oob_probe_reply reply \u003d { 0 };"},{"line_number":420,"context_line":"    assert_true(oob_build_probe_reply(\u0026buf, now, 30, \u0026peer, \u0026reply));"},{"line_number":421,"context_line":"    assert_memory_equal(reply.peer_session_id.id, peer.id, SID_SIZE);"},{"line_number":422,"context_line":"    assert_int_equal(reply.priority, 0);"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"abe5bac3_ed86028f","line":419,"updated":"2026-09-08 08:12:04.000000000","message":"Zero-initializing the reply here is misleading because the subsequent asserts cannot prove whether `oob_build_prove_reply` zeroes or preservers the remaining fields.\n\nIf the current API is retained (see my other observation), I\u0027d initialize those fields to distinct nonzero values and verify they remain unchanged.","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"},{"author":{"_account_id":1000008,"name":"Lev Stipakov","display_name":"Lev Stipakov","email":"lstipakov@gmail.com","username":"stipa"},"change_message_id":"eabfa7ab9856ee4348f35a25977db9d9313ac5ca","unresolved":false,"context_lines":[{"line_number":416,"context_line":"    memcpy(peer.id, \"PEER1234\", SID_SIZE);"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"    /* left as the caller set them: the function only fills the session id */"},{"line_number":419,"context_line":"    struct oob_probe_reply reply \u003d { 0 };"},{"line_number":420,"context_line":"    assert_true(oob_build_probe_reply(\u0026buf, now, 30, \u0026peer, \u0026reply));"},{"line_number":421,"context_line":"    assert_memory_equal(reply.peer_session_id.id, peer.id, SID_SIZE);"},{"line_number":422,"context_line":"    assert_int_equal(reply.priority, 0);"}],"source_content_type":"text/x-csrc","patch_set":12,"id":"1e643339_ce98958d","line":419,"in_reply_to":"abe5bac3_ed86028f","updated":"2026-09-09 07:27:42.000000000","message":"no-op after API change above.","commit_id":"8a45bcacebf903eea3c03773a73159560a6ea3ee"}]}
