diff options
| author | Your Name <you@example.com> | 2026-05-17 16:39:31 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-17 16:39:31 +0530 |
| commit | 0c2c67b463d6a90aaa0bb69bf3c91dba1d9ec3ec (patch) | |
| tree | afd9d9bca2d184825ebf7413ec31830e14131030 /tests/unit | |
| parent | 3342c8e7b4f645c75470d3d893d09037a672cfd2 (diff) | |
feat: per-client NAT filtering via LWIP_HOOK_IP4_CANFORWARD
- Add lwip_tollgate_hooks.h defining LWIP_HOOK_IP4_CANFORWARD macro
- Inject hook into lwIP build via CMakeLists.txt ESP_IDF_LWIP_HOOK_FILENAME
- Filter forwarded packets by source IP against firewall allowed list
- Only filter packets from AP subnet (10.192.45.0/24), allow all others
- Fix byte order bug: use network byte order for firewall_is_client_allowed
- NAT always enabled, removed global NAT toggle functions
- Remove spent-secret tracking from session.c (mint is authority)
- Remove unused get_ap_netif() function
- Reduce API server stack from 32KB to 16KB (fixes ESP_ERR_HTTPD_TASK)
- Add esp_random.h stub for unit tests
- All 186 unit tests passing
- Verified on hardware: block->pay->allow->revoke->block E2E works
Diffstat (limited to 'tests/unit')
| -rw-r--r-- | tests/unit/stubs/esp_random.h | 6 | ||||
| -rwxr-xr-x | tests/unit/test_identity | bin | 296728 -> 297880 bytes | |||
| -rwxr-xr-x | tests/unit/test_mcp_handler | bin | 0 -> 38736 bytes | |||
| -rwxr-xr-x | tests/unit/test_nip04 | bin | 0 -> 298776 bytes | |||
| -rw-r--r-- | tests/unit/test_session.c | 37 | ||||
| -rwxr-xr-x | tests/unit/test_tollgate_client | bin | 51904 -> 51992 bytes |
6 files changed, 19 insertions, 24 deletions
diff --git a/tests/unit/stubs/esp_random.h b/tests/unit/stubs/esp_random.h new file mode 100644 index 0000000..bb58af2 --- /dev/null +++ b/tests/unit/stubs/esp_random.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef STUB_ESP_RANDOM_H | ||
| 2 | #define STUB_ESP_RANDOM_H | ||
| 3 | |||
| 4 | #include "esp_system.h" | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/tests/unit/test_identity b/tests/unit/test_identity index 7ad1485..277bb49 100755 --- a/tests/unit/test_identity +++ b/tests/unit/test_identity | |||
| Binary files differ | |||
diff --git a/tests/unit/test_mcp_handler b/tests/unit/test_mcp_handler new file mode 100755 index 0000000..b5d6a85 --- /dev/null +++ b/tests/unit/test_mcp_handler | |||
| Binary files differ | |||
diff --git a/tests/unit/test_nip04 b/tests/unit/test_nip04 new file mode 100755 index 0000000..cb52040 --- /dev/null +++ b/tests/unit/test_nip04 | |||
| Binary files differ | |||
diff --git a/tests/unit/test_session.c b/tests/unit/test_session.c index 548be0d..2619ba3 100644 --- a/tests/unit/test_session.c +++ b/tests/unit/test_session.c | |||
| @@ -46,8 +46,7 @@ static void test_sessions(void) | |||
| 46 | ASSERT_EQ_INT(0, session_active_count(), "No sessions after init"); | 46 | ASSERT_EQ_INT(0, session_active_count(), "No sessions after init"); |
| 47 | 47 | ||
| 48 | printf("\n--- session_create ---\n"); | 48 | printf("\n--- session_create ---\n"); |
| 49 | const char *secrets[] = {"secret1", "secret2"}; | 49 | session_t *s = session_create(0x0A01A8C0, 60000); |
| 50 | session_t *s = session_create(0x0A01A8C0, 60000, secrets, 2); | ||
| 51 | ASSERT(s != NULL, "session_create returns non-NULL"); | 50 | ASSERT(s != NULL, "session_create returns non-NULL"); |
| 52 | ASSERT_EQ_INT(1, session_active_count(), "1 session after create"); | 51 | ASSERT_EQ_INT(1, session_active_count(), "1 session after create"); |
| 53 | ASSERT_EQ_INT(1, g_granted_count, "firewall_grant_access was called"); | 52 | ASSERT_EQ_INT(1, g_granted_count, "firewall_grant_access was called"); |
| @@ -57,23 +56,18 @@ static void test_sessions(void) | |||
| 57 | ASSERT(found == s, "session_find_by_ip returns the created session"); | 56 | ASSERT(found == s, "session_find_by_ip returns the created session"); |
| 58 | ASSERT(session_find_by_ip(0x01020304) == NULL, "session_find_by_ip returns NULL for unknown IP"); | 57 | ASSERT(session_find_by_ip(0x01020304) == NULL, "session_find_by_ip returns NULL for unknown IP"); |
| 59 | 58 | ||
| 60 | printf("\n--- session_is_secret_spent ---\n"); | ||
| 61 | ASSERT(session_is_secret_spent("secret1"), "secret1 is marked spent"); | ||
| 62 | ASSERT(session_is_secret_spent("secret2"), "secret2 is marked spent"); | ||
| 63 | ASSERT(!session_is_secret_spent("secret_unknown"), "unknown secret is not spent"); | ||
| 64 | |||
| 65 | printf("\n--- Duplicate secret rejected ---\n"); | ||
| 66 | const char *dup_secrets[] = {"secret1"}; | ||
| 67 | g_granted_count = 0; | ||
| 68 | session_t *dup = session_create(0x0B01A8C0, 60000, dup_secrets, 1); | ||
| 69 | ASSERT(dup == NULL, "Duplicate secret returns NULL"); | ||
| 70 | ASSERT_EQ_INT(0, g_granted_count, "No new firewall grant for duplicate"); | ||
| 71 | |||
| 72 | printf("\n--- session_extend ---\n"); | 59 | printf("\n--- session_extend ---\n"); |
| 73 | uint64_t old_allotment = s->allotment_ms; | 60 | uint64_t old_allotment = s->allotment_ms; |
| 74 | session_extend(s, 30000); | 61 | session_extend(s, 30000); |
| 75 | ASSERT(s->allotment_ms == old_allotment + 30000, "Allotment extended by 30000ms"); | 62 | ASSERT(s->allotment_ms == old_allotment + 30000, "Allotment extended by 30000ms"); |
| 76 | 63 | ||
| 64 | printf("\n--- session_extend for existing client ---\n"); | ||
| 65 | g_granted_count = 0; | ||
| 66 | session_t *s2 = session_create(0x0A01A8C0, 30000); | ||
| 67 | ASSERT(s2 == s, "same IP returns existing session"); | ||
| 68 | ASSERT_EQ_INT(0, g_granted_count, "no new firewall grant for extension"); | ||
| 69 | ASSERT(s->allotment_ms == old_allotment + 60000, "allotment extended by 30000ms on re-pay"); | ||
| 70 | |||
| 77 | printf("\n--- session_revoke ---\n"); | 71 | printf("\n--- session_revoke ---\n"); |
| 78 | g_revoked_count = 0; | 72 | g_revoked_count = 0; |
| 79 | session_revoke(s); | 73 | session_revoke(s); |
| @@ -81,10 +75,8 @@ static void test_sessions(void) | |||
| 81 | ASSERT_EQ_INT(0, session_active_count(), "No active sessions after revoke"); | 75 | ASSERT_EQ_INT(0, session_active_count(), "No active sessions after revoke"); |
| 82 | 76 | ||
| 83 | printf("\n--- session_revoke_all ---\n"); | 77 | printf("\n--- session_revoke_all ---\n"); |
| 84 | const char *s1[] = {"s1"}; | 78 | session_create(0x01000001, 60000); |
| 85 | const char *s2[] = {"s2"}; | 79 | session_create(0x01000002, 60000); |
| 86 | session_create(0x01000001, 60000, s1, 1); | ||
| 87 | session_create(0x01000002, 60000, s2, 1); | ||
| 88 | ASSERT_EQ_INT(2, session_active_count(), "2 sessions created"); | 80 | ASSERT_EQ_INT(2, session_active_count(), "2 sessions created"); |
| 89 | 81 | ||
| 90 | g_revoked_count = 0; | 82 | g_revoked_count = 0; |
| @@ -93,8 +85,7 @@ static void test_sessions(void) | |||
| 93 | 85 | ||
| 94 | printf("\n--- session_tick does not crash ---\n"); | 86 | printf("\n--- session_tick does not crash ---\n"); |
| 95 | session_manager_init(); | 87 | session_manager_init(); |
| 96 | const char *st[] = {"tick_secret"}; | 88 | session_create(0x0A000001, 60000); |
| 97 | session_create(0x0A000001, 60000, st, 1); | ||
| 98 | session_tick(); | 89 | session_tick(); |
| 99 | ASSERT_EQ_INT(1, session_active_count(), "Session still active after tick (not expired)"); | 90 | ASSERT_EQ_INT(1, session_active_count(), "Session still active after tick (not expired)"); |
| 100 | } | 91 | } |
| @@ -106,9 +97,8 @@ void test_bytes_sessions(void) | |||
| 106 | memset(&g_test_config, 0, sizeof(g_test_config)); | 97 | memset(&g_test_config, 0, sizeof(g_test_config)); |
| 107 | strncpy(g_test_config.metric, "bytes", sizeof(g_test_config.metric) - 1); | 98 | strncpy(g_test_config.metric, "bytes", sizeof(g_test_config.metric) - 1); |
| 108 | 99 | ||
| 109 | const char *sec[] = {"bytes_secret"}; | ||
| 110 | uint64_t allotment = 22020096; | 100 | uint64_t allotment = 22020096; |
| 111 | session_t *s = session_create_bytes(0x0A010001, allotment, sec, 1); | 101 | session_t *s = session_create_bytes(0x0A010001, allotment); |
| 112 | ASSERT(s != NULL, "bytes session created"); | 102 | ASSERT(s != NULL, "bytes session created"); |
| 113 | ASSERT_EQ_INT(1, session_active_count(), "1 active bytes session"); | 103 | ASSERT_EQ_INT(1, session_active_count(), "1 active bytes session"); |
| 114 | 104 | ||
| @@ -133,8 +123,7 @@ void test_bytes_sessions(void) | |||
| 133 | session_manager_init(); | 123 | session_manager_init(); |
| 134 | memset(&g_test_config, 0, sizeof(g_test_config)); | 124 | memset(&g_test_config, 0, sizeof(g_test_config)); |
| 135 | strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1); | 125 | strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1); |
| 136 | const char *ms_sec[] = {"ms_secret"}; | 126 | session_t *ms = session_create(0x0A020001, 60000); |
| 137 | session_t *ms = session_create(0x0A020001, 60000, ms_sec, 1); | ||
| 138 | ASSERT(ms != NULL, "ms session created"); | 127 | ASSERT(ms != NULL, "ms session created"); |
| 139 | ASSERT(!session_is_expired(ms), "ms session not expired immediately"); | 128 | ASSERT(!session_is_expired(ms), "ms session not expired immediately"); |
| 140 | 129 | ||
diff --git a/tests/unit/test_tollgate_client b/tests/unit/test_tollgate_client index 33b272e..f9b0f7d 100755 --- a/tests/unit/test_tollgate_client +++ b/tests/unit/test_tollgate_client | |||
| Binary files differ | |||