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 /main/session.c | |
| 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 'main/session.c')
| -rw-r--r-- | main/session.c | 48 |
1 files changed, 3 insertions, 45 deletions
diff --git a/main/session.c b/main/session.c index 4854163..9b4380c 100644 --- a/main/session.c +++ b/main/session.c | |||
| @@ -7,15 +7,10 @@ | |||
| 7 | #include "freertos/task.h" | 7 | #include "freertos/task.h" |
| 8 | #include <string.h> | 8 | #include <string.h> |
| 9 | 9 | ||
| 10 | #define SPENT_SECRETS_MAX 100 | ||
| 11 | |||
| 12 | static const char *TAG = "session"; | 10 | static const char *TAG = "session"; |
| 13 | static session_t s_sessions[SESSION_MAX_CLIENTS]; | 11 | static session_t s_sessions[SESSION_MAX_CLIENTS]; |
| 14 | static int s_session_count = 0; | 12 | static int s_session_count = 0; |
| 15 | 13 | ||
| 16 | static char s_spent_secrets[SPENT_SECRETS_MAX][65]; | ||
| 17 | static int s_spent_count = 0; | ||
| 18 | |||
| 19 | static int64_t get_time_ms(void) | 14 | static int64_t get_time_ms(void) |
| 20 | { | 15 | { |
| 21 | return (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS; | 16 | return (int64_t)xTaskGetTickCount() * portTICK_PERIOD_MS; |
| @@ -25,7 +20,6 @@ esp_err_t session_manager_init(void) | |||
| 25 | { | 20 | { |
| 26 | memset(s_sessions, 0, sizeof(s_sessions)); | 21 | memset(s_sessions, 0, sizeof(s_sessions)); |
| 27 | s_session_count = 0; | 22 | s_session_count = 0; |
| 28 | s_spent_count = 0; | ||
| 29 | ESP_LOGI(TAG, "Session manager initialized"); | 23 | ESP_LOGI(TAG, "Session manager initialized"); |
| 30 | return ESP_OK; | 24 | return ESP_OK; |
| 31 | } | 25 | } |
| @@ -37,27 +31,14 @@ static void populate_mac(session_t *session, uint32_t client_ip) | |||
| 37 | } | 31 | } |
| 38 | } | 32 | } |
| 39 | 33 | ||
| 40 | session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, | 34 | session_t *session_create(uint32_t client_ip, uint64_t allotment_ms) |
| 41 | const char *spent_secrets[], int secret_count) | ||
| 42 | { | 35 | { |
| 43 | session_t *existing = session_find_by_ip(client_ip); | 36 | session_t *existing = session_find_by_ip(client_ip); |
| 44 | if (existing) { | 37 | if (existing) { |
| 45 | session_extend(existing, allotment_ms); | 38 | session_extend(existing, allotment_ms); |
| 46 | for (int i = 0; i < secret_count && s_spent_count < SPENT_SECRETS_MAX; i++) { | ||
| 47 | strncpy(s_spent_secrets[s_spent_count], spent_secrets[i], 64); | ||
| 48 | s_spent_secrets[s_spent_count][64] = '\0'; | ||
| 49 | s_spent_count++; | ||
| 50 | } | ||
| 51 | return existing; | 39 | return existing; |
| 52 | } | 40 | } |
| 53 | 41 | ||
| 54 | for (int i = 0; i < secret_count; i++) { | ||
| 55 | if (session_is_secret_spent(spent_secrets[i])) { | ||
| 56 | ESP_LOGW(TAG, "Duplicate secret rejected"); | ||
| 57 | return NULL; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | if (s_session_count >= SESSION_MAX_CLIENTS) { | 42 | if (s_session_count >= SESSION_MAX_CLIENTS) { |
| 62 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { | 43 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { |
| 63 | if (!s_sessions[i].active || session_is_expired(&s_sessions[i])) { | 44 | if (!s_sessions[i].active || session_is_expired(&s_sessions[i])) { |
| @@ -73,22 +54,8 @@ session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, | |||
| 73 | s_sessions[i].allotment_ms = allotment_ms; | 54 | s_sessions[i].allotment_ms = allotment_ms; |
| 74 | s_sessions[i].start_time_ms = get_time_ms(); | 55 | s_sessions[i].start_time_ms = get_time_ms(); |
| 75 | s_sessions[i].active = true; | 56 | s_sessions[i].active = true; |
| 76 | s_sessions[i].spent_secret_count = 0; | ||
| 77 | populate_mac(&s_sessions[i], client_ip); | 57 | populate_mac(&s_sessions[i], client_ip); |
| 78 | 58 | ||
| 79 | for (int j = 0; j < secret_count && j < 5; j++) { | ||
| 80 | strncpy(s_sessions[i].spent_secrets[s_sessions[i].spent_secret_count], | ||
| 81 | spent_secrets[j], 64); | ||
| 82 | s_sessions[i].spent_secrets[s_sessions[i].spent_secret_count][64] = '\0'; | ||
| 83 | s_sessions[i].spent_secret_count++; | ||
| 84 | } | ||
| 85 | |||
| 86 | for (int j = 0; j < secret_count && s_spent_count < SPENT_SECRETS_MAX; j++) { | ||
| 87 | strncpy(s_spent_secrets[s_spent_count], spent_secrets[j], 64); | ||
| 88 | s_spent_secrets[s_spent_count][64] = '\0'; | ||
| 89 | s_spent_count++; | ||
| 90 | } | ||
| 91 | |||
| 92 | s_session_count++; | 59 | s_session_count++; |
| 93 | firewall_grant_access(client_ip); | 60 | firewall_grant_access(client_ip); |
| 94 | 61 | ||
| @@ -104,10 +71,9 @@ session_t *session_create(uint32_t client_ip, uint64_t allotment_ms, | |||
| 104 | return NULL; | 71 | return NULL; |
| 105 | } | 72 | } |
| 106 | 73 | ||
| 107 | session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes, | 74 | session_t *session_create_bytes(uint32_t client_ip, uint64_t allotment_bytes) |
| 108 | const char *spent_secrets[], int secret_count) | ||
| 109 | { | 75 | { |
| 110 | session_t *s = session_create(client_ip, 0, spent_secrets, secret_count); | 76 | session_t *s = session_create(client_ip, 0); |
| 111 | if (s) { | 77 | if (s) { |
| 112 | s->allotment_bytes = allotment_bytes; | 78 | s->allotment_bytes = allotment_bytes; |
| 113 | s->bytes_consumed = 0; | 79 | s->bytes_consumed = 0; |
| @@ -170,14 +136,6 @@ bool session_is_expired(const session_t *session) | |||
| 170 | return elapsed >= (int64_t)session->allotment_ms; | 136 | return elapsed >= (int64_t)session->allotment_ms; |
| 171 | } | 137 | } |
| 172 | 138 | ||
| 173 | bool session_is_secret_spent(const char *secret) | ||
| 174 | { | ||
| 175 | for (int i = 0; i < s_spent_count; i++) { | ||
| 176 | if (strncmp(s_spent_secrets[i], secret, 64) == 0) return true; | ||
| 177 | } | ||
| 178 | return false; | ||
| 179 | } | ||
| 180 | |||
| 181 | void session_check_expiry(void) | 139 | void session_check_expiry(void) |
| 182 | { | 140 | { |
| 183 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { | 141 | for (int i = 0; i < SESSION_MAX_CLIENTS; i++) { |