Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-14 06:13:09 +00:00

nfqws2: fix tls reasm

This commit is contained in:
bol-van
2026-01-11 18:20:29 +03:00
parent f93c6de772
commit e6206c5a5f

View File

@@ -1280,80 +1280,79 @@ static uint8_t dpi_desync_tcp_packet_play(
process_retrans_fail(ctrack, dis, (struct sockaddr*)&src, ifin);
t_protocol_probe testers[] = {
{L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial},
{L7P_HTTP_REQ,L7_HTTP,IsHttp,false},
{L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false},
{L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false}
};
protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ctrack, &l7proto, &l7payload);
if (l7payload==L7P_UNKNOWN)
// do not detect payload if reasm is in progress
if (!ctrack || ReasmIsEmpty(&ctrack->reasm_client))
{
// this is special type. detection requires AES and can be successful only for the first data packet. no reason to AES every packet
if (ctrack && (ctrack->pos.client.seq_last - ctrack->pos.client.seq0)==1)
t_protocol_probe testers[] = {
{L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial},
{L7P_HTTP_REQ,L7_HTTP,IsHttp,false},
{L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false},
{L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false}
};
protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ctrack, &l7proto, &l7payload);
if (l7payload==L7P_UNKNOWN)
{
t_protocol_probe testers[] = {
{L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto}
};
protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ctrack, &l7proto, &l7payload);
// this is special type. detection requires AES and can be successful only for the first data packet. no reason to AES every packet
if (ctrack && (ctrack->pos.client.seq_last - ctrack->pos.client.seq0)==1)
{
t_protocol_probe testers[] = {
{L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto}
};
protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ctrack, &l7proto, &l7payload);
}
}
}
switch(l7payload)
if (l7payload==L7P_HTTP_REQ)
{
case L7P_HTTP_REQ:
// we do not reassemble http
reasm_client_cancel(ctrack);
bHaveHost = HttpExtractHost(rdata_payload, rlen_payload, host, sizeof(host));
if (!bHaveHost)
{
DLOG("not applying tampering to HTTP without Host:\n");
goto pass;
}
break;
case L7P_TLS_CLIENT_HELLO:
{
bool bReqFull = IsTLSRecordFull(rdata_payload, rlen_payload);
DLOG(bReqFull ? "TLS ClientHello is FULL\n" : "TLS ClientHello is PARTIAL\n");
if (bReqFull) TLSDebug(rdata_payload, rlen_payload);
bHaveHost = TLSHelloExtractHost(rdata_payload, rlen_payload, host, sizeof(host), true);
if (ctrack && !l7_payload_match(l7payload, params.reasm_payload_disable))
{
// do not reasm retransmissions
if (!bReqFull && ReasmIsEmpty(&ctrack->reasm_client) && !is_retransmission(&ctrack->pos.client))
{
// do not reconstruct unexpected large payload (they are feeding garbage ?)
if (!reasm_client_start(ctrack, IPPROTO_TCP, TLSRecordLen(dis->data_payload), TCP_MAX_REASM, dis->data_payload, dis->len_payload))
goto pass_reasm_cancel;
}
if (!ReasmIsEmpty(&ctrack->reasm_client))
{
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &ctrack->pos, &dst, fwmark, desync_fwmark, ifin, ifout))
{
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
}
else
{
DLOG_ERR("rawpacket_queue failed !\n");
goto pass_reasm_cancel;
}
if (ReasmIsFull(&ctrack->reasm_client))
{
replay_queue(&ctrack->delayed);
reasm_client_fin(ctrack);
}
return VERDICT_DROP;
}
}
break;
}
bHaveHost = HttpExtractHost(rdata_payload, rlen_payload, host, sizeof(host));
if (!bHaveHost)
{
DLOG("not applying tampering to HTTP without Host:\n");
goto pass;
}
}
else if (l7payload==L7P_TLS_CLIENT_HELLO || l7proto==L7_TLS && l7payload==L7P_UNKNOWN && ctrack && !ReasmIsEmpty(&ctrack->reasm_client))
{
l7payload = L7P_TLS_CLIENT_HELLO;
bool bReqFull = IsTLSRecordFull(rdata_payload, rlen_payload);
DLOG(bReqFull ? "TLS client hello is FULL\n" : "TLS client hello is PARTIAL\n");
if (bReqFull) TLSDebug(rdata_payload, rlen_payload);
bHaveHost = TLSHelloExtractHost(rdata_payload, rlen_payload, host, sizeof(host), true);
if (ctrack && !l7_payload_match(l7payload, params.reasm_payload_disable))
{
// do not reasm retransmissions
if (!bReqFull && ReasmIsEmpty(&ctrack->reasm_client) && !is_retransmission(&ctrack->pos.client))
{
// do not reconstruct unexpected large payload (they are feeding garbage ?)
if (!reasm_client_start(ctrack, IPPROTO_TCP, TLSRecordLen(dis->data_payload), TCP_MAX_REASM, dis->data_payload, dis->len_payload))
goto pass_reasm_cancel;
}
if (!ReasmIsEmpty(&ctrack->reasm_client))
{
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &ctrack->pos, &dst, fwmark, desync_fwmark, ifin, ifout))
{
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
}
else
{
DLOG_ERR("rawpacket_queue failed !\n");
goto pass_reasm_cancel;
}
if (ReasmIsFull(&ctrack->reasm_client))
{
replay_queue(&ctrack->delayed);
reasm_client_fin(ctrack);
}
return VERDICT_DROP;
}
}
}
}
if (bHaveHost)