mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2025-12-17 12:54:36 +03:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
754ff6ff06 | ||
|
|
3114036d09 | ||
|
|
ae7398035a | ||
|
|
ee009cf107 | ||
|
|
810aef6aed | ||
|
|
c0f43a293e | ||
|
|
03cb084f10 | ||
|
|
abd2e77ca4 | ||
|
|
d2265d3167 | ||
|
|
4fbfeb8956 | ||
|
|
207a2f7004 | ||
|
|
311b26e744 | ||
|
|
e344f5711c | ||
|
|
14fb025468 | ||
|
|
a95fe3ebff | ||
|
|
8a0bef08bf | ||
|
|
cb9cc82fde | ||
|
|
c2784dd79e | ||
|
|
bc95b6f598 | ||
|
|
985a09c73d | ||
|
|
15793fb84f | ||
|
|
f0d42129aa | ||
|
|
83af8cc541 | ||
|
|
62f2953515 | ||
|
|
7b66094f56 | ||
|
|
a6c7169033 | ||
|
|
c8c596f37e | ||
|
|
fb552640b6 | ||
|
|
ed210cdf44 | ||
|
|
dcff8389b3 | ||
|
|
9bb1bc5682 | ||
|
|
16f2a8fb81 | ||
|
|
c517169e94 | ||
|
|
e9ac13bcda | ||
|
|
78ae517871 | ||
|
|
ed45c42c9e | ||
|
|
aab7842a76 | ||
|
|
79bda5c482 | ||
|
|
68bc67685f | ||
|
|
e463f4b4e5 | ||
|
|
1a867ddf9c | ||
|
|
7e43110f74 | ||
|
|
abcca5ea84 | ||
|
|
74822fca16 | ||
|
|
8401dfcc1a | ||
|
|
c4bbd0b8e2 | ||
|
|
6b2f3cfa74 | ||
|
|
d9bf7c3ccd | ||
|
|
ad18fb9854 | ||
|
|
bc82203364 | ||
|
|
9bfce3156e | ||
|
|
f7362094d3 | ||
|
|
f1aece75ae | ||
|
|
60dd3cb004 | ||
|
|
d031ae65bf | ||
|
|
a1fb62ff82 | ||
|
|
46e6c8f2db | ||
|
|
905d3c98a6 | ||
|
|
b08836de50 | ||
|
|
cf1f2a8674 | ||
|
|
16464646a9 | ||
|
|
ba015cf44e | ||
|
|
3837635f2c | ||
|
|
95c5ca81b2 | ||
|
|
bbb7e4cea8 | ||
|
|
15eb10ac68 | ||
|
|
4c846c712d | ||
|
|
4a82fd442d | ||
|
|
b3c9ff8419 | ||
|
|
fc6fd98a62 | ||
|
|
6304328548 | ||
|
|
86867fe678 | ||
|
|
54349a1c31 | ||
|
|
4f18a73239 | ||
|
|
67629fb6ef | ||
|
|
27a6d256f0 | ||
|
|
938dce7333 | ||
|
|
99c403ca62 | ||
|
|
6ee4101f58 | ||
|
|
f94a20d221 | ||
|
|
54f810b6b0 | ||
|
|
55a3a94065 | ||
|
|
8383ecaadf | ||
|
|
8deacbc438 | ||
|
|
1cfd2b1b9f | ||
|
|
766a8ab4ed | ||
|
|
b7190f0e1f | ||
|
|
857aeb2366 | ||
|
|
871670845f | ||
|
|
68a68aede9 | ||
|
|
4a8f7ac4fb | ||
|
|
ee4ce8893c | ||
|
|
406cf2ca68 | ||
|
|
277b1fb4ef | ||
|
|
5494be72ba | ||
|
|
09089e0364 | ||
|
|
c92cd77c51 | ||
|
|
f97a2d04f0 | ||
|
|
d7c681d1a2 | ||
|
|
ab74ddc425 | ||
|
|
cc1676ad92 | ||
|
|
7f59593a28 | ||
|
|
372cc6a45d | ||
|
|
46c4f36de8 | ||
|
|
8911e459d8 | ||
|
|
f4edcf7b4f | ||
|
|
bb8bafb663 | ||
|
|
e25d7432de | ||
|
|
c60dbf7ca7 | ||
|
|
b1273c8e10 | ||
|
|
9e98b478df | ||
|
|
67c226dc7c | ||
|
|
46219e95e7 |
58
.github/ISSUE_TEMPLATE/bug.yml
vendored
58
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,19 +1,53 @@
|
|||||||
name: Bug Report / Сообщение об ошибке
|
name: The program crashes, hangs, certain function does not work / Программа падает, зависает, отдельная функция не работает
|
||||||
description: File a bug report / Сообщить об ошибке в проекте
|
description: File a bug report / Сообщить об ошибке в программе
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Please pay some attention!
|
### Carefully read all the text IN FULL. Take this seriously.
|
||||||
GoodbyeDPI does not guarantee to work on your ISP on 100% or at all. If GoodbyeDPI can't unblock some or any websites, this is most likely not a software bug, and you should not report it.
|
### Use this form only for software bug reports! The website does not open? That's likely NOT a bug, do NOT report it here! You have a question regarding the program? That's not a bug either!
|
||||||
Please report software bugs, such as: website incompatibility (if the website works without GoodbyeDPI but breaks with GoobyeDPI enabled), antivirus incompatibility, DNS redirection problems, incorrect packet handling, and other software issues.
|
#### If in doubt, [use NTC.party forum](https://ntc.party/c/community-software/goodbyedpi).
|
||||||
Please make sure to check other opened and closed issues, it could be your question or issue has been already discussed.
|
### Внимательно прочитайте ВЕСЬ текст ниже. Отнеситесь к этому со всей ответственностью.
|
||||||
|
### Используйте эту форму только для сообщений об ошибках в программе! Неоткрывающиеся сайты таковыми не являются, вопросы по программе к ошибкам не относятся.
|
||||||
|
#### Если у вас есть сомнения, [воспользуйтесь форумом NTC.party](https://ntc.party/c/community-software/goodbyedpi).
|
||||||
|
|
||||||
Пожалуйста, прочтите!
|
GoodbyeDPI does not guarantee to work with your ISP for every blocked website or at all. If GoodbyeDPI can't unblock some or any websites, this is most likely not a software bug, and you should not report it here.
|
||||||
GoodbyeDPI не гарантирует ни 100% работу с вашим провайдером, ни работу вообще. Если GoodbyeDPI не разблокирует доступ к некоторым или всем веб-сайтам, вероятнее всего, это не программная ошибка, и не стоит о ней сообщать здесь.
|
|
||||||
Сообщайте только об ошибках в программе, таких как: некорректная работа с веб-сайтами (когда веб-сайт работает без GoodbyeDPI, но ломается с GoodbyeDPI), несовместимость с антивирусами, проблемы с перенаправлением DNS, некорректная обработка пакетов, и другие проблемы.
|
Please only report software bugs, such as:
|
||||||
Также посмотрите другие открытые и закрытые баги. Возможно, ваш вопрос или проблема уже обсуждались.
|
* program crash
|
||||||
|
* incorrect network packet handling
|
||||||
|
* antivirus incompatibility
|
||||||
|
* DNS redirection problems
|
||||||
|
* memory leaks
|
||||||
|
* other software issues
|
||||||
|
|
||||||
|
Please make sure to check other opened and closed issues, it could be your bug has been reported already.
|
||||||
|
For questions, or if in doubt, [use NTC.party forum](https://ntc.party/c/community-software/goodbyedpi).
|
||||||
|
|
||||||
|
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда!
|
||||||
|
GoodbyeDPI не гарантирует ни 100% работу с вашим провайдером, ни работу с каждым заблокированным сайтом. Если GoodbyeDPI не разблокирует доступ к некоторым или всем веб-сайтам, вероятнее всего, это не программная ошибка, и не стоит о ней сообщать здесь.
|
||||||
|
|
||||||
|
Пожалуйста, сообщайте только об ошибках в программе, таких как:
|
||||||
|
* падение программы
|
||||||
|
* некорректная обработка сетевых пакетов
|
||||||
|
* несовместимость с антивирусами
|
||||||
|
* проблемы с перенаправлением DNS
|
||||||
|
* утечки памяти
|
||||||
|
* другие ошибки в программе
|
||||||
|
|
||||||
|
Также посмотрите другие открытые и закрытые баги. Возможно, ошибка уже обсуждалась или исправлена.
|
||||||
|
Для вопросов, а также в случае сомнений в определении бага, обращайтесь [на форум NTC.party](https://ntc.party/c/community-software/goodbyedpi).
|
||||||
|
- type: checkboxes
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: CAPTCHA
|
||||||
|
description: Confirm that you have read the text above / Подтвердите, что вы прочитали текст выше
|
||||||
|
options:
|
||||||
|
- label: I understand I could be banned from the repository if I misusing issue section not for posting bugs, but for question or 'broken website' report. / Я понимаю, что меня могут заблокировать в репозитории, если я буду использовать раздел issue не для сообщений об ошибках, а для вопросов или сообщении о «неработающем веб-сайте».
|
||||||
|
required: true
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
id: os
|
id: os
|
||||||
attributes:
|
attributes:
|
||||||
@@ -35,8 +69,8 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
id: what-happened
|
id: what-happened
|
||||||
attributes:
|
attributes:
|
||||||
label: Describe the issue / Опишите проблему
|
label: Describe the bug / Опишите ошибку программы
|
||||||
description: A clear and concise description of what the bug is / Подробно опишите, в чём заключается проблема
|
description: A clear and concise description of what the bug is / Подробно опишите, в чём заключается ошибка
|
||||||
placeholder: Attach the screenshots for clarity / При необходимости приложите скриншоты
|
placeholder: Attach the screenshots for clarity / При необходимости приложите скриншоты
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,13 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
|
- name: The program worked yesterday but not today / Программа работала вчера, но перестала работать сегодня
|
||||||
|
url: https://ntc.party/c/community-software/goodbyedpi/8
|
||||||
|
about: Visit support community forum, people will certainly help you! / Посетите форум поддержки, где сообщество вам поможет!
|
||||||
|
|
||||||
|
- name: Сertain website is still unreachable / Отдельный веб-сайт всё ещё недоступен
|
||||||
|
url: https://ntc.party/c/community-software/goodbyedpi/8
|
||||||
|
about: That could be solved with community support! / Проблема будет решена силами сообщества!
|
||||||
|
|
||||||
- name: Questions about the program / Вопросы по програме
|
- name: Questions about the program / Вопросы по програме
|
||||||
url: https://ntc.party/c/community-software/goodbyedpi/8
|
url: https://ntc.party/c/community-software/goodbyedpi/8
|
||||||
about: Please ask and answer questions on forum / Пожалуйста, задавайте вопросы только на форуме
|
about: Please ask and answer questions on forum / Пожалуйста, задавайте вопросы только на форуме
|
||||||
|
|||||||
11
.github/ISSUE_TEMPLATE/feature.yml
vendored
11
.github/ISSUE_TEMPLATE/feature.yml
vendored
@@ -5,8 +5,15 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
If you think of a great function or circumvention method which is missing from the program, go ahead and suggest it here.
|
If you think of a great function or circumvention method which is missing from the program, go ahead and suggest it here. But first make sure to search exiting tickets.
|
||||||
Если вы придумали новую функцию или метод обхода, которого еще нет в программе, напишите о нем подробнее здесь.
|
Если вы придумали новую функцию или метод обхода, которого еще нет в программе, напишите о нем подробнее здесь. Но сначала убедитесь с помощью поиска, что такого запроса еще не было.
|
||||||
|
- type: checkboxes
|
||||||
|
id: ensure
|
||||||
|
attributes:
|
||||||
|
label: I've made sure there's no existing feature request / Я убедился, что такой функциональности еще никто не предлагал
|
||||||
|
options:
|
||||||
|
- label: I've made sure there's no existing feature request / Я убедился, что такой функциональности еще никто не предлагал
|
||||||
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
32
.github/workflows/build.yml
vendored
32
.github/workflows/build.yml
vendored
@@ -4,31 +4,37 @@ on:
|
|||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- 'src/**'
|
- 'src/**'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
WINDIVERT_URL: https://www.reqrypt.org/download/WinDivert-1.4.3-A.zip
|
WINDIVERT_URL: https://reqrypt.org/download/WinDivert-2.2.0-D.zip
|
||||||
WINDIVERT_NAME: WinDivert-1.4.3-A.zip
|
WINDIVERT_NAME: WinDivert-2.2.0-D.zip
|
||||||
WINDIVERT_SHA256: 4084bc3931f31546d375ed89e3f842776efa46f321ed0adcd32d3972a7d02566
|
WINDIVERT_BASENAME: WinDivert-2.2.0-D
|
||||||
|
WINDIVERT_SHA256: 1d461cfdfa7ba88ebcfbb3603b71b703e9f72aba8aeff99a75ce293e6f89d2ba
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Declare short commit variable
|
- name: Declare short commit variable
|
||||||
id: vars
|
id: vars
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Install MinGW-w64
|
- name: Install MinGW-w64
|
||||||
run: >
|
run: >
|
||||||
|
sudo rm /var/lib/man-db/auto-update &&
|
||||||
sudo DEBIAN_FRONTEND=noninteractive XZ_DEFAULTS="-T0" XZ_OPT="-T0" eatmydata
|
sudo DEBIAN_FRONTEND=noninteractive XZ_DEFAULTS="-T0" XZ_OPT="-T0" eatmydata
|
||||||
apt install -y --no-install-recommends gcc-mingw-w64
|
apt install -y --no-install-recommends gcc-mingw-w64
|
||||||
|
|
||||||
- name: Download WinDivert from cache
|
- name: Download WinDivert from cache
|
||||||
id: windivert-cache
|
id: windivert-cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ env. WINDIVERT_NAME }}
|
path: ${{ env. WINDIVERT_NAME }}
|
||||||
key: ${{ env. WINDIVERT_SHA256 }}
|
key: ${{ env. WINDIVERT_SHA256 }}
|
||||||
@@ -45,15 +51,15 @@ jobs:
|
|||||||
- name: Compile x86_64
|
- name: Compile x86_64
|
||||||
run: >
|
run: >
|
||||||
cd src && make clean &&
|
cd src && make clean &&
|
||||||
make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=../WinDivert-1.4.3-A/include WINDIVERTLIBS=../WinDivert-1.4.3-A/x86_64 -j4
|
make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=../${{ env.WINDIVERT_BASENAME }}/include WINDIVERTLIBS=../${{ env.WINDIVERT_BASENAME }}/x64 -j4
|
||||||
|
|
||||||
- name: Prepare x86_64 directory
|
- name: Prepare x86_64 directory
|
||||||
run: |
|
run: |
|
||||||
mkdir goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
mkdir goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
||||||
cp src/goodbyedpi.exe WinDivert-1.4.3-A/x86_64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
- name: Upload output file x86_64 (64 bit)
|
- name: Upload output file x86_64
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
name: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
||||||
path: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
path: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
|
||||||
@@ -61,15 +67,15 @@ jobs:
|
|||||||
- name: Compile i686
|
- name: Compile i686
|
||||||
run: >
|
run: >
|
||||||
cd src && make clean &&
|
cd src && make clean &&
|
||||||
make CPREFIX=i686-w64-mingw32- WINDIVERTHEADERS=../WinDivert-1.4.3-A/include WINDIVERTLIBS=../WinDivert-1.4.3-A/x86 -j4
|
make CPREFIX=i686-w64-mingw32- WINDIVERTHEADERS=../${{ env.WINDIVERT_BASENAME }}/include WINDIVERTLIBS=../${{ env.WINDIVERT_BASENAME }}/x86 -j4
|
||||||
|
|
||||||
- name: Prepare x86 directory
|
- name: Prepare x86 directory
|
||||||
run: |
|
run: |
|
||||||
mkdir goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
mkdir goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||||
cp src/goodbyedpi.exe WinDivert-1.4.3-A/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||||
|
|
||||||
- name: Upload output file x86
|
- name: Upload output file x86
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
name: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||||
path: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
path: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||||
|
|||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
*.exe
|
||||||
78
README.md
78
README.md
@@ -1,19 +1,30 @@
|
|||||||
GoodbyeDPI — Passive Deep Packet Inspection blocker and Active DPI circumvention utility
|
GoodbyeDPI — Deep Packet Inspection circumvention utility
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
This software designed to bypass Deep Packet Inspection systems found in many Internet Service Providers which block access to certain websites.
|
This software designed to bypass Deep Packet Inspection systems found in many Internet Service Providers which block access to certain websites.
|
||||||
|
|
||||||
It handles DPI connected using optical splitter or port mirroring (**Passive DPI**) which do not block any data but just replying faster than requested destination, and **Active DPI** connected in sequence.
|
It handles DPI connected using optical splitter or port mirroring (**Passive DPI**) which do not block any data but just replying faster than requested destination, and **Active DPI** connected in sequence.
|
||||||
|
|
||||||
**Windows 7, 8, 8.1 and 10** with administrator privileges required.
|
**Windows 7, 8, 8.1, 10 or 11** with administrator privileges required.
|
||||||
|
|
||||||
|
# Quick start
|
||||||
|
|
||||||
|
* **For Russia**: Download [latest version from Releases page](https://github.com/ValdikSS/GoodbyeDPI/releases), unpack the file and run **1_russia_blacklist_dnsredir.cmd** script.
|
||||||
|
* For other countries: Download [latest version from Releases page](https://github.com/ValdikSS/GoodbyeDPI/releases), unpack the file and run **2_any_country_dnsredir.cmd**.
|
||||||
|
|
||||||
|
These scripts launch GoodbyeDPI in recommended mode with DNS resolver redirection to Yandex DNS on non-standard port (to prevent DNS poisoning).
|
||||||
|
If it works — congratulations! You can use it as-is or configure further.
|
||||||
|
|
||||||
# How to use
|
# How to use
|
||||||
|
|
||||||
Download [latest version from Releases page](https://github.com/ValdikSS/GoodbyeDPI/releases) and run.
|
Download [latest version from Releases page](https://github.com/ValdikSS/GoodbyeDPI/releases) and run.
|
||||||
|
|
||||||
|
## Supported arguments
|
||||||
|
To get relevant information about your version of the program, use the -h (--help) argument at startup.
|
||||||
```
|
```
|
||||||
Usage: goodbyedpi.exe [OPTION...]
|
Usage: goodbyedpi.exe [OPTION...]
|
||||||
-p block passive DPI
|
-p block passive DPI
|
||||||
|
-q block QUIC/HTTP3
|
||||||
-r replace Host with hoSt
|
-r replace Host with hoSt
|
||||||
-s remove space between host header and its value
|
-s remove space between host header and its value
|
||||||
-m mix Host header case (test.com -> tEsT.cOm)
|
-m mix Host header case (test.com -> tEsT.cOm)
|
||||||
@@ -34,10 +45,18 @@ Usage: goodbyedpi.exe [OPTION...]
|
|||||||
--blacklist <txtfile> perform circumvention tricks only to host names and subdomains from
|
--blacklist <txtfile> perform circumvention tricks only to host names and subdomains from
|
||||||
supplied text file (HTTP Host/TLS SNI).
|
supplied text file (HTTP Host/TLS SNI).
|
||||||
This option can be supplied multiple times.
|
This option can be supplied multiple times.
|
||||||
|
--allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.
|
||||||
|
--frag-by-sni if SNI is detected in TLS packet, fragment the packet right before SNI value.
|
||||||
--set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.
|
--set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.
|
||||||
DANGEROUS! May break websites in unexpected ways. Use with care.
|
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
|
||||||
--auto-ttl [decttl] activate Fake Request Mode, automatically detect TTL and decrease
|
--auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease
|
||||||
it from standard 64 or 128 by decttl (128/64 - TTL - 4 by default).
|
it based on a distance. If the distance is shorter than a2, TTL is decreased
|
||||||
|
by a2. If it's longer, (a1; a2) scale is used with the distance as a weight.
|
||||||
|
If the resulting TTL is more than m(ax), set it to m.
|
||||||
|
Default (if set): --auto-ttl 1-4-10. Also sets --min-ttl 3.
|
||||||
|
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
|
||||||
|
--min-ttl <value> minimum TTL distance (128/64 - TTL) for which to send Fake Request
|
||||||
|
in --set-ttl and --auto-ttl modes.
|
||||||
--wrong-chksum activate Fake Request Mode and send it with incorrect TCP checksum.
|
--wrong-chksum activate Fake Request Mode and send it with incorrect TCP checksum.
|
||||||
May not work in a VM or with some routers, but is safer than set-ttl.
|
May not work in a VM or with some routers, but is safer than set-ttl.
|
||||||
--wrong-seq activate Fake Request Mode and send it with TCP SEQ/ACK in the past.
|
--wrong-seq activate Fake Request Mode and send it with TCP SEQ/ACK in the past.
|
||||||
@@ -47,6 +66,22 @@ Usage: goodbyedpi.exe [OPTION...]
|
|||||||
--reverse-frag fragment (split) the packets just as --native-frag, but send them in the
|
--reverse-frag fragment (split) the packets just as --native-frag, but send them in the
|
||||||
reversed order. Works with the websites which could not handle segmented
|
reversed order. Works with the websites which could not handle segmented
|
||||||
HTTPS TLS ClientHello (because they receive the TCP flow "combined").
|
HTTPS TLS ClientHello (because they receive the TCP flow "combined").
|
||||||
|
--fake-from-hex <value> Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).
|
||||||
|
This option can be supplied multiple times, in this case each fake packet
|
||||||
|
would be sent on every request in the command line argument order.
|
||||||
|
--fake-with-sni <value> Generate fake packets for Fake Request Mode with given SNI domain name.
|
||||||
|
The packets mimic Mozilla Firefox 130 TLS ClientHello packet
|
||||||
|
(with random generated fake SessionID, key shares and ECH grease).
|
||||||
|
Can be supplied multiple times for multiple fake packets.
|
||||||
|
--fake-gen <value> Generate random-filled fake packets for Fake Request Mode, value of them
|
||||||
|
(up to 30).
|
||||||
|
--fake-resend <value> Send each fake packet value number of times.
|
||||||
|
Default: 1 (send each packet once).
|
||||||
|
--max-payload [value] packets with TCP payload data more than [value] won't be processed.
|
||||||
|
Use this option to reduce CPU usage by skipping huge amount of data
|
||||||
|
(like file transfers) in already established sessions.
|
||||||
|
May skip some huge HTTP requests from being processed.
|
||||||
|
Default (if set): --max-payload 1200.
|
||||||
|
|
||||||
|
|
||||||
LEGACY modesets:
|
LEGACY modesets:
|
||||||
@@ -56,18 +91,23 @@ LEGACY modesets:
|
|||||||
-4 -p -r -s (best speed)
|
-4 -p -r -s (best speed)
|
||||||
|
|
||||||
Modern modesets (more stable, more compatible, faster):
|
Modern modesets (more stable, more compatible, faster):
|
||||||
-5 -f 2 -e 2 --auto-ttl --reverse-frag (this is the default)
|
-5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload
|
||||||
-6 -f 2 -e 2 --wrong-seq --reverse-frag
|
-6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload
|
||||||
```
|
-7 -f 2 -e 2 --wrong-chksum --reverse-frag --max-payload
|
||||||
|
-8 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload
|
||||||
|
-9 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload -q (this is the default)
|
||||||
|
|
||||||
|
Note: combination of --wrong-seq and --wrong-chksum generates two different fake packets.
|
||||||
|
```
|
||||||
|
## How to check
|
||||||
To check if your ISP's DPI could be circumvented, first make sure that your provider does not poison DNS answers by enabling "Secure DNS (DNS over HTTPS)" option in your browser.
|
To check if your ISP's DPI could be circumvented, first make sure that your provider does not poison DNS answers by enabling "Secure DNS (DNS over HTTPS)" option in your browser.
|
||||||
|
|
||||||
* **Chrome**: Settings → [Privacy and security](chrome://settings/security) > Use secure DNS → With: NextDNS
|
* **Chrome**: Settings → [Privacy and security](chrome://settings/security) → Use secure DNS → With: NextDNS
|
||||||
* **Firefox**: [Settings](about:preferences) → Network Settings → Enable DNS over HTTPS → Use provider: NextDNS
|
* **Firefox**: [Settings](about:preferences) → Network Settings → Enable DNS over HTTPS → Use provider: NextDNS
|
||||||
|
|
||||||
Then run the `goodbyedpi.exe` executable without any options. If it works — congratulations! You can use it as-is or configure further, for example by using `--blacklist` option if the list of blocked websites is known and available for your country.
|
Then run the `goodbyedpi.exe` executable without any options. If it works — congratulations! You can use it as-is or configure further, for example by using `--blacklist` option if the list of blocked websites is known and available for your country.
|
||||||
|
|
||||||
If your provider intercepts DNS requests, you may want to use `--dns-addr` option to a public DNS resover running on non-standard port (such as Yandex DNS `77.88.8.8:1253`) or configure DNS over HTTPS/TLS using third-party applications.
|
If your provider intercepts DNS requests, you may want to use `--dns-addr` option to a public DNS resolver running on non-standard port (such as Yandex DNS `77.88.8.8:1253`) or configure DNS over HTTPS/TLS using third-party applications.
|
||||||
|
|
||||||
Check the .cmd scripts and modify it according to your preference and network conditions.
|
Check the .cmd scripts and modify it according to your preference and network conditions.
|
||||||
|
|
||||||
@@ -114,17 +154,25 @@ Modify them according to your own needs.
|
|||||||
# Known issues
|
# Known issues
|
||||||
|
|
||||||
* Horribly outdated Windows 7 installations are not able to load WinDivert driver due to missing support for SHA256 digital signatures. Install KB3033929 [x86](https://www.microsoft.com/en-us/download/details.aspx?id=46078)/[x64](https://www.microsoft.com/en-us/download/details.aspx?id=46148), or better, update the whole system using Windows Update.
|
* Horribly outdated Windows 7 installations are not able to load WinDivert driver due to missing support for SHA256 digital signatures. Install KB3033929 [x86](https://www.microsoft.com/en-us/download/details.aspx?id=46078)/[x64](https://www.microsoft.com/en-us/download/details.aspx?id=46148), or better, update the whole system using Windows Update.
|
||||||
|
* Intel/Qualcomm Killer network cards: `Advanced Stream Detect` in Killer Control Center is incompatible with GoodbyeDPI, [disable it](https://github.com/ValdikSS/GoodbyeDPI/issues/541#issuecomment-2296038239).
|
||||||
|
* QUIK trading software [may interfere with GoodbyeDPI](https://github.com/ValdikSS/GoodbyeDPI/issues/677#issuecomment-2390595606). First start QUIK, then GoodbyeDPI.
|
||||||
* ~~Some SSL/TLS stacks unable to process fragmented ClientHello packets, and HTTPS websites won't open. Bug: [#4](https://github.com/ValdikSS/GoodbyeDPI/issues/4), [#64](https://github.com/ValdikSS/GoodbyeDPI/issues/64).~~ Fragmentation issues are fixed in v0.1.7.
|
* ~~Some SSL/TLS stacks unable to process fragmented ClientHello packets, and HTTPS websites won't open. Bug: [#4](https://github.com/ValdikSS/GoodbyeDPI/issues/4), [#64](https://github.com/ValdikSS/GoodbyeDPI/issues/64).~~ Fragmentation issues are fixed in v0.1.7.
|
||||||
* ~~ESET Antivirus is incompatible with WinDivert driver [#91](https://github.com/ValdikSS/GoodbyeDPI/issues/91). This is most probably antivirus bug, not WinDivert.~~
|
* ~~ESET Antivirus is incompatible with WinDivert driver [#91](https://github.com/ValdikSS/GoodbyeDPI/issues/91). This is most probably antivirus bug, not WinDivert.~~
|
||||||
|
|
||||||
|
|
||||||
# Similar projects
|
# Similar projects
|
||||||
|
|
||||||
- **[zapret](https://github.com/bol-van/zapret)** by @bol-van (for Linux).
|
- **[zapret](https://github.com/bol-van/zapret)** by @bol-van (for MacOS, Linux and Windows)
|
||||||
- **[Green Tunnel](https://github.com/SadeghHayeri/GreenTunnel)** by @SadeghHayeri (for MacOS, Linux and Windows).
|
- **[Green Tunnel](https://github.com/SadeghHayeri/GreenTunnel)** by @SadeghHayeri (for MacOS, Linux and Windows)
|
||||||
- **[DPITunnel](https://github.com/zhenyolka/DPITunnel)** by @zhenyolka (for Android).
|
- **[DPI Tunnel CLI](https://github.com/nomoresat/DPITunnel-cli)** by @zhenyolka (for Linux and routers)
|
||||||
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** by @krlvm (for Windows, MacOS and Linux).
|
- **[DPI Tunnel for Android](https://github.com/nomoresat/DPITunnel-android)** by @zhenyolka (for Android)
|
||||||
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** by @krlvm (for Android).
|
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** by @krlvm (for Windows, MacOS and Linux)
|
||||||
|
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** by @krlvm (for Android)
|
||||||
|
- **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** by @xvzc (for macOS and Linux)
|
||||||
|
- **[SpoofDPI-Platform](https://github.com/r3pr3ss10n/SpoofDPI-Platform)** by @r3pr3ss10n (for Android, macOS, Windows)
|
||||||
|
- **[GhosTCP](https://github.com/macronut/ghostcp)** by @macronut (for Windows)
|
||||||
|
- **[ByeDPI](https://github.com/hufrea/byedpi)** for Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** / **[ByeByeDPI](https://github.com/romanvht/ByeByeDPI/)** for Android (no root)
|
||||||
|
- **[youtubeUnblock](https://github.com/Waujito/youtubeUnblock/)** by @Waujito (for OpenWRT/Entware routers and Linux)
|
||||||
|
|
||||||
# Kudos
|
# Kudos
|
||||||
|
|
||||||
|
|||||||
17
src/Makefile
17
src/Makefile
@@ -11,14 +11,23 @@ TARGET = goodbyedpi.exe
|
|||||||
#LIBS = -L$(WINDIVERTLIBS) -Wl,-Bstatic -lssp -Wl,-Bdynamic -lWinDivert -lws2_32
|
#LIBS = -L$(WINDIVERTLIBS) -Wl,-Bstatic -lssp -Wl,-Bdynamic -lWinDivert -lws2_32
|
||||||
LIBS = -L$(WINDIVERTLIBS) -lWinDivert -lws2_32 -l:libssp.a
|
LIBS = -L$(WINDIVERTLIBS) -lWinDivert -lws2_32 -l:libssp.a
|
||||||
CC = $(CPREFIX)gcc
|
CC = $(CPREFIX)gcc
|
||||||
|
|
||||||
CCWINDRES = $(CPREFIX)windres
|
CCWINDRES = $(CPREFIX)windres
|
||||||
|
ifeq (, $(shell which $(CPREFIX)windres))
|
||||||
|
CCWINDRES = windres
|
||||||
|
endif
|
||||||
|
|
||||||
CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
|
CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
|
||||||
-O2 -D_FORTIFY_SOURCE=2 -fstack-protector \
|
-O2 -D_FORTIFY_SOURCE=2 -fstack-protector \
|
||||||
-Wall -Wextra -Wpedantic -Wformat=2 -Wno-format-nonliteral -Wshadow -Wstrict-aliasing=1 -Werror=format-security \
|
-Wall -Wextra -Wpedantic -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 \
|
||||||
|
-Wformat-security -Wno-format-nonliteral -Wshadow -Wstrict-aliasing=1 \
|
||||||
|
-Wnull-dereference -Warray-bounds=2 -Wimplicit-fallthrough=3 \
|
||||||
|
-Wstringop-overflow=4 \
|
||||||
|
-Wformat-signedness -Wstrict-overflow=2 -Wcast-align=strict \
|
||||||
-Wfloat-equal -Wcast-align -Wsign-conversion \
|
-Wfloat-equal -Wcast-align -Wsign-conversion \
|
||||||
#-fstack-protector-strong
|
#-fstack-protector-strong
|
||||||
LDFLAGS = -fstack-protector -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
|
LDFLAGS = -fstack-protector -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
|
||||||
-Wl,--image-base,0x140000000 -Wl,--disable-auto-image-base
|
-Wl,--disable-auto-image-base
|
||||||
|
|
||||||
ifdef BIT64
|
ifdef BIT64
|
||||||
LDFLAGS += -Wl,--high-entropy-va -Wl,--pic-executable,-e,mainCRTStartup
|
LDFLAGS += -Wl,--high-entropy-va -Wl,--pic-executable,-e,mainCRTStartup
|
||||||
@@ -29,7 +38,7 @@ endif
|
|||||||
|
|
||||||
.PHONY: default all clean
|
.PHONY: default all clean
|
||||||
|
|
||||||
default: manifest $(TARGET)
|
default: $(TARGET)
|
||||||
all: default
|
all: default
|
||||||
|
|
||||||
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c utils/*.c)) goodbyedpi-rc.o
|
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c utils/*.c)) goodbyedpi-rc.o
|
||||||
@@ -38,7 +47,7 @@ HEADERS = $(wildcard *.h utils/*.h)
|
|||||||
%.o: %.c $(HEADERS)
|
%.o: %.c $(HEADERS)
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
manifest:
|
goodbyedpi-rc.o:
|
||||||
$(CCWINDRES) goodbyedpi-rc.rc goodbyedpi-rc.o
|
$(CCWINDRES) goodbyedpi-rc.rc goodbyedpi-rc.o
|
||||||
|
|
||||||
.PRECIOUS: $(TARGET) $(OBJECTS)
|
.PRECIOUS: $(TARGET) $(OBJECTS)
|
||||||
|
|||||||
@@ -70,8 +70,10 @@ int blackwhitelist_load_list(const char *filename) {
|
|||||||
line);
|
line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strlen(line) < 4)
|
if (strlen(line) < 2) {
|
||||||
|
printf("WARNING: host %s is less than 2 characters, skipping\n", line);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (add_hostname(line))
|
if (add_hostname(line))
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
@@ -97,8 +99,7 @@ int blackwhitelist_check_hostname(const char *host_addr, size_t host_len) {
|
|||||||
|
|
||||||
tokenized_host = strchr(current_host, '.');
|
tokenized_host = strchr(current_host, '.');
|
||||||
while (tokenized_host != NULL && tokenized_host < (current_host + HOST_MAXLEN)) {
|
while (tokenized_host != NULL && tokenized_host < (current_host + HOST_MAXLEN)) {
|
||||||
/* Search hostname only if there is next token */
|
if (check_get_hostname(tokenized_host + 1))
|
||||||
if (strchr(tokenized_host + 1, '.') && check_get_hostname(tokenized_host + 1))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
tokenized_host = strchr(tokenized_host + 1, '.');
|
tokenized_host = strchr(tokenized_host + 1, '.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static time_t last_cleanup = 0;
|
|||||||
static udp_connrecord_t *conntrack = NULL;
|
static udp_connrecord_t *conntrack = NULL;
|
||||||
|
|
||||||
void flush_dns_cache() {
|
void flush_dns_cache() {
|
||||||
long long int WINAPI (*DnsFlushResolverCache)();
|
INT_PTR WINAPI (*DnsFlushResolverCache)();
|
||||||
|
|
||||||
HMODULE dnsapi = LoadLibrary("dnsapi.dll");
|
HMODULE dnsapi = LoadLibrary("dnsapi.dll");
|
||||||
if (dnsapi == NULL)
|
if (dnsapi == NULL)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#define _CRT_RAND_S
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <in6addr.h>
|
#include <in6addr.h>
|
||||||
@@ -7,6 +9,15 @@
|
|||||||
#include "windivert.h"
|
#include "windivert.h"
|
||||||
#include "goodbyedpi.h"
|
#include "goodbyedpi.h"
|
||||||
|
|
||||||
|
struct fake_t {
|
||||||
|
const unsigned char* data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fake_t *fakes[30] = {0};
|
||||||
|
int fakes_count = 0;
|
||||||
|
int fakes_resend = 1;
|
||||||
|
|
||||||
static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3.org\r\n"
|
static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3.org\r\n"
|
||||||
"User-Agent: curl/7.65.3\r\nAccept: */*\r\n"
|
"User-Agent: curl/7.65.3\r\nAccept: */*\r\n"
|
||||||
"Accept-Encoding: deflate, gzip, br\r\n\r\n";
|
"Accept-Encoding: deflate, gzip, br\r\n\r\n";
|
||||||
@@ -46,6 +57,91 @@ static const unsigned char fake_https_request[] = {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Captured from Firefox 130.0.1
|
||||||
|
static const unsigned char fake_clienthello_part0[] = { // 116 bytes
|
||||||
|
// TLS 1.2 ClientHello header (DD for length placeholder)
|
||||||
|
0x16, 0x03, 0x01, 0xDD, 0xDD, 0x01, 0x00, 0xDD, 0xDD, 0x03, 0x03,
|
||||||
|
// Random bytes (AA for placeholder)
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
// Random Session ID
|
||||||
|
0x20,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
// Cipher Suites
|
||||||
|
0x00, 0x22, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0xCC, 0xA9, 0xCC, 0xA8,
|
||||||
|
0xC0, 0x2C, 0xC0, 0x30, 0xC0, 0x0A, 0xC0, 0x09, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D,
|
||||||
|
0x00, 0x2F, 0x00, 0x35,
|
||||||
|
// Compression Methods
|
||||||
|
0x01, 0x00,
|
||||||
|
// Extensions Length
|
||||||
|
0xDD, 0xDD,
|
||||||
|
};
|
||||||
|
// SNI: 00 00 L1 L1 L2 L2 00 L3 L3 (sni)
|
||||||
|
// L1 = L+5, L2 = L+3, L3 = L // 9 + L bytes
|
||||||
|
static const unsigned char fake_clienthello_part1[] = { // 523 bytes
|
||||||
|
// extended_master_secret
|
||||||
|
0x00, 0x17, 0x00, 0x00,
|
||||||
|
// renegotiation_info
|
||||||
|
0xFF, 0x01, 0x00, 0x01, 0x00,
|
||||||
|
// supported_groups
|
||||||
|
0x00, 0x0A, 0x00, 0x0E,
|
||||||
|
0x00, 0x0C, 0x00, 0x1D, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, 0x00, 0x01, 0x01,
|
||||||
|
// ex_point_formats
|
||||||
|
0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
|
||||||
|
// session_ticket
|
||||||
|
0x00, 0x23, 0x00, 0x00,
|
||||||
|
// ALPN
|
||||||
|
0x00, 0x10, 0x00, 0x0E,
|
||||||
|
0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31,
|
||||||
|
// status_request
|
||||||
|
0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
// delegated_credentials
|
||||||
|
0x00, 0x22, 0x00, 0x0A, 0x00, 0x08, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03,
|
||||||
|
// key_share
|
||||||
|
0x00, 0x33, 0x00, 0x6B, 0x00, 0x69, 0x00, 0x1D, 0x00, 0x20,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0x00, 0x17, 0x00, 0x41, 0x04,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
// supported_versions
|
||||||
|
0x00, 0x2B, 0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03,
|
||||||
|
// signature_algorithms
|
||||||
|
0x00, 0x0D, 0x00, 0x18, 0x00, 0x16, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, 0x08, 0x05,
|
||||||
|
0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01,
|
||||||
|
// psk_key_exchange_modes
|
||||||
|
0x00, 0x2D, 0x00, 0x02, 0x01, 0x01,
|
||||||
|
// record_size_limit
|
||||||
|
0x00, 0x1C, 0x00, 0x02, 0x40, 0x01,
|
||||||
|
// encrypted_client_hello
|
||||||
|
0xFE, 0x0D, 0x01, 0x19, 0x00, 0x00, 0x01, 0x00, 0x01, 0xAA, 0x00, 0x20,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0x00, 0xEF,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
|
||||||
|
};
|
||||||
|
// JA4: t13d1715h2_5b57614c22b0_5c2c66f702b0
|
||||||
|
// JA4_r: t13d1715h2_002f,0035,009c,009d,1301,1302,1303,c009,c00a,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0017,001c,0022,0023,002b,002d,0033,fe0d,ff01_0403,0503,0603,0804,0805,0806,0401,0501,0601,0203,0201
|
||||||
|
// JA3 Fullstring: 771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-65037,29-23-24-25-256-257,0
|
||||||
|
// JA3: b5001237acdf006056b409cc433726b0
|
||||||
|
|
||||||
static int send_fake_data(const HANDLE w_filter,
|
static int send_fake_data(const HANDLE w_filter,
|
||||||
const PWINDIVERT_ADDRESS addr,
|
const PWINDIVERT_ADDRESS addr,
|
||||||
const char *pkt,
|
const char *pkt,
|
||||||
@@ -54,7 +150,8 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
const BOOL is_https,
|
const BOOL is_https,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum,
|
const BYTE set_checksum,
|
||||||
const BYTE set_seq
|
const BYTE set_seq,
|
||||||
|
const struct fake_t *fake_data
|
||||||
) {
|
) {
|
||||||
char packet_fake[MAX_PACKET_SIZE];
|
char packet_fake[MAX_PACKET_SIZE];
|
||||||
WINDIVERT_ADDRESS addr_new;
|
WINDIVERT_ADDRESS addr_new;
|
||||||
@@ -66,23 +163,29 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
PWINDIVERT_TCPHDR ppTcpHdr;
|
PWINDIVERT_TCPHDR ppTcpHdr;
|
||||||
unsigned const char *fake_request_data = is_https ? fake_https_request : fake_http_request;
|
unsigned const char *fake_request_data = is_https ? fake_https_request : fake_http_request;
|
||||||
UINT fake_request_size = is_https ? sizeof(fake_https_request) : sizeof(fake_http_request) - 1;
|
UINT fake_request_size = is_https ? sizeof(fake_https_request) : sizeof(fake_http_request) - 1;
|
||||||
|
if (fake_data) {
|
||||||
|
fake_request_data = fake_data->data;
|
||||||
|
fake_request_size = fake_data->size;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
|
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
|
||||||
memcpy(packet_fake, pkt, packetLen);
|
memcpy(packet_fake, pkt, packetLen);
|
||||||
|
|
||||||
addr_new.PseudoTCPChecksum = 0;
|
addr_new.TCPChecksum = 0;
|
||||||
addr_new.PseudoIPChecksum = 0;
|
addr_new.IPChecksum = 0;
|
||||||
|
|
||||||
if (!is_ipv6) {
|
if (!is_ipv6) {
|
||||||
// IPv4 TCP Data packet
|
// IPv4 TCP Data packet
|
||||||
if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr,
|
if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr,
|
||||||
NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen))
|
NULL, NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen,
|
||||||
|
NULL, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// IPv6 TCP Data packet
|
// IPv6 TCP Data packet
|
||||||
if (!WinDivertHelperParsePacket(packet_fake, packetLen, NULL,
|
if (!WinDivertHelperParsePacket(packet_fake, packetLen, NULL,
|
||||||
&ppIpV6Hdr, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen))
|
&ppIpV6Hdr, NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen,
|
||||||
|
NULL, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,18 +223,18 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate the checksum
|
// Recalculate the checksum
|
||||||
WinDivertHelperCalcChecksums(packet_fake, packetLen_new, &addr_new, (UINT64)NULL);
|
WinDivertHelperCalcChecksums(packet_fake, packetLen_new, &addr_new, 0ULL);
|
||||||
|
|
||||||
if (set_checksum) {
|
if (set_checksum) {
|
||||||
// ...and damage it
|
// ...and damage it
|
||||||
ppTcpHdr->Checksum = htons(ntohs(ppTcpHdr->Checksum) - 1);
|
ppTcpHdr->Checksum = htons(ntohs(ppTcpHdr->Checksum) - 1);
|
||||||
}
|
}
|
||||||
//printf("Pseudo checksum: %d\n", addr_new.PseudoTCPChecksum);
|
//printf("Pseudo checksum: %d\n", addr_new.TCPChecksum);
|
||||||
|
|
||||||
WinDivertSend(
|
WinDivertSend(
|
||||||
w_filter, packet_fake,
|
w_filter, packet_fake,
|
||||||
packetLen_new,
|
packetLen_new,
|
||||||
&addr_new, NULL
|
NULL, &addr_new
|
||||||
);
|
);
|
||||||
debug("Fake packet: OK");
|
debug("Fake packet: OK");
|
||||||
|
|
||||||
@@ -146,22 +249,26 @@ static int send_fake_request(const HANDLE w_filter,
|
|||||||
const BOOL is_https,
|
const BOOL is_https,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum,
|
const BYTE set_checksum,
|
||||||
const BYTE set_seq
|
const BYTE set_seq,
|
||||||
|
const struct fake_t *fake_data
|
||||||
) {
|
) {
|
||||||
if (set_ttl) {
|
if (set_ttl) {
|
||||||
send_fake_data(w_filter, addr, pkt, packetLen,
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, is_https,
|
is_ipv6, is_https,
|
||||||
set_ttl, FALSE, FALSE);
|
set_ttl, FALSE, FALSE,
|
||||||
|
fake_data);
|
||||||
}
|
}
|
||||||
if (set_checksum) {
|
if (set_checksum) {
|
||||||
send_fake_data(w_filter, addr, pkt, packetLen,
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, is_https,
|
is_ipv6, is_https,
|
||||||
FALSE, set_checksum, FALSE);
|
FALSE, set_checksum, FALSE,
|
||||||
|
fake_data);
|
||||||
}
|
}
|
||||||
if (set_seq) {
|
if (set_seq) {
|
||||||
send_fake_data(w_filter, addr, pkt, packetLen,
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, is_https,
|
is_ipv6, is_https,
|
||||||
FALSE, FALSE, set_seq);
|
FALSE, FALSE, set_seq,
|
||||||
|
fake_data);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -175,9 +282,18 @@ int send_fake_http_request(const HANDLE w_filter,
|
|||||||
const BYTE set_checksum,
|
const BYTE set_checksum,
|
||||||
const BYTE set_seq
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
return send_fake_request(w_filter, addr, pkt, packetLen,
|
int ret = 0;
|
||||||
|
for (int i=0; i<fakes_count || i == 0; i++) {
|
||||||
|
for (int j=0; j<fakes_resend; j++)
|
||||||
|
if (send_fake_request(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, FALSE,
|
is_ipv6, FALSE,
|
||||||
set_ttl, set_checksum, set_seq);
|
set_ttl, set_checksum, set_seq,
|
||||||
|
fakes[i]))
|
||||||
|
{
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_fake_https_request(const HANDLE w_filter,
|
int send_fake_https_request(const HANDLE w_filter,
|
||||||
@@ -189,7 +305,137 @@ int send_fake_https_request(const HANDLE w_filter,
|
|||||||
const BYTE set_checksum,
|
const BYTE set_checksum,
|
||||||
const BYTE set_seq
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
return send_fake_request(w_filter, addr, pkt, packetLen,
|
int ret = 0;
|
||||||
|
for (int i=0; i<fakes_count || i == 0; i++) {
|
||||||
|
for (int j=0; j<fakes_resend; j++)
|
||||||
|
if (send_fake_request(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, TRUE,
|
is_ipv6, TRUE,
|
||||||
set_ttl, set_checksum, set_seq);
|
set_ttl, set_checksum, set_seq,
|
||||||
|
fakes[i]))
|
||||||
|
{
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_add(const unsigned char *data, size_t size) {
|
||||||
|
struct fake_t *fake = malloc(sizeof(struct fake_t));
|
||||||
|
fake->size = size;
|
||||||
|
fake->data = data;
|
||||||
|
|
||||||
|
for (size_t k = 0; k <= sizeof(fakes) / sizeof(*fakes); k++) {
|
||||||
|
if (!fakes[k]) {
|
||||||
|
fakes[k] = fake;
|
||||||
|
fakes_count++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fake_load_from_hex(const char *data) {
|
||||||
|
size_t len = strlen(data);
|
||||||
|
if (len < 2 || len % 2 || len > (1420 * 2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
unsigned char *finaldata = calloc((len + 2) / 2, 1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i<len - 1; i+=2) {
|
||||||
|
char num1 = data[i];
|
||||||
|
char num2 = data[i+1];
|
||||||
|
debug("Current num1: %X, num2: %X\n", num1, num2);
|
||||||
|
unsigned char finalchar = 0;
|
||||||
|
char curchar = num1;
|
||||||
|
|
||||||
|
for (int j=0; j<=1; j++) {
|
||||||
|
if (curchar >= '0' && curchar <= '9')
|
||||||
|
curchar -= '0';
|
||||||
|
else if (curchar >= 'a' && curchar <= 'f')
|
||||||
|
curchar -= 'a' - 0xA;
|
||||||
|
else if (curchar >= 'A' && curchar <= 'F')
|
||||||
|
curchar -= 'A' - 0xA;
|
||||||
|
else
|
||||||
|
return 2; // incorrect character, not a hex data
|
||||||
|
|
||||||
|
if (!j) {
|
||||||
|
num1 = curchar;
|
||||||
|
curchar = num2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
num2 = curchar;
|
||||||
|
}
|
||||||
|
debug("Processed num1: %X, num2: %X\n", num1, num2);
|
||||||
|
finalchar = (num1 << 4) | num2;
|
||||||
|
debug("Final char: %X\n", finalchar);
|
||||||
|
finaldata[i/2] = finalchar;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fake_add(finaldata, len / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fake_load_random(unsigned int count, unsigned int maxsize) {
|
||||||
|
if (count < 1 || count > sizeof(fakes) / sizeof(*fakes))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
unsigned int random = 0;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<count; i++) {
|
||||||
|
unsigned int len = 0;
|
||||||
|
if (rand_s(&len))
|
||||||
|
return 1;
|
||||||
|
len = 8 + (len % maxsize);
|
||||||
|
|
||||||
|
unsigned char *data = calloc(len, 1);
|
||||||
|
for (unsigned int j=0; j<len; j++) {
|
||||||
|
rand_s(&random);
|
||||||
|
data[j] = random % 0xFF;
|
||||||
|
}
|
||||||
|
if (fake_add(data, len))
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_uint16be(unsigned char *buffer, int offset, int value) {
|
||||||
|
buffer[offset] = (value >> 8) & 0xFF;
|
||||||
|
buffer[offset + 1] = value & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fake_load_from_sni(const char *domain_name) {
|
||||||
|
if (!domain_name) {
|
||||||
|
return 1; // just extra safeguard against NPE
|
||||||
|
}
|
||||||
|
// calculate sizes
|
||||||
|
const int name_size = strlen(domain_name);
|
||||||
|
const int part0_size = sizeof(fake_clienthello_part0);
|
||||||
|
const int part1_size = sizeof(fake_clienthello_part1);
|
||||||
|
const int sni_head_size = 9;
|
||||||
|
const int packet_size = part0_size + part1_size + sni_head_size + name_size;
|
||||||
|
// allocate memory
|
||||||
|
unsigned char *packet = malloc(packet_size);
|
||||||
|
// copy major parts of packet
|
||||||
|
memcpy(packet, fake_clienthello_part0, part0_size);
|
||||||
|
memcpy(&packet[part0_size + sni_head_size + name_size], fake_clienthello_part1, part1_size);
|
||||||
|
// replace placeholders with random generated values
|
||||||
|
unsigned int random = 0;
|
||||||
|
for (int i = 0; i < packet_size; i++) {
|
||||||
|
if (packet[i] == 0xAA) {
|
||||||
|
rand_s(&random);
|
||||||
|
packet[i] = random & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write size fields into packet
|
||||||
|
set_uint16be(packet, 0x0003, packet_size - 5);
|
||||||
|
set_uint16be(packet, 0x0007, packet_size - 9);
|
||||||
|
set_uint16be(packet, 0x0072, packet_size - 116);
|
||||||
|
// write SNI extension
|
||||||
|
set_uint16be(packet, part0_size + 0, 0x0000);
|
||||||
|
set_uint16be(packet, part0_size + 2, name_size + 5);
|
||||||
|
set_uint16be(packet, part0_size + 4, name_size + 3);
|
||||||
|
packet[part0_size + 6] = 0x00;
|
||||||
|
set_uint16be(packet, part0_size + 7, name_size);
|
||||||
|
memcpy(&packet[part0_size + sni_head_size], domain_name, name_size);
|
||||||
|
// add packet to fakes
|
||||||
|
return fake_add(packet, packet_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
extern int fakes_count;
|
||||||
|
extern int fakes_resend;
|
||||||
int send_fake_http_request(const HANDLE w_filter,
|
int send_fake_http_request(const HANDLE w_filter,
|
||||||
const PWINDIVERT_ADDRESS addr,
|
const PWINDIVERT_ADDRESS addr,
|
||||||
const char *pkt,
|
const char *pkt,
|
||||||
@@ -16,3 +18,6 @@ int send_fake_https_request(const HANDLE w_filter,
|
|||||||
const BYTE set_checksum,
|
const BYTE set_checksum,
|
||||||
const BYTE set_seq
|
const BYTE set_seq
|
||||||
);
|
);
|
||||||
|
int fake_load_from_hex(const char *data);
|
||||||
|
int fake_load_from_sni(const char *domain_name);
|
||||||
|
int fake_load_random(unsigned int count, unsigned int maxsize);
|
||||||
|
|||||||
593
src/goodbyedpi.c
593
src/goodbyedpi.c
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ int service_register(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if (!service_argc && !service_argv) {
|
if (!service_argc && !service_argv) {
|
||||||
service_argc = argc;
|
service_argc = argc;
|
||||||
service_argv = malloc(sizeof(void*) * (size_t)argc);
|
service_argv = calloc((size_t)(argc + 1), sizeof(void*));
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
service_argv[i] = strdup(argv[i]);
|
service_argv[i] = strdup(argv[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
#include "goodbyedpi.h"
|
#include "goodbyedpi.h"
|
||||||
#include "ttltrack.h"
|
#include "ttltrack.h"
|
||||||
#include "utils/uthash.h"
|
#include "utils/uthash.h"
|
||||||
@@ -218,23 +219,33 @@ int tcp_handle_outgoing(uint32_t srcip[4], uint32_t dstip[4],
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_get_auto_ttl(const uint8_t ttl, const uint8_t decrease_for) {
|
int tcp_get_auto_ttl(const uint8_t ttl, const uint8_t autottl1,
|
||||||
|
const uint8_t autottl2, const uint8_t minhops,
|
||||||
|
const uint8_t maxttl) {
|
||||||
|
uint8_t nhops = 0;
|
||||||
uint8_t ttl_of_fake_packet = 0;
|
uint8_t ttl_of_fake_packet = 0;
|
||||||
|
|
||||||
if (ttl > 98 && ttl < 128) {
|
if (ttl > 98 && ttl < 128) {
|
||||||
/* Safekeeping */
|
nhops = 128 - ttl;
|
||||||
if (128 - ttl > decrease_for + 1) {
|
|
||||||
ttl_of_fake_packet = 128 - ttl - decrease_for;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (ttl > 34 && ttl < 64) {
|
else if (ttl > 34 && ttl < 64) {
|
||||||
/* Safekeeping */
|
nhops = 64 - ttl;
|
||||||
if (64 - ttl > decrease_for + 1) {
|
|
||||||
ttl_of_fake_packet = 64 - ttl - decrease_for;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ttl_of_fake_packet = 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nhops <= autottl1 || nhops < minhops) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ttl_of_fake_packet = nhops - autottl2;
|
||||||
|
if (ttl_of_fake_packet < autottl2 && nhops <= 9) {
|
||||||
|
ttl_of_fake_packet = nhops - autottl1 - trunc((autottl2 - autottl1) * ((float)nhops/10));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxttl && ttl_of_fake_packet > maxttl) {
|
||||||
|
ttl_of_fake_packet = maxttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ttl_of_fake_packet;
|
return ttl_of_fake_packet;
|
||||||
|
|||||||
@@ -21,5 +21,7 @@ int tcp_handle_outgoing(uint32_t srcip[4], uint32_t dstip[4],
|
|||||||
tcp_conntrack_info_t *conn_info,
|
tcp_conntrack_info_t *conn_info,
|
||||||
uint8_t is_ipv6);
|
uint8_t is_ipv6);
|
||||||
|
|
||||||
int tcp_get_auto_ttl(uint8_t ttl, uint8_t decrease_for);
|
int tcp_get_auto_ttl(const uint8_t ttl, const uint8_t autottl1,
|
||||||
|
const uint8_t autottl2, const uint8_t minhops,
|
||||||
|
const uint8_t maxttl);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2003-2017, Troy D. Hanson http://troydhanson.github.com/uthash/
|
Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.io/uthash/
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,12 +24,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef UTHASH_H
|
#ifndef UTHASH_H
|
||||||
#define UTHASH_H
|
#define UTHASH_H
|
||||||
|
|
||||||
#define UTHASH_VERSION 2.0.2
|
#define UTHASH_VERSION 2.3.0
|
||||||
|
|
||||||
#include <string.h> /* memcmp, memset, strlen */
|
#include <string.h> /* memcmp, memset, strlen */
|
||||||
#include <stddef.h> /* ptrdiff_t */
|
#include <stddef.h> /* ptrdiff_t */
|
||||||
#include <stdlib.h> /* exit */
|
#include <stdlib.h> /* exit */
|
||||||
|
|
||||||
|
#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT
|
||||||
|
/* This codepath is provided for backward compatibility, but I plan to remove it. */
|
||||||
|
#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead"
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT
|
||||||
|
#else
|
||||||
|
#include <stdint.h> /* uint8_t, uint32_t */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These macros use decltype or the earlier __typeof GNU extension.
|
/* These macros use decltype or the earlier __typeof GNU extension.
|
||||||
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
|
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
|
||||||
when compiling c++ source) this code uses whatever method is needed
|
when compiling c++ source) this code uses whatever method is needed
|
||||||
@@ -62,23 +72,6 @@ do {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1600
|
|
||||||
#include <stdint.h>
|
|
||||||
#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#endif
|
|
||||||
#elif defined(__GNUC__) && !defined(__VXWORKS__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef uthash_malloc
|
#ifndef uthash_malloc
|
||||||
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
|
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
|
||||||
#endif
|
#endif
|
||||||
@@ -88,13 +81,18 @@ typedef unsigned char uint8_t;
|
|||||||
#ifndef uthash_bzero
|
#ifndef uthash_bzero
|
||||||
#define uthash_bzero(a,n) memset(a,'\0',n)
|
#define uthash_bzero(a,n) memset(a,'\0',n)
|
||||||
#endif
|
#endif
|
||||||
#ifndef uthash_memcmp
|
|
||||||
#define uthash_memcmp(a,b,n) memcmp(a,b,n)
|
|
||||||
#endif
|
|
||||||
#ifndef uthash_strlen
|
#ifndef uthash_strlen
|
||||||
#define uthash_strlen(s) strlen(s)
|
#define uthash_strlen(s) strlen(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HASH_FUNCTION
|
||||||
|
#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HASH_KEYCMP
|
||||||
|
#define HASH_KEYCMP(a,b,n) memcmp(a,b,n)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef uthash_noexpand_fyi
|
#ifndef uthash_noexpand_fyi
|
||||||
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
|
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
|
||||||
#endif
|
#endif
|
||||||
@@ -136,7 +134,7 @@ typedef unsigned char uint8_t;
|
|||||||
/* calculate the element whose hash handle address is hhp */
|
/* calculate the element whose hash handle address is hhp */
|
||||||
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
||||||
/* calculate the hash handle from element address elp */
|
/* calculate the hash handle from element address elp */
|
||||||
#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho)))
|
#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho)))
|
||||||
|
|
||||||
#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \
|
#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \
|
||||||
do { \
|
do { \
|
||||||
@@ -150,7 +148,7 @@ do {
|
|||||||
|
|
||||||
#define HASH_VALUE(keyptr,keylen,hashv) \
|
#define HASH_VALUE(keyptr,keylen,hashv) \
|
||||||
do { \
|
do { \
|
||||||
HASH_FCN(keyptr, keylen, hashv); \
|
HASH_FUNCTION(keyptr, keylen, hashv); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \
|
#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \
|
||||||
@@ -167,9 +165,12 @@ do {
|
|||||||
|
|
||||||
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
||||||
do { \
|
do { \
|
||||||
|
(out) = NULL; \
|
||||||
|
if (head) { \
|
||||||
unsigned _hf_hashv; \
|
unsigned _hf_hashv; \
|
||||||
HASH_VALUE(keyptr, keylen, _hf_hashv); \
|
HASH_VALUE(keyptr, keylen, _hf_hashv); \
|
||||||
HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \
|
HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef HASH_BLOOM
|
#ifdef HASH_BLOOM
|
||||||
@@ -397,7 +398,7 @@ do {
|
|||||||
do { \
|
do { \
|
||||||
IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \
|
IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \
|
||||||
(add)->hh.hashv = (hashval); \
|
(add)->hh.hashv = (hashval); \
|
||||||
(add)->hh.key = (char*) (keyptr); \
|
(add)->hh.key = (const void*) (keyptr); \
|
||||||
(add)->hh.keylen = (unsigned) (keylen_in); \
|
(add)->hh.keylen = (unsigned) (keylen_in); \
|
||||||
if (!(head)) { \
|
if (!(head)) { \
|
||||||
(add)->hh.next = NULL; \
|
(add)->hh.next = NULL; \
|
||||||
@@ -478,11 +479,20 @@ do {
|
|||||||
|
|
||||||
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
|
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
|
||||||
#define HASH_FIND_STR(head,findstr,out) \
|
#define HASH_FIND_STR(head,findstr,out) \
|
||||||
HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out)
|
do { \
|
||||||
|
unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \
|
||||||
|
HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \
|
||||||
|
} while (0)
|
||||||
#define HASH_ADD_STR(head,strfield,add) \
|
#define HASH_ADD_STR(head,strfield,add) \
|
||||||
HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add)
|
do { \
|
||||||
|
unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \
|
||||||
|
HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \
|
||||||
|
} while (0)
|
||||||
#define HASH_REPLACE_STR(head,strfield,add,replaced) \
|
#define HASH_REPLACE_STR(head,strfield,add,replaced) \
|
||||||
HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced)
|
do { \
|
||||||
|
unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \
|
||||||
|
HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \
|
||||||
|
} while (0)
|
||||||
#define HASH_FIND_INT(head,findint,out) \
|
#define HASH_FIND_INT(head,findint,out) \
|
||||||
HASH_FIND(hh,head,findint,sizeof(int),out)
|
HASH_FIND(hh,head,findint,sizeof(int),out)
|
||||||
#define HASH_ADD_INT(head,intfield,add) \
|
#define HASH_ADD_INT(head,intfield,add) \
|
||||||
@@ -502,6 +512,7 @@ do {
|
|||||||
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
|
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
|
||||||
*/
|
*/
|
||||||
#ifdef HASH_DEBUG
|
#ifdef HASH_DEBUG
|
||||||
|
#include <stdio.h> /* fprintf, stderr */
|
||||||
#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0)
|
#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0)
|
||||||
#define HASH_FSCK(hh,head,where) \
|
#define HASH_FSCK(hh,head,where) \
|
||||||
do { \
|
do { \
|
||||||
@@ -569,13 +580,6 @@ do {
|
|||||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
|
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
|
|
||||||
#ifdef HASH_FUNCTION
|
|
||||||
#define HASH_FCN HASH_FUNCTION
|
|
||||||
#else
|
|
||||||
#define HASH_FCN HASH_JEN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
|
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
|
||||||
#define HASH_BER(key,keylen,hashv) \
|
#define HASH_BER(key,keylen,hashv) \
|
||||||
do { \
|
do { \
|
||||||
@@ -674,7 +678,8 @@ do {
|
|||||||
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \
|
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \
|
||||||
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \
|
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \
|
||||||
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \
|
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \
|
||||||
case 1: _hj_i += _hj_key[0]; \
|
case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \
|
||||||
|
default: ; \
|
||||||
} \
|
} \
|
||||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@@ -722,6 +727,8 @@ do {
|
|||||||
case 1: hashv += *_sfh_key; \
|
case 1: hashv += *_sfh_key; \
|
||||||
hashv ^= hashv << 10; \
|
hashv ^= hashv << 10; \
|
||||||
hashv += hashv >> 1; \
|
hashv += hashv >> 1; \
|
||||||
|
break; \
|
||||||
|
default: ; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* Force "avalanching" of final 127 bits */ \
|
/* Force "avalanching" of final 127 bits */ \
|
||||||
@@ -733,87 +740,6 @@ do {
|
|||||||
hashv += hashv >> 6; \
|
hashv += hashv >> 6; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef HASH_USING_NO_STRICT_ALIASING
|
|
||||||
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
|
|
||||||
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
|
|
||||||
* MurmurHash uses the faster approach only on CPU's where we know it's safe.
|
|
||||||
*
|
|
||||||
* Note the preprocessor built-in defines can be emitted using:
|
|
||||||
*
|
|
||||||
* gcc -m64 -dM -E - < /dev/null (on gcc)
|
|
||||||
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
|
|
||||||
*/
|
|
||||||
#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
|
|
||||||
#define MUR_GETBLOCK(p,i) p[i]
|
|
||||||
#else /* non intel */
|
|
||||||
#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL)
|
|
||||||
#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL)
|
|
||||||
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)
|
|
||||||
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)
|
|
||||||
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
|
|
||||||
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
|
|
||||||
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
|
|
||||||
#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
|
|
||||||
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
|
|
||||||
#else /* assume little endian non-intel */
|
|
||||||
#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
|
|
||||||
#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
|
|
||||||
#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
|
|
||||||
#endif
|
|
||||||
#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
|
|
||||||
(MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
|
|
||||||
(MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
|
|
||||||
MUR_ONE_THREE(p))))
|
|
||||||
#endif
|
|
||||||
#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
|
|
||||||
#define MUR_FMIX(_h) \
|
|
||||||
do { \
|
|
||||||
_h ^= _h >> 16; \
|
|
||||||
_h *= 0x85ebca6bu; \
|
|
||||||
_h ^= _h >> 13; \
|
|
||||||
_h *= 0xc2b2ae35u; \
|
|
||||||
_h ^= _h >> 16; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define HASH_MUR(key,keylen,hashv) \
|
|
||||||
do { \
|
|
||||||
const uint8_t *_mur_data = (const uint8_t*)(key); \
|
|
||||||
const int _mur_nblocks = (int)(keylen) / 4; \
|
|
||||||
uint32_t _mur_h1 = 0xf88D5353u; \
|
|
||||||
uint32_t _mur_c1 = 0xcc9e2d51u; \
|
|
||||||
uint32_t _mur_c2 = 0x1b873593u; \
|
|
||||||
uint32_t _mur_k1 = 0; \
|
|
||||||
const uint8_t *_mur_tail; \
|
|
||||||
const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \
|
|
||||||
int _mur_i; \
|
|
||||||
for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \
|
|
||||||
_mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
|
|
||||||
_mur_k1 *= _mur_c1; \
|
|
||||||
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
|
|
||||||
_mur_k1 *= _mur_c2; \
|
|
||||||
\
|
|
||||||
_mur_h1 ^= _mur_k1; \
|
|
||||||
_mur_h1 = MUR_ROTL32(_mur_h1,13); \
|
|
||||||
_mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \
|
|
||||||
} \
|
|
||||||
_mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \
|
|
||||||
_mur_k1=0; \
|
|
||||||
switch ((keylen) & 3U) { \
|
|
||||||
case 0: break; \
|
|
||||||
case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \
|
|
||||||
case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \
|
|
||||||
case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \
|
|
||||||
_mur_k1 *= _mur_c1; \
|
|
||||||
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
|
|
||||||
_mur_k1 *= _mur_c2; \
|
|
||||||
_mur_h1 ^= _mur_k1; \
|
|
||||||
} \
|
|
||||||
_mur_h1 ^= (uint32_t)(keylen); \
|
|
||||||
MUR_FMIX(_mur_h1); \
|
|
||||||
hashv = _mur_h1; \
|
|
||||||
} while (0)
|
|
||||||
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
|
||||||
|
|
||||||
/* iterate over items in a known bucket to find desired item */
|
/* iterate over items in a known bucket to find desired item */
|
||||||
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \
|
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \
|
||||||
do { \
|
do { \
|
||||||
@@ -824,7 +750,7 @@ do {
|
|||||||
} \
|
} \
|
||||||
while ((out) != NULL) { \
|
while ((out) != NULL) { \
|
||||||
if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \
|
if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \
|
||||||
if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \
|
if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@@ -910,12 +836,12 @@ do {
|
|||||||
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
|
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
|
||||||
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
|
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
|
||||||
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
|
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||||
2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \
|
sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \
|
||||||
if (!_he_new_buckets) { \
|
if (!_he_new_buckets) { \
|
||||||
HASH_RECORD_OOM(oomed); \
|
HASH_RECORD_OOM(oomed); \
|
||||||
} else { \
|
} else { \
|
||||||
uthash_bzero(_he_new_buckets, \
|
uthash_bzero(_he_new_buckets, \
|
||||||
2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \
|
sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \
|
||||||
(tbl)->ideal_chain_maxlen = \
|
(tbl)->ideal_chain_maxlen = \
|
||||||
((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \
|
((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \
|
||||||
((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \
|
((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \
|
||||||
@@ -928,7 +854,9 @@ do {
|
|||||||
_he_newbkt = &(_he_new_buckets[_he_bkt]); \
|
_he_newbkt = &(_he_new_buckets[_he_bkt]); \
|
||||||
if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \
|
if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \
|
||||||
(tbl)->nonideal_items++; \
|
(tbl)->nonideal_items++; \
|
||||||
_he_newbkt->expand_mult = _he_newbkt->count / (tbl)->ideal_chain_maxlen; \
|
if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \
|
||||||
|
_he_newbkt->expand_mult++; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
_he_thh->hh_prev = NULL; \
|
_he_thh->hh_prev = NULL; \
|
||||||
_he_thh->hh_next = _he_newbkt->hh_head; \
|
_he_thh->hh_next = _he_newbkt->hh_head; \
|
||||||
@@ -1061,7 +989,7 @@ do {
|
|||||||
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
|
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
|
||||||
if (cond(_elt)) { \
|
if (cond(_elt)) { \
|
||||||
IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \
|
IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \
|
||||||
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
|
_dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \
|
||||||
_dst_hh->key = _src_hh->key; \
|
_dst_hh->key = _src_hh->key; \
|
||||||
_dst_hh->keylen = _src_hh->keylen; \
|
_dst_hh->keylen = _src_hh->keylen; \
|
||||||
_dst_hh->hashv = _src_hh->hashv; \
|
_dst_hh->hashv = _src_hh->hashv; \
|
||||||
@@ -1200,7 +1128,7 @@ typedef struct UT_hash_handle {
|
|||||||
void *next; /* next element in app order */
|
void *next; /* next element in app order */
|
||||||
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
|
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
|
||||||
struct UT_hash_handle *hh_next; /* next hh in bucket order */
|
struct UT_hash_handle *hh_next; /* next hh in bucket order */
|
||||||
void *key; /* ptr to enclosing struct's key */
|
const void *key; /* ptr to enclosing struct's key */
|
||||||
unsigned keylen; /* enclosing struct's key len */
|
unsigned keylen; /* enclosing struct's key len */
|
||||||
unsigned hashv; /* result of hash-fcn(key) */
|
unsigned hashv; /* result of hash-fcn(key) */
|
||||||
} UT_hash_handle;
|
} UT_hash_handle;
|
||||||
|
|||||||
Reference in New Issue
Block a user