diff --git a/ebpf-sockmap/bpf/sockmap.bpf.c b/ebpf-sockmap/bpf/sockmap.bpf.c index 6fcb8b4..9b8c8e8 100644 --- a/ebpf-sockmap/bpf/sockmap.bpf.c +++ b/ebpf-sockmap/bpf/sockmap.bpf.c @@ -274,9 +274,31 @@ int bpf_sockops_handler(struct bpf_sock_ops *skops) // Redireciona os dados diretamente para o socket par, // pulando toda a pilha de rede. // ───────────────────────────────────────────────────────── +// Acima deste tamanho, NÃO tentamos redirecionar — vai direto pro +// fallback (caminho normal de rede, já comprovado correto e íntegro por +// teste isolado de 500MB via nc). Motivo: evidência em produção (trace +// ao vivo) mostrou que rajadas grandes e sustentadas pelo caminho +// acelerado (BPF_F_INGRESS do sk_msg) corrompem a integridade do byte +// stream o suficiente pra quebrar framing HTTP/2 no cliente +// (ERR_HTTP2_PROTOCOL_ERROR), mesmo com bpf_msg_redirect_hash +// retornando sucesso (SK_PASS) em 100% dos casos — ou seja, o redirect +// "funciona" do ponto de vista da própria chamada, mas os dados que +// chegam do outro lado saem malformados. Não é bug de chave/family (já +// validamos ambos corretos); é uma limitação real do mecanismo de +// redirect desta kernel sob volume alto. Mensagens pequenas (onde a +// aceleração realmente importa — round-trips de banco/cache) continuam +// sendo redirecionadas normalmente; só streams grandes (modelos 3D, +// downloads) ficam de fora do caminho acelerado. +#define SOCKMAP_MAX_REDIRECT_SIZE 16384 + SEC("sk_msg") int bpf_msg_redirect(struct sk_msg_md *msg) { + if (msg->size > SOCKMAP_MAX_REDIRECT_SIZE) { + stats_inc(2); + return SK_PASS; + } + // Construímos a chave do socket PAR (invertendo src/dst). // Se A→B enviou dados, queremos encontrar no mapa a entrada // que B registrou: {sip=B, dip=A, sport=portaB, dport=portaA} @@ -303,9 +325,6 @@ int bpf_msg_redirect(struct sk_msg_md *msg) // Tenta redirecionar diretamente para o socket par. int ret = bpf_msg_redirect_hash(msg, &sock_hash, &key, BPF_F_INGRESS); - // DEBUG TEMPORÁRIO — pra achar o bug de transferência grande. - if (msg->size > 8192) - bpf_printk("MSG grande dip=%x dport=%u size=%u ret=%d", key.dip4, key.dport, msg->size, ret); if (ret == SK_PASS) { stats_inc(1); // Redirecionamento OK — caminho acelerado return SK_PASS;