diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 52cce1a..56d4d72 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index 7668e38..ebec8a6 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/freebsd-x64/dvtws b/binaries/freebsd-x64/dvtws index 0db5d9a..535a050 100755 Binary files a/binaries/freebsd-x64/dvtws and b/binaries/freebsd-x64/dvtws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index 39b09a7..3249cc5 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index 4c5b95c..fd46fbc 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index af7e936..9a9d15d 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 8886fa0..7d5fd8a 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 682a057..774e8bf 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 020a683..cd4e29d 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/darkmagic.c b/nfq/darkmagic.c index 5af8ead..f98b2dc 100644 --- a/nfq/darkmagic.c +++ b/nfq/darkmagic.c @@ -56,6 +56,16 @@ uint8_t tcp_find_scale_factor(const struct tcphdr *tcp) if (scale && scale[1]==3) return scale[2]; return SCALE_NONE; } +bool tcp_has_fastopen(const struct tcphdr *tcp) +{ + uint8_t *opt; + // new style RFC7413 + opt = tcp_find_option((struct tcphdr*)tcp, 34); + if (opt) return true; + // old style RFC6994 + opt = tcp_find_option((struct tcphdr*)tcp, 254); + return opt && opt[1]>=4 && opt[2]==0xF9 && opt[3]==0x89; +} // n prefix (nsport, nwsize) means network byte order static void fill_tcphdr( diff --git a/nfq/darkmagic.h b/nfq/darkmagic.h index a538cf0..c0be6f8 100644 --- a/nfq/darkmagic.h +++ b/nfq/darkmagic.h @@ -132,6 +132,7 @@ void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,const st uint8_t *tcp_find_option(struct tcphdr *tcp, uint8_t kind); uint32_t *tcp_find_timestamps(struct tcphdr *tcp); uint8_t tcp_find_scale_factor(const struct tcphdr *tcp); +bool tcp_has_fastopen(const struct tcphdr *tcp); // auto creates internal socket and uses it for subsequent calls bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len); diff --git a/nfq/desync.c b/nfq/desync.c index 120e092..3eb74f8 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -456,6 +456,17 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, return res; break; case DESYNC_SYNDATA: + // make sure we are not breaking TCP fast open + if (tcp_has_fastopen(tcphdr)) + { + DLOG("received SYN with TCP fast open option. syndata desync is not applied.\n"); + break; + } + if (len_payload) + { + DLOG("received SYN with data payload. syndata desync is not applied.\n"); + break; + } pkt1_len = sizeof(pkt1); if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps, ttl_orig,0,0,0, params.fake_syndata,params.fake_syndata_size, pkt1,&pkt1_len))