fix: WS frame parser — skip oversized payload to keep sync

- ws_client.c: When payload exceeds buffer, consume remaining bytes
  before returning error to prevent parser desynchronization.
- market_feed.c: Increase receive buffer 4K→64K, support both
  standard (symbol/timestamp) and compact (s/ts) JSON field names.
- ws_client.c: Disable per-frame debug print in release mode.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
wxj
2026-07-01 12:53:33 +00:00
co-authored by Claude
parent db0f2463ff
commit 9a596e65e1
2 changed files with 16 additions and 6 deletions
+6 -4
View File
@@ -351,7 +351,7 @@ int main(int argc, char *argv[])
rte_ring_sp_enqueue_burst(ring->in, (void **)rx, nb_rx, NULL); rte_ring_sp_enqueue_burst(ring->in, (void **)rx, nb_rx, NULL);
/* Receive WebSocket frame */ /* Receive WebSocket frame */
uint8_t buf[4096]; uint8_t buf[65536];
int opcode = 0, buflen = sizeof(buf); int opcode = 0, buflen = sizeof(buf);
int ws_ret = ws_recv_frame(sockfd, &opcode, buf, &buflen); int ws_ret = ws_recv_frame(sockfd, &opcode, buf, &buflen);
@@ -360,11 +360,13 @@ int main(int argc, char *argv[])
buf[buflen] = '\0'; buf[buflen] = '\0';
uint64_t now_us = rte_get_timer_cycles() * 1000000 / tsc_hz; uint64_t now_us = rte_get_timer_cycles() * 1000000 / tsc_hz;
/* Parse symbol and timestamp from JSON */ /* Parse symbol and timestamp from JSON (supports compact & full keys) */
char sym[32] = "unknown"; char sym[32] = "unknown";
uint64_t ts_us = 0; uint64_t ts_us = 0;
json_get_str((char *)buf, "symbol", sym, sizeof(sym)); if (json_get_str((char *)buf, "symbol", sym, sizeof(sym)) < 0)
json_get_int((char *)buf, "timestamp", &ts_us); json_get_str((char *)buf, "s", sym, sizeof(sym)); /* compact format */
if (json_get_int((char *)buf, "timestamp", &ts_us) < 0)
json_get_int((char *)buf, "ts", &ts_us); /* compact format */
int idx = stats_find_or_add(sym); int idx = stats_find_or_add(sym);
if (idx >= 0 && ts_us > 0 && now_us > ts_us) if (idx >= 0 && ts_us > 0 && now_us > ts_us)
+10 -2
View File
@@ -314,7 +314,7 @@ int ws_recv_frame(int sockfd, int *opcode, uint8_t *buf, int *buflen)
static int frame_count = 0; static int frame_count = 0;
frame_count++; frame_count++;
if (frame_count <= 3 || *opcode != 0x01) if (0) /* debug disabled — enable for parser troubleshooting */
printf("[WS DEBUG #%d] byte0=0x%02x byte1=0x%02x opcode=%d fin=%d masked=%d plen=%lu\n", printf("[WS DEBUG #%d] byte0=0x%02x byte1=0x%02x opcode=%d fin=%d masked=%d plen=%lu\n",
frame_count, byte0, byte1, *opcode, fin, masked, payload_len); frame_count, byte0, byte1, *opcode, fin, masked, payload_len);
@@ -386,8 +386,16 @@ int ws_recv_frame(int sockfd, int *opcode, uint8_t *buf, int *buflen)
/* Read payload */ /* Read payload */
if (payload_len > (uint64_t)(*buflen)) if (payload_len > (uint64_t)(*buflen))
{ {
printf("[WS] WARNING: payload %lu > buffer %d\n", printf("[WS] WARNING: payload %lu > buffer %d, skipping\n",
payload_len, *buflen); payload_len, *buflen);
/* Consume (skip) oversized payload to keep parser in sync */
uint64_t remain = payload_len;
uint8_t skip_buf[2048];
while (remain > 0) {
int chunk = (int)(remain < sizeof(skip_buf) ? remain : sizeof(skip_buf));
if (ws_read(sockfd, skip_buf, chunk) <= 0) break;
remain -= chunk;
}
return -1; return -1;
} }