This repository was archived by the owner on Apr 5, 2026. It is now read-only.
fix: DC table initializers put port 443 into ipv6 field, add -Werror CI #111
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [ "master" ] | |
| pull_request: | |
| branches: [ "master" ] | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Fast compile-only check: ensures no compiler warnings slip through. | |
| # The main build uses -Wall but not -Werror, so warnings don't fail the | |
| # build for end users on different compiler versions. This CI job adds | |
| # -Werror to catch regressions like the dc-table overflow in v3.5.3. | |
| build-werror: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential libssl-dev zlib1g-dev | |
| - name: Build with -Werror | |
| run: make clean && make -j$(nproc) EXTRA_CFLAGS="-Werror" | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v3 | |
| with: | |
| fetch-depth: 0 | |
| - name: Build and Run Tests | |
| env: | |
| MTPROXY_SECRET: ${{ secrets.MTPROXY_SECRET }} | |
| run: | | |
| if [ -z "$MTPROXY_SECRET" ]; then | |
| export MTPROXY_SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| echo "Generated random MTPROXY_SECRET for testing" | |
| fi | |
| make test | |
| - name: Run TLS E2E Tests | |
| env: | |
| MTPROXY_SECRET: ${{ secrets.MTPROXY_SECRET }} | |
| run: | | |
| if [ -z "$MTPROXY_SECRET" ]; then | |
| export MTPROXY_SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| fi | |
| make test-tls | |
| - name: Run Multi-Secret Tests | |
| run: make test-multi-secret | |
| - name: Run Secret Limit Tests | |
| run: make test-secret-limit | |
| - name: Run DRS Delays Tests | |
| run: make test-drs-delays | |
| test-arm64: | |
| runs-on: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Build and smoke test (ARM64) | |
| run: | | |
| export MTPROXY_SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| echo "Generated MTPROXY_SECRET for ARM64 testing" | |
| make test | |
| - name: Run TLS E2E Tests (ARM64) | |
| run: | | |
| export MTPROXY_SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| make test-tls | |
| test-native-build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v3 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential libssl-dev zlib1g-dev git curl vim-common python3 python3-pip python3-venv netcat-openbsd libunwind-dev | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install requests telethon | |
| - name: Build MTProxy | |
| run: | | |
| make clean && make -j$(nproc) | |
| - name: Verify version string | |
| run: | | |
| EXPECTED_VERSION=$(git describe --tags --match 'v*' --abbrev=0 | sed 's/^v//') | |
| echo "Expected version: $EXPECTED_VERSION" | |
| ACTUAL_OUTPUT=$(objs/bin/mtproto-proxy 2>&1 || true) | |
| echo "$ACTUAL_OUTPUT" | grep -q "mtproxy-${EXPECTED_VERSION}" || { | |
| echo "ERROR: version mismatch — expected mtproxy-${EXPECTED_VERSION}" | |
| exit 1 | |
| } | |
| echo "Version check passed" | |
| - name: Setup and Run Proxy | |
| run: | | |
| echo "Checking connectivity to Telegram DC (149.154.175.50:443)..." | |
| nc -zv 149.154.175.50 443 || echo "Failed to connect to Telegram DC 149.154.175.50:443" | |
| mkdir -p mtproxy-run | |
| cp objs/bin/mtproto-proxy mtproxy-run/ | |
| cd mtproxy-run | |
| # Download config/secret (ME relay mode) | |
| curl --connect-timeout 10 --max-time 30 --retry 3 -fsSL https://core.telegram.org/getProxySecret -o proxy-secret | |
| curl --connect-timeout 10 --max-time 30 --retry 3 -fsSL https://core.telegram.org/getProxyConfig -o proxy-multi.conf | |
| SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| echo "Using secret: $SECRET" | |
| # ME relay mode proxy | |
| ./mtproto-proxy -u nobody -p 8888 -H 8443 -S $SECRET --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 1 & | |
| echo "MTPROXY_SECRET=$SECRET" >> $GITHUB_ENV | |
| sleep 5 | |
| - name: Run Python Tests | |
| run: | | |
| source .venv/bin/activate | |
| export MTPROXY_HOST=localhost | |
| export MTPROXY_PORT=8443 | |
| python3 tests/test_proxy.py | |
| - name: Run TLS E2E Tests (ME Relay) | |
| run: | | |
| source .venv/bin/activate | |
| cd mtproxy-run | |
| ./mtproto-proxy -p 9888 -H 9443 -S $MTPROXY_SECRET \ | |
| --http-stats --aes-pwd proxy-secret proxy-multi.conf -D ya.ru -M 0 & | |
| TLS_PID=$! | |
| cd .. | |
| for i in $(seq 1 30); do | |
| curl -sf http://localhost:9888/stats >/dev/null 2>&1 && break | |
| sleep 2 | |
| done | |
| MTPROXY_HOST=localhost MTPROXY_PORT=9443 MTPROXY_STATS_PORT=9888 \ | |
| MTPROXY_SECRET=$MTPROXY_SECRET TLS_BACKEND_HOST=ya.ru TLS_BACKEND_PORT=443 \ | |
| python3 tests/test_tls_e2e.py | |
| kill $TLS_PID 2>/dev/null || true | |
| test-direct-e2e: | |
| runs-on: ubuntu-latest | |
| # Only run when secrets are available (skip on fork PRs) | |
| if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential libssl-dev zlib1g-dev git curl vim-common python3 python3-pip python3-venv netcat-openbsd | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install requests telethon TelethonFakeTLS | |
| - name: Build MTProxy | |
| run: | | |
| make clean && make -j$(nproc) | |
| - name: Start Direct-Mode Proxies | |
| run: | | |
| echo "Checking connectivity to Telegram DC (149.154.167.51:443)..." | |
| nc -zv 149.154.167.51 443 || echo "WARNING: Cannot reach Telegram DC" | |
| mkdir -p mtproxy-run | |
| cp objs/bin/mtproto-proxy mtproxy-run/ | |
| cd mtproxy-run | |
| SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| echo "Using secret: $SECRET" | |
| echo "MTPROXY_SECRET=$SECRET" >> $GITHUB_ENV | |
| # Obfuscated2 direct-mode proxy (no proxy-secret/proxy-multi.conf needed) | |
| ./mtproto-proxy -u nobody -p 8888 -H 8443 -S $SECRET \ | |
| --http-stats --direct -M 0 2>obfs2.log & | |
| echo "Started obfs2 direct-mode proxy on port 8443" | |
| # Fake-TLS direct-mode proxy | |
| ./mtproto-proxy -u nobody -p 9888 -H 9443 -S $SECRET \ | |
| --http-stats --direct -D ya.ru -M 0 2>faketls.log & | |
| echo "Started fake-TLS direct-mode proxy on port 9443" | |
| # Wait for both proxies to be ready | |
| for port in 8888 9888; do | |
| for i in $(seq 1 30); do | |
| curl -sf http://localhost:$port/stats >/dev/null 2>&1 && break | |
| sleep 2 | |
| done | |
| curl -sf http://localhost:$port/stats >/dev/null 2>&1 || { | |
| echo "ERROR: Proxy on stats port $port not ready after 60s" | |
| exit 1 | |
| } | |
| done | |
| echo "Both proxies are ready" | |
| - name: Run Direct Mode E2E Tests | |
| env: | |
| TG_STRING_SESSION: ${{ secrets.TG_STRING_SESSION }} | |
| run: | | |
| source .venv/bin/activate | |
| DIRECT_HOST=localhost \ | |
| DIRECT_OBFS2_PORT=8443 \ | |
| DIRECT_TLS_PORT=9443 \ | |
| MTPROXY_SECRET=$MTPROXY_SECRET \ | |
| EE_DOMAIN=ya.ru \ | |
| python3 tests/test_direct_e2e.py | |
| - name: Proxy logs (debug) | |
| if: always() | |
| run: | | |
| echo "=== Obfs2 proxy log ===" | |
| cat mtproxy-run/obfs2.log 2>/dev/null || echo "(no log)" | |
| echo "" | |
| echo "=== Fake-TLS proxy log ===" | |
| cat mtproxy-run/faketls.log 2>/dev/null || echo "(no log)" | |
| test-asan: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential libssl-dev zlib1g-dev git curl vim-common python3 python3-pip python3-venv | |
| - name: Build with AddressSanitizer | |
| run: | | |
| make clean && make -j$(nproc) \ | |
| EXTRA_CFLAGS="-fsanitize=address -fno-omit-frame-pointer" \ | |
| EXTRA_LDFLAGS="-fsanitize=address" | |
| - name: Setup and Run Proxy | |
| run: | | |
| mkdir -p mtproxy-run | |
| cp objs/bin/mtproto-proxy mtproxy-run/ | |
| cd mtproxy-run | |
| curl --connect-timeout 10 --max-time 30 --retry 3 -fsSL https://core.telegram.org/getProxySecret -o proxy-secret | |
| curl --connect-timeout 10 --max-time 30 --retry 3 -fsSL https://core.telegram.org/getProxyConfig -o proxy-multi.conf | |
| SECRET=$(head -c 16 /dev/urandom | xxd -ps) | |
| echo "Using secret: $SECRET" | |
| echo "MTPROXY_SECRET=$SECRET" >> $GITHUB_ENV | |
| ASAN_OPTIONS=detect_leaks=0 \ | |
| ./mtproto-proxy -u nobody -p 8888 -H 8443 -S $SECRET \ | |
| --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 1 \ | |
| 2>asan.log & | |
| echo $! > proxy.pid | |
| sleep 5 | |
| - name: Run Tests | |
| run: | | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install requests | |
| MTPROXY_HOST=localhost MTPROXY_PORT=8443 python3 tests/test_proxy.py | |
| - name: Check for ASan Errors | |
| if: always() | |
| run: | | |
| PID=$(cat mtproxy-run/proxy.pid 2>/dev/null || true) | |
| if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then | |
| echo "Proxy still running (PID $PID) — no ASan crash during test" | |
| kill "$PID" 2>/dev/null; wait "$PID" 2>/dev/null || true | |
| else | |
| echo "WARNING: Proxy exited early — possible ASan error" | |
| fi | |
| if [ -f mtproxy-run/asan.log ] && grep -q "AddressSanitizer" mtproxy-run/asan.log; then | |
| echo "::error::AddressSanitizer errors detected" | |
| cat mtproxy-run/asan.log | |
| exit 1 | |
| fi | |
| echo "No ASan errors detected" | |
| - name: Verify ASan catches known heap overflow | |
| run: | | |
| # Re-introduce the CONN_INFO heap overflow fixed in a7e832e to | |
| # prove ASan catches real bugs in the proxy, not just toy programs. | |
| # | |
| # The bug: CONN_INFO(LC)->window_clamp writes at offset ~512 into | |
| # an 80-byte listening_connection_info (allocated via malloc). | |
| # | |
| # Key: use -M 0 (no fork) so the bug triggers in the main process | |
| # whose stderr we capture. With -M 1, the bug only fires in the | |
| # child worker, but $! captures the parent PID. | |
| sed -i 's/LISTEN_CONN_INFO(LC)->window_clamp/CONN_INFO(LC)->window_clamp/' mtproto/mtproto-proxy.c | |
| make -j$(nproc) \ | |
| EXTRA_CFLAGS="-fsanitize=address -fno-omit-frame-pointer" \ | |
| EXTRA_LDFLAGS="-fsanitize=address" | |
| cp objs/bin/mtproto-proxy mtproxy-run/ | |
| cd mtproxy-run | |
| ASAN_OPTIONS=detect_leaks=0 \ | |
| ./mtproto-proxy -u nobody -p 7888 -H 7443 -S $MTPROXY_SECRET \ | |
| --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 0 \ | |
| >asan-bug.log 2>&1 & | |
| BUG_PID=$! | |
| sleep 5 | |
| kill "$BUG_PID" 2>/dev/null || true | |
| wait "$BUG_PID" 2>/dev/null || true | |
| if grep -q "heap-buffer-overflow" asan-bug.log; then | |
| echo "ASan correctly detected the known heap-buffer-overflow" | |
| else | |
| echo "::error::ASan did NOT detect the known heap overflow" | |
| echo "--- asan-bug.log ---" | |
| cat asan-bug.log | |
| exit 1 | |
| fi | |
| - name: Restore source tree | |
| if: always() | |
| run: git checkout -- mtproto/mtproto-proxy.c |