)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Implement initial packet reflection protection using bloom filter"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When an OpenVPN server is used/tried to be usedc in a reflection attack"},{"line_number":10,"context_line":"the protection with the simple --connect-freq-initial also block legimitate"},{"line_number":11,"context_line":"client from other networks that are not attacked by a reflection attack."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"140c2624_9f153ae5","line":9,"updated":"2026-08-30 16:28:03.000000000","message":"\"usedc\" -\u003e \"used\"","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"},{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":7,"context_line":"Implement initial packet reflection protection using bloom filter"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When an OpenVPN server is used/tried to be usedc in a reflection attack"},{"line_number":10,"context_line":"the protection with the simple --connect-freq-initial also block legimitate"},{"line_number":11,"context_line":"client from other networks that are not attacked by a reflection attack."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"To allow a server to still reply to these clients, we need to make the counts"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"9f26e985_c90f8d99","line":10,"updated":"2026-08-30 16:28:03.000000000","message":"\"block\" -\u003e \"blocks\"\n\"legimitate\" -\u003e \"legitimate\"","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"},{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When an OpenVPN server is used/tried to be usedc in a reflection attack"},{"line_number":10,"context_line":"the protection with the simple --connect-freq-initial also block legimitate"},{"line_number":11,"context_line":"client from other networks that are not attacked by a reflection attack."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"To allow a server to still reply to these clients, we need to make the counts"},{"line_number":14,"context_line":"rather more detailed and count per subnet or IP address. On the other hand"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"27780e5b_11938546","line":11,"updated":"2026-08-30 16:28:03.000000000","message":"\"clients\"?","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"},{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":15,"context_line":"when we keep all this state, we eliminate the advantage of having a stateless"},{"line_number":16,"context_line":"cookie based initial packet handshake."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"As compromoise we use a bloom filter to store the information. This data"},{"line_number":19,"context_line":"structure is probabilistic and can have false positive and more packets"},{"line_number":20,"context_line":"being dropped but since it is a constant size and the size of this map"},{"line_number":21,"context_line":"is small enough for non-embedded systems (tests were done with a 2MB"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"c9a91b6b_9f87b405","line":18,"updated":"2026-08-30 16:28:03.000000000","message":"\"compromoise\" -\u003e \"compromise\" (maybe \"a compromise\"?).","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"},{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"The code is split into the bloom filter implementation and the actual logic"},{"line_number":25,"context_line":"implementing tracking the subnets, so the bloom filter should be relatively"},{"line_number":26,"context_line":"easily be exchangable by another data structure."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"As hash funtion SIPHASH has been chosen since it was designed for this kind"},{"line_number":29,"context_line":"of application."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"5062755f_6e0963a8","line":26,"updated":"2026-08-30 16:28:03.000000000","message":"\"exchangeable\"","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"},{"author":{"_account_id":1000053,"name":"razvanc","display_name":"Razvan Cojocaru","email":"razvanc@mailbox.org","username":"razvanc"},"change_message_id":"1e5d27a9962825bde72d15da684360136bffe74d","unresolved":true,"context_lines":[{"line_number":25,"context_line":"implementing tracking the subnets, so the bloom filter should be relatively"},{"line_number":26,"context_line":"easily be exchangable by another data structure."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"As hash funtion SIPHASH has been chosen since it was designed for this kind"},{"line_number":29,"context_line":"of application."},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"Change-Id: I0a9274cab7fefce3b13c05052fb9a072e0bfa6b9"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"c1d19860_af2edf03","line":28,"updated":"2026-08-30 16:28:03.000000000","message":"\"funtion\" -\u003e \"function\"","commit_id":"8f25090ead49b0c71eb783623d1309738e9a7b12"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"526ba69c_33156428","updated":"2024-09-21 14:26:47.000000000","message":"I havne\u0027t reviewed the whole thing yet, but I found some stuff to complain about","commit_id":"d43f1cc810efceedecd674b1351a189098d2355a"}],"src/openvpn/Makefile.am":[{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":43,"context_line":"\tauth_token.c auth_token.h \\"},{"line_number":44,"context_line":"\tbase64.c base64.h \\"},{"line_number":45,"context_line":"\tbasic.h \\"},{"line_number":46,"context_line":"    bloom.c bloom.h \\"},{"line_number":47,"context_line":"\tbuffer.c buffer.h \\"},{"line_number":48,"context_line":"\tcirc_list.h \\"},{"line_number":49,"context_line":"\tclinat.c clinat.h \\"}],"source_content_type":"application/octet-stream","patch_set":8,"id":"5feab99c_f33c2318","line":46,"range":{"start_line":46,"start_character":0,"end_line":46,"end_character":5},"updated":"2024-09-21 14:26:47.000000000","message":"tabs vs spaces","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"}],"src/openvpn/bloom.c":[{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":98,"context_line":"    return num_siphash;"},{"line_number":99,"context_line":"}"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"/**"},{"line_number":102,"context_line":" * Calculates the number of bytes we need for storing a bloom filter of size"},{"line_number":103,"context_line":" * size. We add + 1 to avoid rounding problems and too small allocation */"},{"line_number":104,"context_line":"static inline"},{"line_number":105,"context_line":"size_t"},{"line_number":106,"context_line":"bloom_get_filter_byte_count(size_t size)"},{"line_number":107,"context_line":"{"},{"line_number":108,"context_line":"    static_assert(sizeof(bloom_counter_t) * 8 % BLOOM_FILTER_BITS_COUNT \u003d\u003d 0,"},{"line_number":109,"context_line":"                  \"bloom_counter_t must be a multiple of BLOOM_FILTER_BIT_COUNT\");"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    return size * sizeof(bloom_counter_t)/BLOOM_FILTER_BITS_COUNT + 1;"},{"line_number":112,"context_line":"}"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"static inline"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"ca1b18dc_b9ffbcbe","line":112,"range":{"start_line":101,"start_character":0,"end_line":112,"end_character":1},"updated":"2024-09-21 14:26:47.000000000","message":"I\u0027m really confused by what size means here. This is *not* the size field in the bloom filter struct, right? It\u0027s the total number of bits in the bloom filter, right?","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"},{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":112,"context_line":"}"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"static inline"},{"line_number":116,"context_line":"size_t"},{"line_number":117,"context_line":"bloom_get_filter_bit_offset(size_t bucket)"},{"line_number":118,"context_line":"{"},{"line_number":119,"context_line":"    return (bucket * BLOOM_FILTER_BITS_COUNT) % sizeof(bloom_counter_t);"},{"line_number":120,"context_line":"}"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"static inline"},{"line_number":123,"context_line":"size_t"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"88af9dc3_bf01868e","line":120,"range":{"start_line":115,"start_character":0,"end_line":120,"end_character":1},"updated":"2024-09-21 14:26:47.000000000","message":"If this is a bit offset, don\u0027t we need 8 * sizeof(bloom_counter_t) here?","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"},{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":119,"context_line":"    return (bucket * BLOOM_FILTER_BITS_COUNT) % sizeof(bloom_counter_t);"},{"line_number":120,"context_line":"}"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"static inline"},{"line_number":123,"context_line":"size_t"},{"line_number":124,"context_line":"bloom_get_filter_array_index(size_t bucket)"},{"line_number":125,"context_line":"{"},{"line_number":126,"context_line":"    return (bucket * BLOOM_FILTER_BITS_COUNT) / sizeof(bloom_counter_t);"},{"line_number":127,"context_line":"}"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"static inline bloom_counter_t"},{"line_number":130,"context_line":"bloom_get_filter_get_counter(struct bloom_filter *bf, size_t bucket)"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"f0ce5e7f_d277c415","line":127,"range":{"start_line":122,"start_character":0,"end_line":127,"end_character":1},"updated":"2024-09-21 14:26:47.000000000","message":"This seems wrong to me. Every bucket is 2 bits wide. The bloom_counter_t is 32 bits wide, or 4 bytes, so sizeof(bloom_counter_t) \u003d\u003d 4.\n\nBucket 3 is at a 6 bit offset, so it\u0027s in the first bloom_counter_t (array index 0). But this function gives 3 * 2 / 4 \u003d\u003d 1.","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"},{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    bf-\u003enum_siphash \u003d calculate_num_sip_hash_hashes(bf);"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"    ALLOC_ARRAY_GC(bf-\u003esiphash_keys, struct siphash_key, bf-\u003enum_siphash, gc);"},{"line_number":172,"context_line":"    "},{"line_number":173,"context_line":"    bloom_clear(bf);"},{"line_number":174,"context_line":"    return bf;"},{"line_number":175,"context_line":"}"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"688a1a4a_2c63f6ac","line":172,"range":{"start_line":172,"start_character":0,"end_line":172,"end_character":4},"updated":"2024-09-21 14:26:47.000000000","message":"whitespace","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"}],"src/openvpn/bloom.h":[{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":5,"context_line":" *             packet encryption, packet authentication, and"},{"line_number":6,"context_line":" *             packet compression."},{"line_number":7,"context_line":" *"},{"line_number":8,"context_line":" *  Copyright (C) 2022 OpenVPN Inc \u003csales@openvpn.net\u003e"},{"line_number":9,"context_line":" *"},{"line_number":10,"context_line":" *  This program is free software; you can redistribute it and/or modify"},{"line_number":11,"context_line":" *  it under the terms of the GNU General Public License version 2"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"88db0086_921e0752","line":8,"range":{"start_line":8,"start_character":17,"end_line":8,"end_character":23},"updated":"2024-09-21 14:26:47.000000000","message":"Shouldn\u0027t this be 2024?","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"},{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":29,"context_line":"#include \"buffer.h\""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"/* This is the type we use for the buckets. This is split into small buckets"},{"line_number":32,"context_line":" * with BLOOM_FILTER_BIT_COUNT size */"},{"line_number":33,"context_line":"typedef uint32_t bloom_counter_t;"},{"line_number":34,"context_line":"#define BLOOM_FILTER_BITS_COUNT    2"},{"line_number":35,"context_line":"#define BLOOM_FILTER_BITS_MASK   0x03"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"c0e46973_ad5f7ee1","line":32,"range":{"start_line":32,"start_character":8,"end_line":32,"end_character":30},"updated":"2024-09-21 14:26:47.000000000","message":"BITS","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"}],"src/openvpn/reflect_filter.c":[{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":40,"context_line":"#include \"crypto.h\""},{"line_number":41,"context_line":"#include \"reflect_filter.h\""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"static bool"},{"line_number":44,"context_line":"reflect_filter_rate_limit_check(struct initial_packet_rate_limit *irl)"},{"line_number":45,"context_line":"{"},{"line_number":46,"context_line":"    if (now \u003e irl-\u003elast_period_reset + irl-\u003eperiod_length)"},{"line_number":47,"context_line":"    {"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"e570d1bc_a93710c4","line":44,"range":{"start_line":43,"start_character":0,"end_line":44,"end_character":21},"updated":"2024-09-21 14:26:47.000000000","message":"Remove empty line","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"},{"author":{"_account_id":1000030,"name":"MaxF","email":"max@max-fillinger.net","username":"MaxF"},"change_message_id":"a2ec20f5c9eef16ab062006f5ad13d2aac5a916d","unresolved":true,"context_lines":[{"line_number":113,"context_line":"        struct in6_addr in6;"},{"line_number":114,"context_line":"    };"},{"line_number":115,"context_line":"    int netmask;"},{"line_number":116,"context_line":"    /* we keep the count in the key instead of in the bloom filter table as"},{"line_number":117,"context_line":"     * can then keep the counter in the bloom filter itself small (2 bits)"},{"line_number":118,"context_line":"     * and bloom filter usage is the same for 20000 request from the same IP"},{"line_number":119,"context_line":"     * (20k entries with different count but same IP) and from 20000 random ips"},{"line_number":120,"context_line":"     * (20k entries with count 1 but different IP) */"}],"source_content_type":"text/x-csrc","patch_set":8,"id":"71c672e1_c93872de","line":117,"range":{"start_line":116,"start_character":1,"end_line":117,"end_character":74},"updated":"2024-09-21 14:26:47.000000000","message":"...as we can then...","commit_id":"9ad1a4d4b8c54017f2a5fdb12c5697a85bde5d5b"}]}
