diff --git a/binaries/armhf/nfqws b/binaries/armhf/nfqws old mode 100755 new mode 100644 index 9eab5c3..89386a0 Binary files a/binaries/armhf/nfqws and b/binaries/armhf/nfqws differ diff --git a/binaries/armhf/tpws b/binaries/armhf/tpws old mode 100755 new mode 100644 index e446221..fd888a0 Binary files a/binaries/armhf/tpws and b/binaries/armhf/tpws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws old mode 100755 new mode 100644 index f47784a..699332e Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-lsb/tpws b/binaries/mips32r1-lsb/tpws old mode 100755 new mode 100644 index a811d3a..ac6eb0d Binary files a/binaries/mips32r1-lsb/tpws and b/binaries/mips32r1-lsb/tpws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws old mode 100755 new mode 100644 index dc7027c..bb48908 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips32r1-msb/tpws b/binaries/mips32r1-msb/tpws old mode 100755 new mode 100644 index 0f0961a..1b1d4ee Binary files a/binaries/mips32r1-msb/tpws and b/binaries/mips32r1-msb/tpws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws old mode 100755 new mode 100644 index 8cab852..5a10397 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/binaries/x86_64/tpws b/binaries/x86_64/tpws old mode 100755 new mode 100644 index c18c800..b115de7 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 0ee221c..2d73b4a 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -247,7 +247,7 @@ struct cbdata_s { int wsize; int qnum; - bool hostcase; + bool hostcase,hostnospace; char hostspell[4]; }; @@ -257,7 +257,7 @@ bool processPacketData(unsigned char *data,int len,const struct cbdata_s *cbdata struct iphdr *iphdr = NULL; struct ip6_hdr *ip6hdr = NULL; struct tcphdr *tcphdr = NULL; - unsigned char *p; + unsigned char *phost,*pua; int len_tcp; bool bRet = false; uint8_t proto; @@ -290,11 +290,29 @@ bool processPacketData(unsigned char *data,int len,const struct cbdata_s *cbdata tcp_rewrite_winsize(tcphdr,(uint16_t)cbdata->wsize); bRet = true; } - if (cbdata->hostcase && (p = find_bin(data,len,"\r\nHost: ",8))) + if ((cbdata->hostcase || cbdata->hostnospace) && (phost = find_bin(data,len,"\r\nHost: ",8))) { - printf("modifying Host: => %c%c%c%c:\n",cbdata->hostspell[0],cbdata->hostspell[1],cbdata->hostspell[2],cbdata->hostspell[3]); - memcpy(p+2,cbdata->hostspell,4); - bRet = true; + if (cbdata->hostcase) + { + printf("modifying Host: => %c%c%c%c:\n",cbdata->hostspell[0],cbdata->hostspell[1],cbdata->hostspell[2],cbdata->hostspell[3]); + memcpy(phost+2,cbdata->hostspell,4); + bRet = true; + } + if (cbdata->hostnospace && (pua = find_bin(data,len,"\r\nUser-Agent: ",14)) && (pua = find_bin(pua+1,len-(pua-data)-1,"\r\n",2))) + { + printf("removing space after Host: and adding it to User-Agent:\n"); + if (pua > phost) + { + memmove(phost+7,phost+8,pua-phost-8); + phost[pua-phost-1] = ' '; + } + else + { + memmove(pua+1,pua,phost-pua+7); + *pua = ' '; + } + bRet = true; + } } if (bRet) { @@ -350,7 +368,14 @@ bool droproot(uid_t uid, gid_t gid) void exithelp() { - printf(" --qnum=\n --wsize=\t; set window size. 0 = do not modify\n --hostcase\t\t; change Host: => host:\n --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n --daemon\t\t; daemonize\n"); + printf( + " --qnum=\n" + " --wsize=\t; set window size. 0 = do not modify\n" + " --hostcase\t\t; change Host: => host:\n" + " --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n" + " --hostnospace\t\t; remove space after Host: and add it to User-Agent: to preserve packet size\n" + " --daemon\t\t; daemonize\n" + ); exit(1); } @@ -377,7 +402,8 @@ int main(int argc, char **argv) {"wsize",required_argument,0,0}, // optidx=2 {"hostcase",no_argument,0,0}, // optidx=3 {"hostspell",required_argument,0,0}, // optidx=4 - {"user",required_argument,0,0}, // optidx=5 + {"hostnospace",no_argument,0,0}, // optidx=5 + {"user",required_argument,0,0}, // optidx=6 {NULL,0,NULL,0} }; if (argc<2) exithelp(); @@ -417,7 +443,10 @@ int main(int argc, char **argv) cbdata.hostcase = true; memcpy(cbdata.hostspell,optarg,4); break; - case 5: /* user */ + case 5: /* hostnospace */ + cbdata.hostnospace = true; + break; + case 6: /* user */ { struct passwd *pwd = getpwnam(optarg); if (!pwd) diff --git a/readme.txt b/readme.txt index 8e2252a..8a47a7d 100644 --- a/readme.txt +++ b/readme.txt @@ -190,7 +190,7 @@ tiera : Требуется сплит http запросов в течение в 3) ipset/get_anizapret.sh. быстро и без нагрузки на роутер получает лист с antizapret.prostovpn.org. 4) ipset/get_combined.sh. для провайдеров, которые блокируют по IP https, а остальное по DPI. IP https заносится в ipset ipban, остальные в ipset zapret. -Поскольку скачивается большой список РКН, требования к месту в /tmp аналоичны 2) +Поскольку скачивается большой список РКН, требования к месту в /tmp аналогичны 2) Все варианты рассмотренных скриптов автоматически создают и заполняют ipset. Варианты 2-4 дополнительно вызывают вариант 1. diff --git a/tpws/tpws.c b/tpws/tpws.c index 1855744..88776eb 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -33,7 +33,7 @@ struct params_s gid_t gid; uint16_t port; bool daemon; - bool hostcase, hostdot, hosttab, methodspace, methodeol, unixeol; + bool hostcase, hostdot, hosttab, hostnospace, methodspace, methodeol, unixeol; char hostspell[4]; enum splithttpreq split_http_req; int split_pos; @@ -117,6 +117,7 @@ bool handle_epollin(tproxy_conn_t *conn, int *data_transferred) { ssize_t method_len=0, split_pos=0, pos; const char **method; bool bIsHttp=false; + char bRemovedHostSpace=0; bs = rd; @@ -164,7 +165,7 @@ bool handle_epollin(tproxy_conn_t *conn, int *data_transferred) { } // search for Host only if required (save some CPU) - if (params.hostdot || params.hosttab || params.hostcase || params.split_http_req==split_host) + if (params.hostdot || params.hosttab || params.hostcase || params.hostnospace || params.split_http_req==split_host) { // we need Host: location pHost=find_bin(buf, bs, "\nHost: ", 7); @@ -185,6 +186,16 @@ bool handle_epollin(tproxy_conn_t *conn, int *data_transferred) { } } + if (pHost && params.hostnospace && pHost[5]==' ') + { + p = pHost + 6; + pos = p - buf; + printf("Removing space before host name at pos %zd\n", pos); + memmove(p - 1, p, bs - pos); + bs--; // block will shrink by 1 byte + bRemovedHostSpace=1; + } + if (params.split_pos) { split_pos = params.split_pos < bs ? params.split_pos : 0; @@ -198,7 +209,7 @@ bool handle_epollin(tproxy_conn_t *conn, int *data_transferred) { break; case split_host: if (pHost) - split_pos = pHost + 6 - buf; + split_pos = pHost + 6 - bRemovedHostSpace - buf; break; } } @@ -429,7 +440,22 @@ int8_t block_sigpipe() { void exithelp() { - printf(" --bind-addr=|\n --port=\n --maxconn=\n --split-http-req=method|host\n --split-pos=\t; split at specified pos. invalidates split-http-req.\n --hostcase\t\t; change Host: => host:\n --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n --hostdot\t\t; add \".\" after Host: name\n --hosttab\t\t; add tab after Host: name\n --methodspace\t\t; add extra space after method\n --methodeol\t\t; add end-of-line before method\n --unixeol\t\t; replace 0D0A to 0A\n --daemon\t\t; daemonize\n --user=\t; drop root privs\n"); + printf( + " --bind-addr=|\n" + " --port=\n --maxconn=\n" + " --split-http-req=method|host\n" + " --split-pos=\t; split at specified pos. invalidates split-http-req.\n" + " --hostcase\t\t; change Host: => host:\n" + " --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n" + " --hostdot\t\t; add \".\" after Host: name\n" + " --hosttab\t\t; add tab after Host: name\n" + " --hostnospace\t\t; remove space after Host:\n" + " --methodspace\t\t; add extra space after method\n" + " --methodeol\t\t; add end-of-line before method\n" + " --unixeol\t\t; replace 0D0A to 0A\n" + " --daemon\t\t; daemonize\n" + " --user=\t; drop root privs\n" + ); exit(1); } @@ -453,12 +479,13 @@ void parse_params(int argc, char *argv[]) { "hostcase",no_argument,0,0 },// optidx=7 { "hostspell",required_argument,0,0 },// optidx=8 { "hostdot",no_argument,0,0 },// optidx=9 - { "split-http-req",required_argument,0,0 },// optidx=10 - { "split-pos",required_argument,0,0 },// optidx=11 - { "methodspace",no_argument,0,0 },// optidx=12 - { "methodeol",no_argument,0,0 },// optidx=13 - { "hosttab",no_argument,0,0 },// optidx=14 - { "unixeol",no_argument,0,0 },// optidx=15 + { "hostnospace",no_argument,0,0 },// optidx=10 + { "split-http-req",required_argument,0,0 },// optidx=11 + { "split-pos",required_argument,0,0 },// optidx=12 + { "methodspace",no_argument,0,0 },// optidx=13 + { "methodeol",no_argument,0,0 },// optidx=14 + { "hosttab",no_argument,0,0 },// optidx=15 + { "unixeol",no_argument,0,0 },// optidx=16 { NULL,0,NULL,0 } }; while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) @@ -521,7 +548,10 @@ void parse_params(int argc, char *argv[]) case 9: /* hostdot */ params.hostdot = true; break; - case 10: /* split-http-req */ + case 10: /* hostnospace */ + params.hostnospace = true; + break; + case 11: /* split-http-req */ if (!strcmp(optarg, "method")) params.split_http_req = split_method; else if (!strcmp(optarg, "host")) @@ -532,7 +562,7 @@ void parse_params(int argc, char *argv[]) exit(1); } break; - case 11: /* split-pos */ + case 12: /* split-pos */ i = atoi(optarg); if (i) params.split_pos = i; @@ -542,16 +572,16 @@ void parse_params(int argc, char *argv[]) exit(1); } break; - case 12: /* methodspace */ + case 13: /* methodspace */ params.methodspace = true; break; - case 13: /* methodeol */ + case 14: /* methodeol */ params.methodeol = true; break; - case 14: /* hosttab */ + case 15: /* hosttab */ params.hosttab = true; break; - case 15: /* unixeol */ + case 16: /* unixeol */ params.unixeol = true; break; }