diff --git a/tools/cgathui_common/ble_join.c b/tools/cgathui_common/ble_join.c index 83b5bc98f..a7367e330 100644 --- a/tools/cgathui_common/ble_join.c +++ b/tools/cgathui_common/ble_join.c @@ -172,8 +172,12 @@ int ble_join_receive(struct ble_join* b, ble_link_id id, const uint8_t* bytes, s } uint64_t nonce = local_get64(plain + 24), echo = local_get64(plain + 32); uint32_t wire; memcpy(&wire, plain + 40, 4); uint32_t sequence = ntohl(wire); int opcode = plain[44]; + uint64_t opening_deadline = 0; if (l->local_nonce && (get_time_us() >= l->deadline || - (opcode == JOIN_HELLO && (!l->held || !l->authenticated) && !l->count && l->peer_nonce != nonce))) reset(b, l, 1); + (opcode == JOIN_HELLO && l->peer_nonce && (!l->held || !l->authenticated) && !l->count && l->peer_nonce != nonce))) { + if (l->held && !l->authenticated && get_time_us() < l->deadline) opening_deadline = l->deadline; + reset(b, l, 1); + } if (!nonce || (l->peer_nonce && l->peer_nonce != nonce) || (opcode != JOIN_HELLO && (!l->local_nonce || echo != l->local_nonce)) || (opcode == JOIN_HELLO && (echo || sequence || size != JOIN_BODY)) || @@ -186,6 +190,7 @@ int ble_join_receive(struct ble_join* b, ble_link_id id, const uint8_t* bytes, s OPENSSL_cleanse(plain, sizeof(plain)); return 1; } if (start(b, l, bytes + 2)) { OPENSSL_cleanse(plain, sizeof(plain)); return 1; } + if (opening_deadline) l->deadline = opening_deadline; /* Смена ещё не доказанного challenge не продлевает открытие. */ l->peer_nonce = nonce; DEBUG_DEBUG(CAT, "BLE JOIN RX link=%llu op=%d seq=%u bytes=%zu", (unsigned long long)id, opcode, sequence, size - JOIN_BODY); if (opcode == JOIN_HELLO) { diff --git a/tools/cgathui_common/tests/test_ble_etcp.c b/tools/cgathui_common/tests/test_ble_etcp.c index e08bedd50..d64b68e54 100644 --- a/tools/cgathui_common/tests/test_ble_etcp.c +++ b/tools/cgathui_common/tests/test_ble_etcp.c @@ -358,6 +358,14 @@ static void bootstrap_join(unsigned att_mtu, int reverse) { driver[i] = ble_etcp_create(ua, inst[i], &c, 1); assert(driver[i]); assert(!ble_start(ble_etcp_radio(driver[i]))); } uint64_t group = chat_core_create_channel_auto(inst[0], "BLE bootstrap"); assert(group); + char channel[32], profile[1025], padding[1025]; uint8_t signature[64]; uint64_t timestamp; + snprintf(channel, sizeof(channel), "%llu", (unsigned long long)group); + struct chat_profile_option option = {"padding", ""}; + assert(!chat_core_set_my_profile_options(inst[0], channel, &option, 1)); + assert(!chat_core_get_my_profile(inst[0], channel, profile, sizeof(profile), signature, ×tamp)); + size_t pad = 1024 - strlen(profile); memset(padding, 'x', pad); padding[pad] = 0; option.value = padding; + assert(!chat_core_set_my_profile_options(inst[0], channel, &option, 1)); + assert(!chat_core_get_my_profile(inst[0], channel, profile, sizeof(profile), signature, ×tamp) && strlen(profile) == 1024); assert(!chat_join_store_local_key(inst[0], group, 123)); chat_event_set_handler(inst[1], bootstrap_event); drain(); for (int i = 0; i < 2; i++) { @@ -386,6 +394,13 @@ static void bootstrap_join(unsigned att_mtu, int reverse) { assert(bootstrap_result != 0 && !topo_groups_peer_key_known(inst[0], inst[1]->my_keys.public_key)); end = get_time_us() + 100000; while (get_time_us() < end) uasync_poll(ua, 10); invite.join_key = 123; + /* Отмена при занятом GATT: поздний HELLO/REPLY не оживляет отменённую попытку. */ + assert(invite_link_encode(&invite, NULL, link, sizeof(link)) > 0); + hold = 1; bootstrap_result = -999; + assert(!chat_sync_join_link(inst[1], 9, link, strlen(link))); drain(); + chat_sync_cancel_join(inst[1], 9); assert(bootstrap_result == CHAT_CONNECT_CANCELLED); + hold = 0; schedule(backends[0]); schedule(backends[1]); + end = get_time_us() + 100000; while (get_time_us() < end) uasync_poll(ua, 10); } else assert(bootstrap_result == 0); } assert(topo_groups_peer_key_known(inst[0], inst[1]->my_keys.public_key));