mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
Compare commits
No commits in common. "ef7cbc1ec95a141a27bc9e3f99c04d106fb3508a" and "3fc6b86cf5f095d4cbdbb40dadd2068f887abef7" have entirely different histories.
ef7cbc1ec9
...
3fc6b86cf5
@ -280,7 +280,7 @@ static void parse_params(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (plen1 != -1 && ((!params.ipv6 && (plen1>31 || plen2>31)) || (params.ipv6 && (plen1>127 || plen2>127))))
|
if (plen1 != -1 && (!params.ipv6 && (plen1>31 || plen2>31) || params.ipv6 && (plen1>127 || plen2>127)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "invalid parameter for prefix-length\n");
|
fprintf(stderr, "invalid parameter for prefix-length\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define __FAVOR_BSD
|
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
@ -200,6 +200,7 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
|||||||
|
|
||||||
static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse)
|
static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse)
|
||||||
{
|
{
|
||||||
|
bool b_rev;
|
||||||
t_conn conn,connswp;
|
t_conn conn,connswp;
|
||||||
t_conntrack_pool *ctr;
|
t_conntrack_pool *ctr;
|
||||||
|
|
||||||
@ -249,7 +250,7 @@ static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct ip *ip, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
b_rev = tcphdr && tcp_synack_segment(tcphdr);
|
b_rev = tcphdr && tcp_synack_segment(tcphdr);
|
||||||
if ((tcphdr && tcp_syn_segment(tcphdr)) || b_rev || udphdr)
|
if (tcphdr && tcp_syn_segment(tcphdr) || b_rev || udphdr)
|
||||||
{
|
{
|
||||||
if ((ctr=ConntrackNew(pp, b_rev ? &connswp : &conn)))
|
if ((ctr=ConntrackNew(pp, b_rev ? &connswp : &conn)))
|
||||||
{
|
{
|
||||||
@ -297,12 +298,12 @@ void ConntrackPoolPurge(t_conntrack *p)
|
|||||||
HASH_ITER(hh, p->pool , t, tmp) {
|
HASH_ITER(hh, p->pool , t, tmp) {
|
||||||
tidle = tnow - t->track.t_last;
|
tidle = tnow - t->track.t_last;
|
||||||
if ( t->track.b_cutoff ||
|
if ( t->track.b_cutoff ||
|
||||||
(t->conn.l4proto==IPPROTO_TCP && (
|
t->conn.l4proto==IPPROTO_TCP && (
|
||||||
(t->track.state==SYN && tidle>=p->timeout_syn) ||
|
t->track.state==SYN && tidle>=p->timeout_syn ||
|
||||||
(t->track.state==ESTABLISHED && tidle>=p->timeout_established) ||
|
t->track.state==ESTABLISHED && tidle>=p->timeout_established ||
|
||||||
(t->track.state==FIN && tidle>=p->timeout_fin))
|
t->track.state==FIN && tidle>=p->timeout_fin) ||
|
||||||
) || (t->conn.l4proto==IPPROTO_UDP && tidle>=p->timeout_udp)
|
t->conn.l4proto==IPPROTO_UDP &&
|
||||||
)
|
tidle>=p->timeout_udp)
|
||||||
{
|
{
|
||||||
HASH_DEL(p->pool, t); ConntrackFreeElem(t);
|
HASH_DEL(p->pool, t); ConntrackFreeElem(t);
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
// this conntrack is not bullet-proof
|
// this conntrack is not bullet-proof
|
||||||
// its designed to satisfy dpi desync needs only
|
// its designed to satisfy dpi desync needs only
|
||||||
|
|
||||||
#include "packet_queue.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define __FAVOR_BSD
|
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
|
|
||||||
|
#include "packet_queue.h"
|
||||||
|
|
||||||
//#define HASH_BLOOM 20
|
//#define HASH_BLOOM 20
|
||||||
#define HASH_NONFATAL_OOM 1
|
#define HASH_NONFATAL_OOM 1
|
||||||
|
@ -1321,6 +1321,7 @@ static bool logical_net_filter_match_rate_limited(void)
|
|||||||
static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
|
static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
|
||||||
{
|
{
|
||||||
LPSTR errormessage = NULL;
|
LPSTR errormessage = NULL;
|
||||||
|
DWORD errorcode = 0;
|
||||||
HANDLE h, hMutex;
|
HANDLE h, hMutex;
|
||||||
const char *mutex_name = "Global\\winws_windivert_mutex";
|
const char *mutex_name = "Global\\winws_windivert_mutex";
|
||||||
|
|
||||||
@ -1609,6 +1610,7 @@ static bool set_socket_fwmark(int sock, uint32_t fwmark)
|
|||||||
|
|
||||||
static int rawsend_socket(sa_family_t family)
|
static int rawsend_socket(sa_family_t family)
|
||||||
{
|
{
|
||||||
|
int yes=1;
|
||||||
int *sock = rawsend_family_sock(family);
|
int *sock = rawsend_family_sock(family);
|
||||||
if (!sock) return -1;
|
if (!sock) return -1;
|
||||||
|
|
||||||
|
@ -1,30 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "checksum.h"
|
|
||||||
#include "packet_queue.h"
|
|
||||||
#include "pools.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define __FAVOR_BSD
|
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
#ifndef IPV6_FREEBIND
|
#include "checksum.h"
|
||||||
#define IPV6_FREEBIND 78
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
#include "windivert/windivert.h"
|
#include "windivert/windivert.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "packet_queue.h"
|
||||||
|
#include "pools.h"
|
||||||
|
|
||||||
#ifndef IPPROTO_DIVERT
|
#ifndef IPPROTO_DIVERT
|
||||||
#define IPPROTO_DIVERT 258
|
#define IPPROTO_DIVERT 258
|
||||||
#endif
|
#endif
|
||||||
|
13
nfq/desync.c
13
nfq/desync.c
@ -367,9 +367,9 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, struct
|
|||||||
if (proto==IPPROTO_UDP && udp && len_pkt)
|
if (proto==IPPROTO_UDP && udp && len_pkt)
|
||||||
{
|
{
|
||||||
// make malformed udp packet with zero length and invalid checksum
|
// make malformed udp packet with zero length and invalid checksum
|
||||||
udp->uh_ulen = 0; // invalid length. must be >=8
|
udp->len = 0; // invalid length. must be >=8
|
||||||
udp_fix_checksum(udp,sizeof(struct udphdr),ip,ip6);
|
udp_fix_checksum(udp,sizeof(struct udphdr),ip,ip6);
|
||||||
udp->uh_sum ^= htons(0xBEAF);
|
udp->check ^= htons(0xBEAF);
|
||||||
// truncate packet
|
// truncate packet
|
||||||
*len_pkt = (uint8_t*)udp - (ip ? (uint8_t*)ip : (uint8_t*)ip6) + sizeof(struct udphdr);
|
*len_pkt = (uint8_t*)udp - (ip ? (uint8_t*)ip : (uint8_t*)ip6) + sizeof(struct udphdr);
|
||||||
if (ip)
|
if (ip)
|
||||||
@ -652,8 +652,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
return verdict;
|
return verdict;
|
||||||
verdict = ct_new_postnat_fix_tcp(ctrack, ip, ip6hdr, tcphdr);
|
verdict = ct_new_postnat_fix_tcp(ctrack, ip, ip6hdr, tcphdr);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// can do nothing else with SYN packet
|
// can do nothing else with SYN packet
|
||||||
return verdict;
|
return verdict;
|
||||||
@ -958,6 +956,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
return VERDICT_DROP;
|
return VERDICT_DROP;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
// fix code analyzer warning
|
||||||
pkt1_len=0;
|
pkt1_len=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1170,8 +1169,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
return VERDICT_DROP;
|
return VERDICT_DROP;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1264,6 +1261,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
uint8_t clean[16384], *pclean;
|
uint8_t clean[16384], *pclean;
|
||||||
size_t clean_len;
|
size_t clean_len;
|
||||||
|
bool bIsHello = false;
|
||||||
|
|
||||||
if (replay)
|
if (replay)
|
||||||
{
|
{
|
||||||
@ -1477,6 +1475,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
desync_mode = params.desync_mode2;
|
desync_mode = params.desync_mode2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// fix code analyzer warning
|
||||||
pkt1_len=0;
|
pkt1_len=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1580,8 +1579,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt);
|
return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt);
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define __FAVOR_BSD
|
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
@ -239,7 +239,7 @@ void phton64(uint8_t *p, uint64_t v)
|
|||||||
|
|
||||||
bool seq_within(uint32_t s, uint32_t s1, uint32_t s2)
|
bool seq_within(uint32_t s, uint32_t s1, uint32_t s2)
|
||||||
{
|
{
|
||||||
return (s2>=s1 && s>=s1 && s<=s2) || (s2<s1 && (s<=s2 || s>=s1));
|
return s2>=s1 && s>=s1 && s<=s2 || s2<s1 && (s<=s2 || s>=s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipv6_addr_is_zero(const struct in6_addr *a)
|
bool ipv6_addr_is_zero(const struct in6_addr *a)
|
||||||
@ -313,7 +313,7 @@ time_t file_mod_time(const char *filename)
|
|||||||
|
|
||||||
bool pf_in_range(uint16_t port, const port_filter *pf)
|
bool pf_in_range(uint16_t port, const port_filter *pf)
|
||||||
{
|
{
|
||||||
return port && (((!pf->from && !pf->to) || (port>=pf->from && port<=pf->to)) ^ pf->neg);
|
return port && ((!pf->from && !pf->to || port>=pf->from && port<=pf->to) ^ pf->neg);
|
||||||
}
|
}
|
||||||
bool pf_parse(const char *s, port_filter *pf)
|
bool pf_parse(const char *s, port_filter *pf)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +51,6 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
e = zbuf + zsize;
|
e = zbuf + zsize;
|
||||||
while(p<e)
|
while(p<e)
|
||||||
{
|
{
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
|
||||||
if (!addpool(hostlist,&p,e))
|
if (!addpool(hostlist,&p,e))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
||||||
@ -75,7 +74,6 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
while (fgets(s, 256, F))
|
while (fgets(s, 256, F))
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
|
||||||
if (!addpool(hostlist,&p,p+strlen(p)))
|
if (!addpool(hostlist,&p,p+strlen(p)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
||||||
|
10
nfq/nfqws.c
10
nfq/nfqws.c
@ -226,7 +226,7 @@ static int nfq_main(void)
|
|||||||
while ((rv = recv(fd, buf, sizeof(buf), 0)) > 0)
|
while ((rv = recv(fd, buf, sizeof(buf), 0)) > 0)
|
||||||
{
|
{
|
||||||
dohup();
|
dohup();
|
||||||
int r = nfq_handle_packet(h, (char *)buf, rv);
|
int r = nfq_handle_packet(h, buf, rv);
|
||||||
if (r) fprintf(stderr, "nfq_handle_packet error %d\n", r);
|
if (r) fprintf(stderr, "nfq_handle_packet error %d\n", r);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "recv: errno %d\n",errno);
|
fprintf(stderr, "recv: errno %d\n",errno);
|
||||||
@ -579,7 +579,7 @@ static bool parse_cutoff(const char *opt, unsigned int *value, char *mode)
|
|||||||
}
|
}
|
||||||
static bool parse_badseq_increment(const char *opt, uint32_t *value)
|
static bool parse_badseq_increment(const char *opt, uint32_t *value)
|
||||||
{
|
{
|
||||||
if (((opt[0]=='0' && opt[1]=='x') || (opt[0]=='-' && opt[1]=='0' && opt[2]=='x')) && sscanf(opt+2+(opt[0]=='-'), "%X", (int32_t*)value)>0)
|
if ((opt[0]=='0' && opt[1]=='x' || opt[0]=='-' && opt[1]=='0' && opt[2]=='x') && sscanf(opt+2+(opt[0]=='-'), "%X", (int32_t*)value)>0)
|
||||||
{
|
{
|
||||||
if (opt[0]=='-') params.desync_badseq_increment = -params.desync_badseq_increment;
|
if (opt[0]=='-') params.desync_badseq_increment = -params.desync_badseq_increment;
|
||||||
return true;
|
return true;
|
||||||
@ -621,10 +621,10 @@ bool parse_autottl(const char *s, autottl *t)
|
|||||||
switch (sscanf(s,"%u:%u-%u",&delta,&min,&max))
|
switch (sscanf(s,"%u:%u-%u",&delta,&min,&max))
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
if ((delta && !max) || max>255) return false;
|
if (delta && !max || max>255) return false;
|
||||||
t->max=(uint8_t)max;
|
t->max=(uint8_t)max;
|
||||||
case 2:
|
case 2:
|
||||||
if ((delta && !min) || min>255 || min>max) return false;
|
if (delta && !min || min>255 || min>max) return false;
|
||||||
t->min=(uint8_t)min;
|
t->min=(uint8_t)min;
|
||||||
case 1:
|
case 1:
|
||||||
if (delta>255) return false;
|
if (delta>255) return false;
|
||||||
@ -741,7 +741,7 @@ static bool wf_make_filter(
|
|||||||
const char *pf_tcp_src, const char *pf_tcp_dst,
|
const char *pf_tcp_src, const char *pf_tcp_dst,
|
||||||
const char *pf_udp_src, const char *pf_udp_dst)
|
const char *pf_udp_src, const char *pf_udp_dst)
|
||||||
{
|
{
|
||||||
char pf_dst_buf[512],iface[64];
|
char pf_src_buf[512],pf_dst_buf[512],iface[64];
|
||||||
const char *pf_dst;
|
const char *pf_dst;
|
||||||
const char *f_tcpin = *pf_tcp_src ? *params.hostlist_auto_filename ? "(" DIVERT_TCP_INBOUNDS " or (" DIVERT_HTTP_REDIRECT "))" : DIVERT_TCP_INBOUNDS : "";
|
const char *f_tcpin = *pf_tcp_src ? *params.hostlist_auto_filename ? "(" DIVERT_TCP_INBOUNDS " or (" DIVERT_HTTP_REDIRECT "))" : DIVERT_TCP_INBOUNDS : "";
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *
|
|||||||
|
|
||||||
code = HttpReplyCode(data,len);
|
code = HttpReplyCode(data,len);
|
||||||
|
|
||||||
if ((code!=302 && code!=307) || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false;
|
if (code!=302 && code!=307 || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false;
|
||||||
|
|
||||||
// something like : https://censor.net/badpage.php?reason=denied&source=RKN
|
// something like : https://censor.net/badpage.php?reason=denied&source=RKN
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ bool IsTLSRecordFull(const uint8_t *data, size_t len)
|
|||||||
}
|
}
|
||||||
bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
|
bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
|
||||||
{
|
{
|
||||||
return len >= 6 && data[0] == 0x16 && data[1] == 0x03 && data[2] <= 0x03 && data[5] == 0x01 && (bPartialIsOK || TLSRecordLen(data) <= len);
|
return len >= 6 && data[0] == 0x16 && data[1] == 0x03 && data[2] >= 0x01 && data[2] <= 0x03 && data[5] == 0x01 && (bPartialIsOK || TLSRecordLen(data) <= len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TLSHandshakeLen(const uint8_t *data)
|
size_t TLSHandshakeLen(const uint8_t *data)
|
||||||
@ -210,7 +210,7 @@ bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const
|
|||||||
// <CompressionMethods>
|
// <CompressionMethods>
|
||||||
// u16 ExtensionsLength
|
// u16 ExtensionsLength
|
||||||
|
|
||||||
size_t l;
|
size_t l, ll;
|
||||||
|
|
||||||
if (!bPartialIsOK && !IsTLSHandshakeFull(data,len)) return false;
|
if (!bPartialIsOK && !IsTLSHandshakeFull(data,len)) return false;
|
||||||
|
|
||||||
|
@ -140,10 +140,10 @@ bool samappedcmp(const struct sockaddr_in *sa1,const struct sockaddr_in6 *sa2)
|
|||||||
}
|
}
|
||||||
bool sacmp(const struct sockaddr *sa1,const struct sockaddr *sa2)
|
bool sacmp(const struct sockaddr *sa1,const struct sockaddr *sa2)
|
||||||
{
|
{
|
||||||
return (sa1->sa_family==AF_INET && sa2->sa_family==AF_INET && !memcmp(&((struct sockaddr_in*)sa1)->sin_addr,&((struct sockaddr_in*)sa2)->sin_addr,sizeof(struct in_addr))) ||
|
return sa1->sa_family==AF_INET && sa2->sa_family==AF_INET && !memcmp(&((struct sockaddr_in*)sa1)->sin_addr,&((struct sockaddr_in*)sa2)->sin_addr,sizeof(struct in_addr)) ||
|
||||||
(sa1->sa_family==AF_INET6 && sa2->sa_family==AF_INET6 && !memcmp(&((struct sockaddr_in6*)sa1)->sin6_addr,&((struct sockaddr_in6*)sa2)->sin6_addr,sizeof(struct in6_addr))) ||
|
sa1->sa_family==AF_INET6 && sa2->sa_family==AF_INET6 && !memcmp(&((struct sockaddr_in6*)sa1)->sin6_addr,&((struct sockaddr_in6*)sa2)->sin6_addr,sizeof(struct in6_addr)) ||
|
||||||
(sa1->sa_family==AF_INET && sa2->sa_family==AF_INET6 && samappedcmp((struct sockaddr_in*)sa1,(struct sockaddr_in6*)sa2)) ||
|
sa1->sa_family==AF_INET && sa2->sa_family==AF_INET6 && samappedcmp((struct sockaddr_in*)sa1,(struct sockaddr_in6*)sa2) ||
|
||||||
(sa1->sa_family==AF_INET6 && sa2->sa_family==AF_INET && samappedcmp((struct sockaddr_in*)sa2,(struct sockaddr_in6*)sa1));
|
sa1->sa_family==AF_INET6 && sa2->sa_family==AF_INET && samappedcmp((struct sockaddr_in*)sa2,(struct sockaddr_in6*)sa1);
|
||||||
}
|
}
|
||||||
uint16_t saport(const struct sockaddr *sa)
|
uint16_t saport(const struct sockaddr *sa)
|
||||||
{
|
{
|
||||||
@ -154,7 +154,7 @@ bool saconvmapped(struct sockaddr_storage *a)
|
|||||||
{
|
{
|
||||||
if ((a->ss_family == AF_INET6) && saismapped((struct sockaddr_in6*)a))
|
if ((a->ss_family == AF_INET6) && saismapped((struct sockaddr_in6*)a))
|
||||||
{
|
{
|
||||||
uint32_t ip4 = IN6_EXTRACT_MAP4(((struct sockaddr_in6*)a)->sin6_addr.s6_addr);
|
uint32_t ip4 = *(uint32_t*)(((struct sockaddr_in6*)a)->sin6_addr.s6_addr+12);
|
||||||
uint16_t port = ((struct sockaddr_in6*)a)->sin6_port;
|
uint16_t port = ((struct sockaddr_in6*)a)->sin6_port;
|
||||||
a->ss_family = AF_INET;
|
a->ss_family = AF_INET;
|
||||||
((struct sockaddr_in*)a)->sin_addr.s_addr = ip4;
|
((struct sockaddr_in*)a)->sin_addr.s_addr = ip4;
|
||||||
@ -166,13 +166,11 @@ bool saconvmapped(struct sockaddr_storage *a)
|
|||||||
|
|
||||||
bool is_localnet(const struct sockaddr *a)
|
bool is_localnet(const struct sockaddr *a)
|
||||||
{
|
{
|
||||||
// match 127.0.0.0/8, 0.0.0.0, ::1, ::0, :ffff:127.0.0.0/104, :ffff:0.0.0.0
|
// 0.0.0.0, ::ffff:0.0.0.0 = localhost in linux
|
||||||
return (a->sa_family==AF_INET && (IN_LOOPBACK(htonl(((struct sockaddr_in *)a)->sin_addr.s_addr)) ||
|
return a->sa_family==AF_INET && (*(char*)&((struct sockaddr_in *)a)->sin_addr.s_addr==127 || !((struct sockaddr_in *)a)->sin_addr.s_addr) ||
|
||||||
INADDR_ANY == (((struct sockaddr_in *)a)->sin_addr.s_addr))) ||
|
a->sa_family==AF_INET6 && (
|
||||||
(a->sa_family==AF_INET6 && (IN6_IS_ADDR_LOOPBACK(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr) ||
|
saismapped((struct sockaddr_in6 *)a) && (((struct sockaddr_in6 *)a)->sin6_addr.s6_addr[12]==127 || !*(uint32_t*)(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr+12)) ||
|
||||||
IN6_IS_ADDR_UNSPECIFIED(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr) ||
|
!memcmp(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",15) && !(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr[15] & 0xFE));
|
||||||
(IN6_IS_ADDR_V4MAPPED(((struct sockaddr_in6 *)a)->sin6_addr.s6_addr) && (IN_LOOPBACK(htonl(IN6_EXTRACT_MAP4(((struct sockaddr_in6*)a)->sin6_addr.s6_addr))) ||
|
|
||||||
INADDR_ANY == IN6_EXTRACT_MAP4(((struct sockaddr_in6*)a)->sin6_addr.s6_addr)))));
|
|
||||||
}
|
}
|
||||||
bool is_linklocal(const struct sockaddr_in6 *a)
|
bool is_linklocal(const struct sockaddr_in6 *a)
|
||||||
{
|
{
|
||||||
@ -236,7 +234,7 @@ time_t file_mod_time(const char *filename)
|
|||||||
|
|
||||||
bool pf_in_range(uint16_t port, const port_filter *pf)
|
bool pf_in_range(uint16_t port, const port_filter *pf)
|
||||||
{
|
{
|
||||||
return port && (((!pf->from && !pf->to) || (port>=pf->from && port<=pf->to)) ^ pf->neg);
|
return port && ((!pf->from && !pf->to || port>=pf->from && port<=pf->to) ^ pf->neg);
|
||||||
}
|
}
|
||||||
bool pf_parse(const char *s, port_filter *pf)
|
bool pf_parse(const char *s, port_filter *pf)
|
||||||
{
|
{
|
||||||
|
@ -55,16 +55,3 @@ typedef struct
|
|||||||
} port_filter;
|
} port_filter;
|
||||||
bool pf_in_range(uint16_t port, const port_filter *pf);
|
bool pf_in_range(uint16_t port, const port_filter *pf);
|
||||||
bool pf_parse(const char *s, port_filter *pf);
|
bool pf_parse(const char *s, port_filter *pf);
|
||||||
|
|
||||||
#ifndef IN_LOOPBACK
|
|
||||||
#define IN_LOOPBACK(a) ((((uint32_t) (a)) & 0xff000000) == 0x7f000000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define IN6_EXTRACT_MAP4(a) \
|
|
||||||
(__extension__ \
|
|
||||||
({ const struct in6_addr *__a = (const struct in6_addr *) (a); \
|
|
||||||
(((const uint32_t *) (__a))[3]); }))
|
|
||||||
#else
|
|
||||||
#define IN6_EXTRACT_MAP4(a) (((const uint32_t *) (a))[3])
|
|
||||||
#endif
|
|
||||||
|
@ -51,7 +51,6 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
e = zbuf + zsize;
|
e = zbuf + zsize;
|
||||||
while(p<e)
|
while(p<e)
|
||||||
{
|
{
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
|
||||||
if (!addpool(hostlist,&p,e))
|
if (!addpool(hostlist,&p,e))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
||||||
@ -75,7 +74,6 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
while (fgets(s, 256, F))
|
while (fgets(s, 256, F))
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
|
||||||
if (!addpool(hostlist,&p,p+strlen(p)))
|
if (!addpool(hostlist,&p,p+strlen(p)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
fprintf(stderr, "Not enough memory to store host list : %s\n", filename);
|
||||||
|
@ -104,7 +104,7 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *
|
|||||||
|
|
||||||
code = HttpReplyCode(data,len);
|
code = HttpReplyCode(data,len);
|
||||||
|
|
||||||
if ((code!=302 && code!=307) || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false;
|
if (code!=302 && code!=307 || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false;
|
||||||
|
|
||||||
// something like : https://censor.net/badpage.php?reason=denied&source=RKN
|
// something like : https://censor.net/badpage.php?reason=denied&source=RKN
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ bool IsTLSRecordFull(const uint8_t *data, size_t len)
|
|||||||
}
|
}
|
||||||
bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
|
bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
|
||||||
{
|
{
|
||||||
return len >= 6 && data[0] == 0x16 && data[1] == 0x03 && data[2] <= 0x03 && data[5] == 0x01 && (bPartialIsOK || TLSRecordLen(data) <= len);
|
return len >= 6 && data[0] == 0x16 && data[1] == 0x03 && data[2] >= 0x01 && data[2] <= 0x03 && data[5] == 0x01 && (bPartialIsOK || TLSRecordLen(data) <= len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bPartialIsOK=true - accept partial packets not containing the whole TLS message
|
// bPartialIsOK=true - accept partial packets not containing the whole TLS message
|
||||||
|
@ -66,8 +66,8 @@ typedef struct
|
|||||||
};
|
};
|
||||||
} s5_req;
|
} s5_req;
|
||||||
#define S5_REQ_HEADER_VALID(r,l) (l>=4 && r->ver==5)
|
#define S5_REQ_HEADER_VALID(r,l) (l>=4 && r->ver==5)
|
||||||
#define S5_IP46_VALID(r,l) ((r->atyp==S5_ATYP_IP4 && l>=(4+sizeof(r->d4))) || (r->atyp==S5_ATYP_IP6 && l>=(4+sizeof(r->d6))))
|
#define S5_IP46_VALID(r,l) (r->atyp==S5_ATYP_IP4 && l>=(4+sizeof(r->d4)) || r->atyp==S5_ATYP_IP6 && l>=(4+sizeof(r->d6)))
|
||||||
#define S5_REQ_CONNECT_VALID(r,l) (S5_REQ_HEADER_VALID(r,l) && r->cmd==S5_CMD_CONNECT && (S5_IP46_VALID(r,l) || (r->atyp==S5_ATYP_DOM && l>=5 && l>=(5+r->dd.len))))
|
#define S5_REQ_CONNECT_VALID(r,l) (S5_REQ_HEADER_VALID(r,l) && r->cmd==S5_CMD_CONNECT && (S5_IP46_VALID(r,l) || r->atyp==S5_ATYP_DOM && l>=5 && l>=(5+r->dd.len)))
|
||||||
#define S5_PORT_FROM_DD(r,l) (l>=(4+r->dd.len+2) ? ntohs(*(uint16_t*)(r->dd.domport+r->dd.len)) : 0)
|
#define S5_PORT_FROM_DD(r,l) (l>=(4+r->dd.len+2) ? ntohs(*(uint16_t*)(r->dd.domport+r->dd.len)) : 0)
|
||||||
|
|
||||||
#define S5_REP_OK 0
|
#define S5_REP_OK 0
|
||||||
|
@ -15,6 +15,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
|||||||
size_t method_len = 0, pos;
|
size_t method_len = 0, pos;
|
||||||
const char *method;
|
const char *method;
|
||||||
bool bBypass = false, bHaveHost = false, bHostExcluded = false;
|
bool bBypass = false, bHaveHost = false, bHostExcluded = false;
|
||||||
|
char bRemovedHostSpace = 0;
|
||||||
char *pc, Host[256];
|
char *pc, Host[256];
|
||||||
|
|
||||||
DBGPRINT("tamper_out")
|
DBGPRINT("tamper_out")
|
||||||
@ -118,6 +119,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
|||||||
VPRINT("Removing space before host name at pos %zu", pos)
|
VPRINT("Removing space before host name at pos %zu", pos)
|
||||||
memmove(p - 1, p, *size - pos);
|
memmove(p - 1, p, *size - pos);
|
||||||
(*size)--; // block will shrink by 1 byte
|
(*size)--; // block will shrink by 1 byte
|
||||||
|
bRemovedHostSpace = 1;
|
||||||
}
|
}
|
||||||
if (params.hostcase && HttpFindHost(&pHost,segment,*size))
|
if (params.hostcase && HttpFindHost(&pHost,segment,*size))
|
||||||
{
|
{
|
||||||
@ -183,6 +185,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
|||||||
else if (IsTLSClientHello(segment,*size,false))
|
else if (IsTLSClientHello(segment,*size,false))
|
||||||
{
|
{
|
||||||
size_t tpos=0,spos=0;
|
size_t tpos=0,spos=0;
|
||||||
|
const uint8_t *ext;
|
||||||
|
|
||||||
if (!ctrack->l7proto) ctrack->l7proto=TLS;
|
if (!ctrack->l7proto) ctrack->l7proto=TLS;
|
||||||
|
|
||||||
|
13
tpws/tpws.c
13
tpws/tpws.c
@ -850,6 +850,7 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind
|
|||||||
{
|
{
|
||||||
struct ifaddrs *addrs,*a;
|
struct ifaddrs *addrs,*a;
|
||||||
bool found=false;
|
bool found=false;
|
||||||
|
bool bindll_want = bindll==prefer || bindll==force;
|
||||||
|
|
||||||
if (getifaddrs(&addrs)<0)
|
if (getifaddrs(&addrs)<0)
|
||||||
return false;
|
return false;
|
||||||
@ -875,13 +876,13 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind
|
|||||||
// ipv6 links locals are fe80::/10
|
// ipv6 links locals are fe80::/10
|
||||||
else if (a->ifa_addr->sa_family==AF_INET6
|
else if (a->ifa_addr->sa_family==AF_INET6
|
||||||
&&
|
&&
|
||||||
((!*bindiface && (bindll==prefer || bindll==force)) ||
|
(!*bindiface && (bindll==prefer || bindll==force) ||
|
||||||
(*bindiface && bind_if6 && !strcmp(a->ifa_name, bindiface)))
|
*bindiface && bind_if6 && !strcmp(a->ifa_name, bindiface))
|
||||||
&&
|
&&
|
||||||
((bindll==force && is_linklocal((struct sockaddr_in6*)a->ifa_addr)) ||
|
(bindll==force && is_linklocal((struct sockaddr_in6*)a->ifa_addr) ||
|
||||||
(bindll==prefer && ((pass==0 && is_linklocal((struct sockaddr_in6*)a->ifa_addr)) || (pass==1 && is_private6((struct sockaddr_in6*)a->ifa_addr)) || pass==2)) ||
|
bindll==prefer && (pass==0 && is_linklocal((struct sockaddr_in6*)a->ifa_addr) || pass==1 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==2) ||
|
||||||
(bindll==no && ((pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr)) || (pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr)))) ||
|
bindll==no && (pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr)) ||
|
||||||
(bindll==unwanted && ((pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr)) || (pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr)) || pass==2)))
|
bindll==unwanted && (pass==0 && is_private6((struct sockaddr_in6*)a->ifa_addr) || pass==1 && !is_linklocal((struct sockaddr_in6*)a->ifa_addr) || pass==2))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
salisten->ss_family = AF_INET6;
|
salisten->ss_family = AF_INET6;
|
||||||
|
@ -336,7 +336,7 @@ static bool proxy_remote_conn_ack(tproxy_conn_t *conn, int sock_err)
|
|||||||
//Returns -1 if something fails, >0 on success (socket fd).
|
//Returns -1 if something fails, >0 on success (socket fd).
|
||||||
static int connect_remote(const struct sockaddr *remote_addr, bool bApplyConnectionFooling)
|
static int connect_remote(const struct sockaddr *remote_addr, bool bApplyConnectionFooling)
|
||||||
{
|
{
|
||||||
int remote_fd = 0, yes = 1, no = 0;
|
int remote_fd = 0, yes = 1, no = 0, v;
|
||||||
|
|
||||||
|
|
||||||
if((remote_fd = socket(remote_addr->sa_family, SOCK_STREAM, 0)) < 0)
|
if((remote_fd = socket(remote_addr->sa_family, SOCK_STREAM, 0)) < 0)
|
||||||
@ -625,7 +625,7 @@ static bool check_connection_attempt(tproxy_conn_t *conn, int efd)
|
|||||||
if (!errn)
|
if (!errn)
|
||||||
{
|
{
|
||||||
VPRINT("Socket fd=%d (remote) connected", conn->fd)
|
VPRINT("Socket fd=%d (remote) connected", conn->fd)
|
||||||
if (!epoll_set_flow(conn, true, false) || (conn_partner_alive(conn) && !epoll_set_flow(conn->partner, true, false)))
|
if (!epoll_set_flow(conn, true, false) || conn_partner_alive(conn) && !epoll_set_flow(conn->partner, true, false))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -876,7 +876,10 @@ static bool handle_proxy_mode(tproxy_conn_t *conn, struct tailhead *conn_list)
|
|||||||
break;
|
break;
|
||||||
case S5_ATYP_DOM:
|
case S5_ATYP_DOM:
|
||||||
{
|
{
|
||||||
|
struct addrinfo *ai,hints;
|
||||||
|
int r;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
char sport[6];
|
||||||
|
|
||||||
if (params.no_resolve)
|
if (params.no_resolve)
|
||||||
{
|
{
|
||||||
@ -1064,7 +1067,7 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
|
|||||||
{
|
{
|
||||||
DBGPRINT("%s leg fd=%d stream pos : %" PRIu64 "(n%" PRIu64 ")/%" PRIu64, conn->remote ? "remote" : "local", conn->fd, conn->trd,conn->tnrd+1,conn->twr)
|
DBGPRINT("%s leg fd=%d stream pos : %" PRIu64 "(n%" PRIu64 ")/%" PRIu64, conn->remote ? "remote" : "local", conn->fd, conn->trd,conn->tnrd+1,conn->twr)
|
||||||
#ifdef SPLICE_PRESENT
|
#ifdef SPLICE_PRESENT
|
||||||
if (!params.nosplice && (!params.tamper || (conn->remote && conn->partner->track.bTamperInCutoff) || (!conn->remote && !in_tamper_out_range(conn))))
|
if (!params.nosplice && (!params.tamper || conn->remote && conn->partner->track.bTamperInCutoff || !conn->remote && !in_tamper_out_range(conn)))
|
||||||
{
|
{
|
||||||
// incoming data from remote leg we splice without touching
|
// incoming data from remote leg we splice without touching
|
||||||
// pipe is in the local leg, so its in conn->partner->splice_pipe
|
// pipe is in the local leg, so its in conn->partner->splice_pipe
|
||||||
|
Loading…
x
Reference in New Issue
Block a user