diff --git a/.github/update.log b/.github/update.log index b3865f4146..c614777ff0 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1228,3 +1228,4 @@ Update On Sat Dec 27 19:38:28 CET 2025 Update On Sun Dec 28 19:39:20 CET 2025 Update On Mon Dec 29 19:42:01 CET 2025 Update On Tue Dec 30 19:43:26 CET 2025 +Update On Wed Dec 31 19:39:51 CET 2025 diff --git a/brook/ping/ping.json b/brook/ping/ping.json index f218e6b647..672dac291c 100644 --- a/brook/ping/ping.json +++ b/brook/ping/ping.json @@ -1,7 +1,7 @@ { - "version": "20250808", - "text": "Pre-release reminder: Brook v20260101, released on January 1, 2026, will reset the local cache. Please back up the brook link and script beforehand.", - "link": "https://www.txthinking.com/talks/articles/brook-v20260101-en.article", - "text_zh": "预发布提醒:在 2026-01-01 发布的 Brook v20260101 将会重置本地缓存。请提前备份 brook link 和 script。", - "link_zh": "https://www.txthinking.com/talks/articles/brook-v20260101.article" + "version": "20260101", + "text": "", + "link": "", + "text_zh": "", + "link_zh": "" } diff --git a/clash-meta/adapter/inbound/listen.go b/clash-meta/adapter/inbound/listen.go index b4c6bf6b6a..de4dcf4049 100644 --- a/clash-meta/adapter/inbound/listen.go +++ b/clash-meta/adapter/inbound/listen.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" "github.com/metacubex/tfo-go" ) @@ -34,13 +35,13 @@ func Tfo() bool { func SetMPTCP(open bool) { mutex.Lock() defer mutex.Unlock() - setMultiPathTCP(&lc.ListenConfig, open) + mptcp.SetNetListenConfig(&lc.ListenConfig, open) } func MPTCP() bool { mutex.RLock() defer mutex.RUnlock() - return getMultiPathTCP(&lc.ListenConfig) + return mptcp.GetNetListenConfig(&lc.ListenConfig) } func preResolve(network, address string) (string, error) { diff --git a/clash-meta/adapter/inbound/mptcp_go120.go b/clash-meta/adapter/inbound/mptcp_go120.go deleted file mode 100644 index faae6ec5d8..0000000000 --- a/clash-meta/adapter/inbound/mptcp_go120.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build !go1.21 - -package inbound - -import "net" - -const multipathTCPAvailable = false - -func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { -} - -func getMultiPathTCP(listenConfig *net.ListenConfig) bool { - return false -} diff --git a/clash-meta/adapter/inbound/mptcp_go121.go b/clash-meta/adapter/inbound/mptcp_go121.go deleted file mode 100644 index 9163878a70..0000000000 --- a/clash-meta/adapter/inbound/mptcp_go121.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build go1.21 - -package inbound - -import "net" - -const multipathTCPAvailable = true - -func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { - listenConfig.SetMultipathTCP(open) -} - -func getMultiPathTCP(listenConfig *net.ListenConfig) bool { - return listenConfig.MultipathTCP() -} diff --git a/clash-meta/component/dialer/dialer.go b/clash-meta/component/dialer/dialer.go index d490dca3de..4bc69baa67 100644 --- a/clash-meta/component/dialer/dialer.go +++ b/clash-meta/component/dialer/dialer.go @@ -13,6 +13,7 @@ import ( "time" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" "github.com/metacubex/mihomo/component/resolver" ) @@ -140,9 +141,7 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po dialer := netDialer.(*net.Dialer) keepalive.SetNetDialer(dialer) - if opt.mpTcp { - setMultiPathTCP(dialer) - } + mptcp.SetNetDialer(dialer, opt.mpTcp) if DefaultSocketHook != nil { // ignore interfaceName, routingMark and tfo when DefaultSocketHook not null (in CMFA) socketHookToToDialer(dialer) diff --git a/clash-meta/component/dialer/mptcp_go120.go b/clash-meta/component/dialer/mptcp_go120.go deleted file mode 100644 index 6e564673b4..0000000000 --- a/clash-meta/component/dialer/mptcp_go120.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build !go1.21 - -package dialer - -import ( - "net" -) - -const multipathTCPAvailable = false - -func setMultiPathTCP(dialer *net.Dialer) { -} diff --git a/clash-meta/component/dialer/mptcp_go121.go b/clash-meta/component/dialer/mptcp_go121.go deleted file mode 100644 index 360826c88d..0000000000 --- a/clash-meta/component/dialer/mptcp_go121.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build go1.21 - -package dialer - -import "net" - -const multipathTCPAvailable = true - -func setMultiPathTCP(dialer *net.Dialer) { - dialer.SetMultipathTCP(true) -} diff --git a/clash-meta/component/mptcp/mptcp_go120.go b/clash-meta/component/mptcp/mptcp_go120.go new file mode 100644 index 0000000000..beee7412d6 --- /dev/null +++ b/clash-meta/component/mptcp/mptcp_go120.go @@ -0,0 +1,23 @@ +//go:build !go1.21 + +package mptcp + +import ( + "net" +) + +const MultipathTCPAvailable = false + +func SetNetDialer(dialer *net.Dialer, open bool) { +} + +func GetNetDialer(dialer *net.Dialer) bool { + return false +} + +func SetNetListenConfig(listenConfig *net.ListenConfig, open bool) { +} + +func GetNetListenConfig(listenConfig *net.ListenConfig) bool { + return false +} diff --git a/clash-meta/component/mptcp/mptcp_go121.go b/clash-meta/component/mptcp/mptcp_go121.go new file mode 100644 index 0000000000..f492d99cc7 --- /dev/null +++ b/clash-meta/component/mptcp/mptcp_go121.go @@ -0,0 +1,23 @@ +//go:build go1.21 + +package mptcp + +import "net" + +const MultipathTCPAvailable = true + +func SetNetDialer(dialer *net.Dialer, open bool) { + dialer.SetMultipathTCP(open) +} + +func GetNetDialer(dialer *net.Dialer) bool { + return dialer.MultipathTCP() +} + +func SetNetListenConfig(listenConfig *net.ListenConfig, open bool) { + listenConfig.SetMultipathTCP(open) +} + +func GetNetListenConfig(listenConfig *net.ListenConfig) bool { + return listenConfig.MultipathTCP() +} diff --git a/clash-meta/listener/tproxy/tproxy.go b/clash-meta/listener/tproxy/tproxy.go index b848c0dccc..25c8adf7b9 100644 --- a/clash-meta/listener/tproxy/tproxy.go +++ b/clash-meta/listener/tproxy/tproxy.go @@ -1,10 +1,12 @@ package tproxy import ( + "context" "net" "github.com/metacubex/mihomo/adapter/inbound" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/transport/socks5" ) @@ -46,10 +48,11 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener inbound.WithSpecialRules(""), } } - //TODO: When we upgrade the major version of go.mod to 1.24 or higher, disable mptcp for tproxy. - // Golang will then enable mptcp support for listeners by default. - // This can cause tproxy to malfunction on certain Linux kernel versions. - l, err := net.Listen("tcp", addr) + // Golang will then enable mptcp support for listeners by default when the major version of go.mod is 1.24 or higher. + // This can cause tproxy to malfunction on certain Linux kernel versions, so we force to disable mptcp for tproxy. + lc := net.ListenConfig{} + mptcp.SetNetListenConfig(&lc, false) + l, err := lc.Listen(context.Background(), "tcp", addr) if err != nil { return nil, err } diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 189c650613..99f33c31b4 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,10 +2,10 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.18", - "mihomo_alpha": "alpha-06387d5", + "mihomo_alpha": "alpha-eb30d3f", "clash_rs": "v0.9.3", "clash_premium": "2023-09-05-gdcc8d87", - "clash_rs_alpha": "0.9.3-alpha+sha.61736d2" + "clash_rs_alpha": "0.9.3-alpha+sha.626fbd4" }, "arch_template": { "mihomo": { @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-12-29T22:21:33.860Z" + "updated_at": "2025-12-30T22:21:41.929Z" } diff --git a/geoip/README.md b/geoip/README.md index 852c97e765..b6277b2bb3 100644 --- a/geoip/README.md +++ b/geoip/README.md @@ -11,7 +11,7 @@ This project releases various formats of GeoIP files automatically every Thursda 另外,本项目对 MaxMind 官方 GeoIP 数据做了修改和新增: - 中国大陆 IPv4 地址数据融合了 [IPIP.net](https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt) 和 [@gaoyifan/china-operator-ip](https://github.com/gaoyifan/china-operator-ip/blob/ip-lists/china.txt) -- 中国大陆 IPv6 地址数据融合了 MaxMind GeoLite2 和 [@gaoyifan/china-operator-ip](https://github.com/gaoyifan/china-operator-ip/blob/ip-lists/china6.txt) +- 中国大陆 IPv6 地址数据使用 [@gaoyifan/china-operator-ip](https://github.com/gaoyifan/china-operator-ip/blob/ip-lists/china6.txt) - 新增类别(方便有特殊需求的用户使用): - `geoip:cloudflare`(`GEOIP,CLOUDFLARE`) - `geoip:cloudfront`(`GEOIP,CLOUDFRONT`) diff --git a/geoip/config.json b/geoip/config.json index d765406447..5788cde494 100644 --- a/geoip/config.json +++ b/geoip/config.json @@ -13,8 +13,7 @@ "type": "cutter", "action": "remove", "args": { - "wantedList": ["cn"], - "onlyIPType": "ipv4" + "wantedList": ["cn"] } }, { diff --git a/lede/scripts/download.pl b/lede/scripts/download.pl index 66dde0c73e..6d481013db 100755 --- a/lede/scripts/download.pl +++ b/lede/scripts/download.pl @@ -257,15 +257,12 @@ foreach my $mirror (@ARGV) { } elsif ($mirror =~ /^\@APACHE\/(.+)$/) { push @mirrors, "https://mirrors.aliyun.com/apache/$1"; push @mirrors, "https://mirrors.tencent.com/apache/$1"; - push @mirrors, "https://mirror.netcologne.de/apache.org/$1"; push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1"; + push @mirrors, "https://mirror.cogentco.com/pub/apache/$1"; + push @mirrors, "https://mirror.navercorp.com/apache/$1"; + push @mirrors, "https://ftp.jaist.ac.jp/pub/apache/$1"; push @mirrors, "https://archive.apache.org/dist/$1"; - push @mirrors, "http://mirror.cogentco.com/pub/apache/$1"; - push @mirrors, "http://mirror.navercorp.com/apache/$1"; - push @mirrors, "http://ftp.jaist.ac.jp/pub/apache/$1"; - push @mirrors, "ftp://apache.cs.utah.edu/apache.org/$1"; - push @mirrors, "ftp://apache.mirrors.ovh.net/ftp.apache.org/dist/$1"; } elsif ($mirror =~ /^\@GITHUB\/(.+)$/) { # give github a few more tries (different mirrors) for (1 .. 5) { @@ -278,18 +275,15 @@ foreach my $mirror (@ARGV) { push @mirrors, "https://mirror.netcologne.de/gnu/$1"; push @mirrors, "http://www.nic.funet.fi/pub/gnu/gnu/$1"; push @mirrors, "http://mirror.internode.on.net/pub/gnu/$1"; - push @mirrors, "http://mirror.navercorp.com/gnu/$1"; - push @mirrors, "ftp://mirrors.rit.edu/gnu/$1"; - push @mirrors, "ftp://download.xs4all.nl/pub/gnu/$1"; + push @mirrors, "https://mirror.navercorp.com/gnu/$1"; push @mirrors, "https://ftp.gnu.org/gnu/$1"; } elsif ($mirror =~ /^\@SAVANNAH\/(.+)$/) { + push @mirrors, "https://nongnu.uib.no/$1"; + push @mirrors, "https://nongnu.niranjan.co/$1"; push @mirrors, "https://mirror.netcologne.de/savannah/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/nongnu/$1"; + push @mirrors, "https://download.savannah.nongnu.org/releases/$1"; push @mirrors, "http://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; - push @mirrors, "http://nongnu.uib.no/$1"; - push @mirrors, "http://ftp.igh.cnrs.fr/pub/nongnu/$1"; - push @mirrors, "ftp://cdimage.debian.org/mirror/gnu.org/savannah/$1"; - push @mirrors, "ftp://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; } elsif ($mirror =~ /^\@KERNEL\/(.+)$/) { my @extra = ( $1 ); if ($filename =~ /linux-\d+\.\d+(?:\.\d+)?-rc/) { @@ -298,22 +292,17 @@ foreach my $mirror (@ARGV) { push @extra, "$extra[0]/longterm/v$1"; } foreach my $dir (@extra) { - push @mirrors, "https://mirror.iscas.ac.cn/kernel.org/$dir"; + push @mirrors, "https://mirror.nju.edu.cn/kernel.org/$dir"; + push @mirrors, "https://mirrors.hust.edu.cn/kernel.org/$dir"; push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir"; push @mirrors, "https://cdn.kernel.org/pub/$dir"; - push @mirrors, "https://download.xs4all.nl/ftp.kernel.org/pub/$dir"; push @mirrors, "https://mirrors.mit.edu/kernel/$dir"; push @mirrors, "http://ftp.nara.wide.ad.jp/pub/kernel.org/$dir"; - push @mirrors, "http://www.ring.gr.jp/archives/linux/kernel.org/$dir"; - push @mirrors, "ftp://ftp.riken.jp/Linux/kernel.org/$dir"; - push @mirrors, "ftp://www.mirrorservice.org/sites/ftp.kernel.org/pub/$dir"; } } elsif ($mirror =~ /^\@GNOME\/(.+)$/) { - push @mirrors, "https://mirrors.ustc.edu.cn/gnome/sources/$1"; + push @mirrors, "https://mirror.nju.edu.cn/gnome/sources/$1"; push @mirrors, "https://download.gnome.org/sources/$1"; push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnome/sources/$1"; - push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1"; - push @mirrors, "http://ftp.cse.buffalo.edu/pub/Gnome/sources/$1"; push @mirrors, "http://ftp.nara.wide.ad.jp/pub/X11/GNOME/sources/$1"; } else { push @mirrors, $mirror; diff --git a/mihomo/adapter/inbound/listen.go b/mihomo/adapter/inbound/listen.go index b4c6bf6b6a..de4dcf4049 100644 --- a/mihomo/adapter/inbound/listen.go +++ b/mihomo/adapter/inbound/listen.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" "github.com/metacubex/tfo-go" ) @@ -34,13 +35,13 @@ func Tfo() bool { func SetMPTCP(open bool) { mutex.Lock() defer mutex.Unlock() - setMultiPathTCP(&lc.ListenConfig, open) + mptcp.SetNetListenConfig(&lc.ListenConfig, open) } func MPTCP() bool { mutex.RLock() defer mutex.RUnlock() - return getMultiPathTCP(&lc.ListenConfig) + return mptcp.GetNetListenConfig(&lc.ListenConfig) } func preResolve(network, address string) (string, error) { diff --git a/mihomo/adapter/inbound/mptcp_go120.go b/mihomo/adapter/inbound/mptcp_go120.go deleted file mode 100644 index faae6ec5d8..0000000000 --- a/mihomo/adapter/inbound/mptcp_go120.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build !go1.21 - -package inbound - -import "net" - -const multipathTCPAvailable = false - -func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { -} - -func getMultiPathTCP(listenConfig *net.ListenConfig) bool { - return false -} diff --git a/mihomo/adapter/inbound/mptcp_go121.go b/mihomo/adapter/inbound/mptcp_go121.go deleted file mode 100644 index 9163878a70..0000000000 --- a/mihomo/adapter/inbound/mptcp_go121.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build go1.21 - -package inbound - -import "net" - -const multipathTCPAvailable = true - -func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) { - listenConfig.SetMultipathTCP(open) -} - -func getMultiPathTCP(listenConfig *net.ListenConfig) bool { - return listenConfig.MultipathTCP() -} diff --git a/mihomo/component/dialer/dialer.go b/mihomo/component/dialer/dialer.go index d490dca3de..4bc69baa67 100644 --- a/mihomo/component/dialer/dialer.go +++ b/mihomo/component/dialer/dialer.go @@ -13,6 +13,7 @@ import ( "time" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" "github.com/metacubex/mihomo/component/resolver" ) @@ -140,9 +141,7 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po dialer := netDialer.(*net.Dialer) keepalive.SetNetDialer(dialer) - if opt.mpTcp { - setMultiPathTCP(dialer) - } + mptcp.SetNetDialer(dialer, opt.mpTcp) if DefaultSocketHook != nil { // ignore interfaceName, routingMark and tfo when DefaultSocketHook not null (in CMFA) socketHookToToDialer(dialer) diff --git a/mihomo/component/dialer/mptcp_go120.go b/mihomo/component/dialer/mptcp_go120.go deleted file mode 100644 index 6e564673b4..0000000000 --- a/mihomo/component/dialer/mptcp_go120.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build !go1.21 - -package dialer - -import ( - "net" -) - -const multipathTCPAvailable = false - -func setMultiPathTCP(dialer *net.Dialer) { -} diff --git a/mihomo/component/dialer/mptcp_go121.go b/mihomo/component/dialer/mptcp_go121.go deleted file mode 100644 index 360826c88d..0000000000 --- a/mihomo/component/dialer/mptcp_go121.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build go1.21 - -package dialer - -import "net" - -const multipathTCPAvailable = true - -func setMultiPathTCP(dialer *net.Dialer) { - dialer.SetMultipathTCP(true) -} diff --git a/mihomo/component/mptcp/mptcp_go120.go b/mihomo/component/mptcp/mptcp_go120.go new file mode 100644 index 0000000000..beee7412d6 --- /dev/null +++ b/mihomo/component/mptcp/mptcp_go120.go @@ -0,0 +1,23 @@ +//go:build !go1.21 + +package mptcp + +import ( + "net" +) + +const MultipathTCPAvailable = false + +func SetNetDialer(dialer *net.Dialer, open bool) { +} + +func GetNetDialer(dialer *net.Dialer) bool { + return false +} + +func SetNetListenConfig(listenConfig *net.ListenConfig, open bool) { +} + +func GetNetListenConfig(listenConfig *net.ListenConfig) bool { + return false +} diff --git a/mihomo/component/mptcp/mptcp_go121.go b/mihomo/component/mptcp/mptcp_go121.go new file mode 100644 index 0000000000..f492d99cc7 --- /dev/null +++ b/mihomo/component/mptcp/mptcp_go121.go @@ -0,0 +1,23 @@ +//go:build go1.21 + +package mptcp + +import "net" + +const MultipathTCPAvailable = true + +func SetNetDialer(dialer *net.Dialer, open bool) { + dialer.SetMultipathTCP(open) +} + +func GetNetDialer(dialer *net.Dialer) bool { + return dialer.MultipathTCP() +} + +func SetNetListenConfig(listenConfig *net.ListenConfig, open bool) { + listenConfig.SetMultipathTCP(open) +} + +func GetNetListenConfig(listenConfig *net.ListenConfig) bool { + return listenConfig.MultipathTCP() +} diff --git a/mihomo/listener/tproxy/tproxy.go b/mihomo/listener/tproxy/tproxy.go index b848c0dccc..25c8adf7b9 100644 --- a/mihomo/listener/tproxy/tproxy.go +++ b/mihomo/listener/tproxy/tproxy.go @@ -1,10 +1,12 @@ package tproxy import ( + "context" "net" "github.com/metacubex/mihomo/adapter/inbound" "github.com/metacubex/mihomo/component/keepalive" + "github.com/metacubex/mihomo/component/mptcp" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/transport/socks5" ) @@ -46,10 +48,11 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener inbound.WithSpecialRules(""), } } - //TODO: When we upgrade the major version of go.mod to 1.24 or higher, disable mptcp for tproxy. - // Golang will then enable mptcp support for listeners by default. - // This can cause tproxy to malfunction on certain Linux kernel versions. - l, err := net.Listen("tcp", addr) + // Golang will then enable mptcp support for listeners by default when the major version of go.mod is 1.24 or higher. + // This can cause tproxy to malfunction on certain Linux kernel versions, so we force to disable mptcp for tproxy. + lc := net.ListenConfig{} + mptcp.SetNetListenConfig(&lc, false) + l, err := lc.Listen(context.Background(), "tcp", addr) if err != nil { return nil, err } diff --git a/openclash/.github/workflows/compile_meta_core.yml b/openclash/.github/workflows/compile_meta_core.yml index 27a4699790..a3d3ac6a0b 100644 --- a/openclash/.github/workflows/compile_meta_core.yml +++ b/openclash/.github/workflows/compile_meta_core.yml @@ -58,7 +58,7 @@ jobs: if: ${{ needs.Get-Commit-id.outputs.current_id != needs.Get-Commit-id.outputs.upstream_id }} strategy: matrix: - arch: [normal, loongarch_abi1, loongarch_abi2] + arch: [normal, loongarch_abi1] steps: - name: Checkout OpenClash Repository uses: actions/checkout@v4 @@ -85,16 +85,13 @@ jobs: mkdir -p ${{ github.workspace }}/build_temp/meta_makefiles/loong64_abi1 cp ${{ github.workspace }}/.github/makefile/meta_loongarch_abi1 ${{ github.workspace }}/build_temp/meta_makefiles/loong64_abi1/Makefile - - mkdir -p ${{ github.workspace }}/build_temp/meta_makefiles/loong64_abi2 - cp ${{ github.workspace }}/.github/makefile/meta_loongarch_abi2 ${{ github.workspace }}/build_temp/meta_makefiles/loong64_abi2/Makefile mkdir -p ${{ github.workspace }}/build_temp/meta_output/${{ matrix.arch }}/bin - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: "1.24" + go-version: "1.25" check-latest: true cache: false @@ -108,19 +105,10 @@ jobs: id: cache_go_abi1 uses: actions/cache@v4 with: - path: ${{ steps.go_paths.outputs.archive_dir }}/go1.22.4.linux-amd64-abi1.tar.gz - key: go-loongarch-abi1-1.22.4-${{ matrix.arch }} + path: ${{ steps.go_paths.outputs.archive_dir }}/go1.24.0.linux-amd64-abi1.tar.gz + key: go-loongarch-abi1-1.24.0-${{ matrix.arch }} restore-keys: | - go-loongarch-abi1-1.22.4- - - - name: Cache Go loongarch abi2 tarball - id: cache_go_abi2 - uses: actions/cache@v4 - with: - path: ${{ steps.go_paths.outputs.archive_dir }}/go1.22.4.linux-amd64-abi2.tar.gz - key: go-loongarch-abi2-1.22.4-${{ matrix.arch }} - restore-keys: | - go-loongarch-abi2-1.22.4- + go-loongarch-abi1-1.24.0- - name: Clone MetaCubeX/mihomo source uses: actions/checkout@v4 @@ -142,10 +130,10 @@ jobs: ;; loongarch_abi1) echo "Setup Go for loongarch abi1" - GO_TAR_FILE="go1.22.4.linux-amd64-abi1.tar.gz" + GO_TAR_FILE="go1.24.0.linux-amd64-abi1.tar.gz" if [[ "${{ steps.cache_go_abi1.outputs.cache-hit }}" != 'true' ]]; then echo "Cache not found for $GO_TAR_FILE, downloading..." - wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.22.4/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" + wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.24.0/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" else echo "Restored $GO_TAR_FILE from cache." fi @@ -154,20 +142,6 @@ jobs: echo "/usr/local/go/bin" >> $GITHUB_PATH cp ../build_temp/meta_makefiles/loong64_abi1/Makefile ./Makefile ;; - loongarch_abi2) - echo "Setup Go for loongarch abi2" - GO_TAR_FILE="go1.22.4.linux-amd64-abi2.tar.gz" - if [[ "${{ steps.cache_go_abi2.outputs.cache-hit }}" != 'true' ]]; then - echo "Cache not found for $GO_TAR_FILE, downloading..." - wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.22.4/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" - else - echo "Restored $GO_TAR_FILE from cache." - fi - sudo rm -rf /usr/local/go || true - sudo tar zxf "$GO_ARCHIVE_DIR/$GO_TAR_FILE" -C /usr/local - echo "/usr/local/go/bin" >> $GITHUB_PATH - cp ../build_temp/meta_makefiles/loong64_abi2/Makefile ./Makefile - ;; esac go version make releases @@ -186,7 +160,7 @@ jobs: if: ${{ needs.Get-Commit-id.outputs.current_smart_id != needs.Get-Commit-id.outputs.upstream_smart_id }} strategy: matrix: - arch: [normal, loongarch_abi1, loongarch_abi2] + arch: [normal, loongarch_abi1] steps: - name: Checkout OpenClash Repository uses: actions/checkout@v4 @@ -215,10 +189,6 @@ jobs: mkdir -p ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi1 cp ${{ github.workspace }}/.github/makefile/meta_loongarch_abi1 ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi1/Makefile sed -i 's/VERSION=alpha-g/VERSION=alpha-smart-g/' ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi1/Makefile - - mkdir -p ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi2 - cp ${{ github.workspace }}/.github/makefile/meta_loongarch_abi2 ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi2/Makefile - sed -i 's/VERSION=alpha-g/VERSION=alpha-smart-g/' ${{ github.workspace }}/build_temp/smart_makefiles/loong64_abi2/Makefile mkdir -p ${{ github.workspace }}/build_temp/smart_output/${{ matrix.arch }}/bin @@ -239,19 +209,10 @@ jobs: id: cache_go_abi1 uses: actions/cache@v4 with: - path: ${{ steps.go_paths.outputs.archive_dir }}/go1.22.4.linux-amd64-abi1.tar.gz - key: go-loongarch-abi1-1.22.4-${{ matrix.arch }} + path: ${{ steps.go_paths.outputs.archive_dir }}/go1.24.0.linux-amd64-abi1.tar.gz + key: go-loongarch-abi1-1.24.0-${{ matrix.arch }} restore-keys: | - go-loongarch-abi1-1.22.4- - - - name: Cache Go loongarch abi2 tarball - id: cache_go_abi2 - uses: actions/cache@v4 - with: - path: ${{ steps.go_paths.outputs.archive_dir }}/go1.22.4.linux-amd64-abi2.tar.gz - key: go-loongarch-abi2-1.22.4-${{ matrix.arch }} - restore-keys: | - go-loongarch-abi2-1.22.4- + go-loongarch-abi1-1.24.0- - name: Clone vernesong/mihomo source uses: actions/checkout@v4 @@ -273,10 +234,10 @@ jobs: ;; loongarch_abi1) echo "Setup Go for loongarch abi1" - GO_TAR_FILE="go1.22.4.linux-amd64-abi1.tar.gz" + GO_TAR_FILE="go1.24.0.linux-amd64-abi1.tar.gz" if [ ! -f "$GO_ARCHIVE_DIR/$GO_TAR_FILE" ]; then echo "CRITICAL: $GO_TAR_FILE not found in $GO_ARCHIVE_DIR. Attempting fallback download." - wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.22.4/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" + wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.24.0/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" if [ ! -f "$GO_ARCHIVE_DIR/$GO_TAR_FILE" ]; then echo "ERROR: Fallback download for $GO_TAR_FILE failed. Exiting." exit 1 @@ -287,22 +248,6 @@ jobs: echo "/usr/local/go/bin" >> $GITHUB_PATH cp ../build_temp/smart_makefiles/loong64_abi1/Makefile ./Makefile ;; - loongarch_abi2) - echo "Setup Go for loongarch abi2" - GO_TAR_FILE="go1.22.4.linux-amd64-abi2.tar.gz" - if [ ! -f "$GO_ARCHIVE_DIR/$GO_TAR_FILE" ]; then - echo "CRITICAL: $GO_TAR_FILE not found in $GO_ARCHIVE_DIR. Attempting fallback download." - wget -q "https://github.com/MetaCubeX/loongarch64-golang/releases/download/1.22.4/$GO_TAR_FILE" -O "$GO_ARCHIVE_DIR/$GO_TAR_FILE" - if [ ! -f "$GO_ARCHIVE_DIR/$GO_TAR_FILE" ]; then - echo "ERROR: Fallback download for $GO_TAR_FILE failed. Exiting." - exit 1 - fi - fi - sudo rm -rf /usr/local/go || true - sudo tar zxf "$GO_ARCHIVE_DIR/$GO_TAR_FILE" -C /usr/local - echo "/usr/local/go/bin" >> $GITHUB_PATH - cp ../build_temp/smart_makefiles/loong64_abi2/Makefile ./Makefile - ;; esac go version make releases @@ -345,7 +290,7 @@ jobs: echo "Organizing MetaCubeX compiled files..." if [ "${{ needs.Compile_Meta_Core.result }}" == "success" ] || [ "${{ needs.Compile_Meta_Core.result }}" == "skipped" ]; then rm -rf ./dev/meta/* - for arch_type in normal loongarch_abi1 loongarch_abi2; do + for arch_type in normal loongarch_abi1; do if [ -d ./downloaded-artifacts/meta-core-$arch_type ] && [ -n "$(ls -A ./downloaded-artifacts/meta-core-$arch_type)" ]; then echo "Copying meta-core-$arch_type files..." cp -rf ./downloaded-artifacts/meta-core-$arch_type/. ./dev/meta/ @@ -365,7 +310,7 @@ jobs: echo "Organizing vernesong compiled files..." if [ "${{ needs.Compile_Smart_Core.result }}" == "success" ] || [ "${{ needs.Compile_Smart_Core.result }}" == "skipped" ]; then rm -rf ./dev/smart/* - for arch_type in normal loongarch_abi1 loongarch_abi2; do + for arch_type in normal loongarch_abi1; do if [ -d ./downloaded-artifacts/smart-core-$arch_type ] && [ -n "$(ls -A ./downloaded-artifacts/smart-core-$arch_type)" ]; then echo "Copying smart-core-$arch_type files..." cp -rf ./downloaded-artifacts/smart-core-$arch_type/. ./dev/smart/ diff --git a/openclash/.github/workflows/compile_new_ipk.yml b/openclash/.github/workflows/compile_new_ipk.yml index 1c8322612c..de31f5b1e3 100644 --- a/openclash/.github/workflows/compile_new_ipk.yml +++ b/openclash/.github/workflows/compile_new_ipk.yml @@ -100,7 +100,6 @@ jobs: run: | CHNR_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/etc/openclash/china_ip_route.ipset CHNR6_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/etc/openclash/china_ip6_route.ipset - YACD_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/usr/share/openclash/ui/yacd ZASHBOARD_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/usr/share/openclash/ui/zashboard METACUBEXD_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/usr/share/openclash/ui/metacubexd GEOSITE_PATH=tmp/${{ matrix.target.sdk_dir }}/package/luci-app-openclash/root/etc/openclash/GeoSite.dat @@ -124,15 +123,6 @@ jobs: rm -rf "$METACUBEXD_PATH"/* cp -rf "$METACUBEXD_UNZIP_PATH"/* "$METACUBEXD_PATH" - # 更新 Yacd UI - mkdir -p tmp/yacd_zip - curl -sSL https://github.com/MetaCubeX/Yacd-meta/archive/refs/heads/gh-pages.zip -o tmp/yacd.zip - unzip -q -o tmp/yacd.zip -d tmp/yacd_zip - YACD_UNZIP_PATH="tmp/yacd_zip/Yacd-meta-gh-pages" - mkdir -p "$YACD_PATH" - rm -rf "$YACD_PATH"/* - cp -rf "$YACD_UNZIP_PATH"/* "$YACD_PATH" - # 更新 ZashBoard UI mkdir -p tmp/zashboard_zip curl -sSL https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip -o tmp/zashboard.zip diff --git a/openclash/luci-app-openclash/Makefile b/openclash/luci-app-openclash/Makefile index d7e09e4c39..30c33d10d9 100644 --- a/openclash/luci-app-openclash/Makefile +++ b/openclash/luci-app-openclash/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-openclash -PKG_VERSION:=0.47.028 +PKG_VERSION:=0.47.038 PKG_MAINTAINER:=vernesong PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) diff --git a/openclash/luci-app-openclash/luasrc/controller/openclash.lua b/openclash/luci-app-openclash/luasrc/controller/openclash.lua index 814d5166fd..15d4b5a2b1 100644 --- a/openclash/luci-app-openclash/luasrc/controller/openclash.lua +++ b/openclash/luci-app-openclash/luasrc/controller/openclash.lua @@ -139,33 +139,6 @@ local function is_start() end local function cn_port() - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - port = config['external-controller'] - if port - port = port.to_s - if port:include?(':') - port = port.split(':')[-1] - end - puts port - end - end - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - return ruby_result - end - end - end return fs.uci_get_config("config", "cn_port") or "9090" end @@ -178,27 +151,6 @@ local function daip() end local function dase() - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - dase = config['secret'] - puts \"#{dase}\" - end - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - return ruby_result - end - end - end return fs.uci_get_config("config", "dashboard_password") end @@ -440,11 +392,11 @@ function action_update_config() -- filename or config_file is basename local filename = luci.http.formvalue("filename") local config_file = luci.http.formvalue("config_file") - + if not filename and config_file then filename = config_file end - + luci.http.prepare_content("application/json") if not filename then @@ -454,9 +406,9 @@ function action_update_config() }) return end - + local update_result = luci.sys.call(string.format("/usr/share/openclash/openclash.sh '%s' >/dev/null 2>&1", filename)) - + if update_result == 0 then luci.http.write_json({ status = "success", @@ -709,11 +661,11 @@ end function action_switch_config() local config_file = luci.http.formvalue("config_file") local config_name = luci.http.formvalue("config_name") - + if not config_file and config_name then config_file = "/etc/openclash/config/" .. config_name end - + if not config_file then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -722,7 +674,7 @@ function action_switch_config() }) return end - + if not fs.access(config_file) then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -731,13 +683,13 @@ function action_switch_config() }) return end - + uci:set("openclash", "config", "config_path", config_file) uci:set("openclash", "config", "enable", "1") uci:commit("openclash") luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1 &") - + luci.http.prepare_content("application/json") luci.http.write_json({ status = "success", @@ -788,12 +740,204 @@ function set_subinfo_url() }) end -function sub_info_get() - local sub_ua, filepath, filename, sub_url, sub_info, info, upload, download, total, expire, http_code, len, percent, day_left, day_expire, surplus, used +function fetch_sub_info(sub_url, sub_ua) + local info, upload, download, total, day_expire, http_code + local used, expire, day_left, percent, surplus + + info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code=%%{http_code}' -H 'User-Agent: %s' '%s'", sub_ua, sub_url)) + local http_match = string.match(info, "http_code=(%d+)") + if not info or not http_match or tonumber(http_match) ~= 200 then + info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code=%%{http_code}' -H 'User-Agent: Quantumultx' '%s'", sub_url)) + http_match = string.match(info, "http_code=(%d+)") + end + + if info and http_match then + http_code = http_match + if tonumber(http_code) == 200 then + info = string.lower(info) + if string.find(info, "subscription%-userinfo") then + local sub_info_line = "" + for line in info:gmatch("[^\r\n]+") do + if string.find(line, "subscription%-userinfo") then + sub_info_line = line + break + end + end + info = sub_info_line + local upload_match = string.match(info, "upload=(%d+)") + local download_match = string.match(info, "download=(%d+)") + local total_match = string.match(info, "total=(%d+)") + local expire_match = string.match(info, "expire=(%d+)") + + upload = upload_match and tonumber(upload_match) or nil + download = download_match and tonumber(download_match) or nil + total = total_match and tonumber(string.format("%.1f", total_match)) or nil + used = upload and download and tonumber(string.format("%.1f", upload + download)) or nil + day_expire = expire_match and tonumber(expire_match) or nil + + if day_expire and day_expire == 0 then + expire = luci.i18n.translate("Long-term") + elseif day_expire then + expire = os.date("%Y-%m-%d %H:%M:%S", day_expire) or "null" + else + expire = "null" + end + + if day_expire and day_expire ~= 0 and os.time() <= day_expire then + day_left = math.ceil((day_expire - os.time()) / (3600*24)) + if math.ceil(day_left / 365) > 50 then + day_left = "∞" + end + elseif day_expire and day_expire == 0 then + day_left = "∞" + elseif day_expire == nil then + day_left = "null" + else + day_left = 0 + end + + if used and total and used <= total and total > 0 then + percent = string.format("%.1f",((total-used)/total)*100) or "100" + surplus = fs.filesize(total - used) + elseif used and total and used > total and total > 0 then + percent = "0" + surplus = "-"..fs.filesize(total - used) + elseif used and total and used < total and total == 0.0 then + percent = "0" + surplus = fs.filesize(total - used) + elseif used and total and used == total and total == 0.0 then + percent = "0" + surplus = "0.0 KB" + elseif used and total and used > total and total == 0.0 then + percent = "100" + surplus = fs.filesize(total - used) + elseif used == nil and total and total > 0.0 then + percent = 100 + surplus = fs.filesize(total) + elseif used == nil and total and total == 0.0 then + percent = 100 + surplus = "∞" + else + percent = 0 + surplus = "null" + end + + local total_formatted, used_formatted + if total and total > 0 then + total_formatted = fs.filesize(total) + elseif total and total == 0.0 then + total_formatted = "∞" + else + total_formatted = "null" + end + used_formatted = fs.filesize(used) + + return { + http_code = http_code, + surplus = surplus, + used = used_formatted, + total = total_formatted, + percent = percent, + day_left = day_left, + expire = expire + } + end + end + end + + return nil +end + +-- Get subscription URL with priority (Priority 1: subscribe_info, Priority 2: YAML proxy-providers, Priority 3: config_subscribe) +function get_sub_url(filename) + local sub_url = nil local info_tb = {} + local providers = {} + + -- Priority 1: subscribe_info + uci:foreach("openclash", "subscribe_info", + function(s) + if s.name == filename and s.url and string.find(s.url, "http") then + string.gsub(s.url, '[^\n]+', function(w) table.insert(info_tb, w) end) + sub_url = info_tb[1] + end + end + ) + + if sub_url then + return {type = "single", url = sub_url} + end + + -- Priority 2: YAML proxy-providers (use actual config file content first) + local config_path = "/etc/openclash/config/" .. fs.basename(filename .. ".yaml") + + if fs.access(config_path) then + local ruby_result = luci.sys.exec(string.format([[ + ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e ' + begin + config = YAML.load_file("%s") + providers = [] + if config && config["proxy-providers"] + config["proxy-providers"].each do |name, provider| + # Only include providers with non-empty URLs + if provider && provider["url"] && !provider["url"].to_s.empty? + providers << {"name" => name, "url" => provider["url"].to_s} + end + end + end + # Manual JSON output (ruby-json is not a dependency) + result = "[" + providers.each_with_index do |p, i| + result << "," if i > 0 + # Escape quotes in name and URL + name_escaped = p["name"].gsub("\"", "\\\\\"") + url_escaped = p["url"].gsub("\"", "\\\\\"") + result << "{\"name\":\"#{name_escaped}\",\"url\":\"#{url_escaped}\"}" + end + result << "]" + puts result + rescue => e + puts "[]" + end + ' 2>/dev/null || echo '[]' + ]], config_path)):gsub("\n", "") + + if ruby_result and ruby_result ~= "" and ruby_result ~= "[]" then + local success, parsed_providers = pcall(function() + return json.parse(ruby_result) + end) + + if success and parsed_providers and #parsed_providers > 0 then + return {type = "multiple", providers = parsed_providers} + end + end + end + + -- Priority 3: config_subscribe table (last fallback) + uci:foreach("openclash", "config_subscribe", + function(s) + if s.name == filename and s.address and string.find(s.address, "http") then + string.gsub(s.address, '[^\n]+', function(w) table.insert(info_tb, w) end) + sub_url = info_tb[1] + end + end + ) + + if sub_url then + return {type = "single", url = sub_url} + end + + return nil +end + +function sub_info_get() + local sub_ua, filename, sub_info + local providers_data = {} + filename = luci.http.formvalue("filename") sub_info = "" sub_ua = "Clash" + uci:foreach("openclash", "config_subscribe", function(s) if s.name == filename and s.sub_ua then @@ -801,141 +945,49 @@ function sub_info_get() end end ) + if filename and not is_start() then - uci:foreach("openclash", "subscribe_info", - function(s) - if s.name == filename and s.url and string.find(s.url, "http") then - string.gsub(s.url, '[^\n]+', function(w) table.insert(info_tb, w) end) - sub_url = info_tb[1] - end - end - ) - if not sub_url then - uci:foreach("openclash", "config_subscribe", - function(s) - if s.name == filename and s.address and string.find(s.address, "http") then - string.gsub(s.address, '[^\n]+', function(w) table.insert(info_tb, w) end) - sub_url = info_tb[1] - end - end - ) - end - if not sub_url then + local url_result = get_sub_url(filename) + + if not url_result then sub_info = "No Sub Info Found" - else - info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code='%%{http_code} -H 'User-Agent: %s' '%s'", sub_ua, sub_url)) - if not info or tonumber(string.sub(string.match(info, "http_code=%d+"), 11, -1)) ~= 200 then - info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code='%%{http_code} -H 'User-Agent: Quantumultx' '%s'", sub_url)) - end + elseif url_result.type == "single" then + local info = fetch_sub_info(url_result.url, sub_ua) if info then - http_code=string.sub(string.match(info, "http_code=%d+"), 11, -1) - if tonumber(http_code) == 200 then - info = string.lower(info) - if string.find(info, "subscription%-userinfo") then - info = luci.sys.exec("echo '%s' |grep 'subscription-userinfo'" %info) - upload = string.sub(string.match(info, "upload=%d+"), 8, -1) or nil - download = string.sub(string.match(info, "download=%d+"), 10, -1) or nil - total = tonumber(string.format("%.1f",string.sub(string.match(info, "total=%d+"), 7, -1))) or nil - used = tonumber(string.format("%.1f",(upload + download))) or nil - if string.match(info, "expire=%d+") then - day_expire = tonumber(string.sub(string.match(info, "expire=%d+"), 8, -1)) or nil - end - - if day_expire and day_expire == 0 then - expire = luci.i18n.translate("Long-term") - elseif day_expire then - expire = os.date("%Y-%m-%d %H:%M:%S", day_expire) or "null" - else - expire = "null" - end - - if day_expire and day_expire ~= 0 and os.time() <= day_expire then - day_left = math.ceil((day_expire - os.time()) / (3600*24)) - if math.ceil(day_left / 365) > 50 then - day_left = "∞" - end - elseif day_expire and day_expire == 0 then - day_left = "∞" - elseif day_expire == nil then - day_left = "null" - else - day_left = 0 - end - - if used and total and used <= total and total > 0 then - percent = string.format("%.1f",((total-used)/total)*100) or "100" - surplus = fs.filesize(total - used) - elseif used and total and used > total and total > 0 then - percent = "0" - surplus = "-"..fs.filesize(total - used) - elseif used and total and used < total and total == 0.0 then - percent = "0" - surplus = fs.filesize(total - used) - elseif used and total and used == total and total == 0.0 then - percent = "0" - surplus = "0.0 KB" - elseif used and total and used > total and total == 0.0 then - percent = "100" - surplus = fs.filesize(total - used) - elseif used == nil and total and total > 0.0 then - percent = 100 - surplus = fs.filesize(total) - elseif used == nil and total and total == 0.0 then - percent = 100 - surplus = "∞" - else - percent = 0 - surplus = "null" - end - if total and total > 0 then - total = fs.filesize(total) - elseif total and total == 0.0 then - total = "∞" - else - total = "null" - end - used = fs.filesize(used) - sub_info = "Successful" - else - sub_info = "No Sub Info Found" - end + table.insert(providers_data, info) + sub_info = "Successful" + else + sub_info = "No Sub Info Found" + end + elseif url_result.type == "multiple" then + for i, provider in ipairs(url_result.providers) do + local info = fetch_sub_info(provider.url, sub_ua) + if info then + info.provider_name = provider.name + table.insert(providers_data, info) end end + + if #providers_data > 0 then + sub_info = "Successful" + else + sub_info = "No Sub Info Found" + end end end + luci.http.prepare_content("application/json") luci.http.write_json({ - http_code = http_code, sub_info = sub_info, - surplus = surplus, - used = used, - total = total, - percent = percent, - day_left = day_left, - expire = expire, - get_time = os.time(); + providers = providers_data, + get_time = os.time() }) end function action_rule_mode() - local mode, info - if is_running() then - local daip = daip() - local dase = dase() or "" - local cn_port = cn_port() - if not daip or not cn_port then return end - info = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/configs', dase, daip, cn_port))) - if info then - mode = info["mode"] - else - mode = fs.uci_get_config("config", "proxy_mode") or "rule" - end - else - mode = fs.uci_get_config("config", "proxy_mode") or "rule" - end luci.http.prepare_content("application/json") luci.http.write_json({ - mode = mode; + mode = fs.uci_get_config("config", "proxy_mode") or "rule"; }) end @@ -1025,7 +1077,7 @@ function action_switch_log() local dase = dase() or "" local cn_port = cn_port() level = luci.http.formvalue("log_level") - if not daip or not cn_port then luci.http.status(500, "Switch Faild") return end + if not daip or not cn_port or not level then luci.http.status(500, "Switch Faild") return end info = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPATCH http://"%s":"%s"/configs -d \'{\"log-level\": \"%s\"}\'', dase, daip, cn_port, level)) if info ~= "" then luci.http.status(500, "Switch Faild") @@ -1057,9 +1109,9 @@ function action_toolbar_show_sys() local cpu = "0" local load_avg = "0" local cpu_count = luci.sys.exec("grep -c ^processor /proc/cpuinfo 2>/dev/null"):gsub("\n", "") or 1 - + local pid = luci.sys.exec("pgrep -f '^[^ ]*clash' | head -1 | tr -d '\n' 2>/dev/null") - + if pid and pid ~= "" then cpu = luci.sys.exec(string.format([[ top -b -n1 | awk -v pid="%s" ' @@ -1078,12 +1130,12 @@ function action_toolbar_show_sys() end load_avg = luci.sys.exec("awk '{print $2; exit}' /proc/loadavg 2>/dev/null"):gsub("\n", "") or "0" - + if not string.match(load_avg, "^[0-9]*%.?[0-9]*$") then load_avg = "0" end end - + luci.http.prepare_content("application/json") luci.http.write_json({ cpu = cpu, @@ -1099,10 +1151,10 @@ function action_toolbar_show() local dase = dase() or "" local cn_port = cn_port() if not daip or not cn_port then return end - + traffic = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/traffic', dase, daip, cn_port))) connections = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/connections', dase, daip, cn_port))) - + if traffic and connections and connections.connections then connection = #(connections.connections) up = s(traffic.up) @@ -1116,7 +1168,7 @@ function action_toolbar_show() down_total = "0 KB" connection = "0" end - + mem = tonumber(luci.sys.exec(string.format("cat /proc/%s/status 2>/dev/null |grep -w VmRSS |awk '{print $2}'", pid))) cpu = luci.sys.exec(string.format([[ top -b -n1 | awk -v pid="%s" ' @@ -1128,7 +1180,7 @@ function action_toolbar_show() cpu_col>0 && $1==pid { print $cpu_col } ' ]], pid)) - + if mem and cpu then mem = fs.filesize(mem*1024) or "0 KB" cpu = string.match(cpu, "%d+%.?%d*") or "0" @@ -1146,7 +1198,7 @@ function action_toolbar_show() else return end - + luci.http.prepare_content("application/json") luci.http.write_json({ connections = connection, @@ -1280,13 +1332,15 @@ end function action_status() luci.http.prepare_content("application/json") luci.http.write_json({ - clash = is_running(), + clash = uci:get("openclash", "config", "enable") == "1", daip = daip(), dase = dase(), db_foward_port = db_foward_port(), db_foward_domain = db_foward_domain(), db_forward_ssl = db_foward_ssl(), cn_port = cn_port(), + yacd = fs.isdirectory("/usr/share/openclash/ui/yacd") , + dashboard = fs.isdirectory("/usr/share/openclash/ui/dashboard") , core_type = fs.uci_get_config("config", "core_type") or "Meta"; }) end @@ -1385,7 +1439,7 @@ function action_refresh_log() luci.http.prepare_content("application/json") local logfile = "/tmp/openclash.log" local log_len = tonumber(luci.http.formvalue("log_len")) or 0 - + if not fs.access(logfile) then luci.http.write_json({ len = 0, @@ -1395,9 +1449,9 @@ function action_refresh_log() }) return end - + local total_lines = tonumber(luci.sys.exec("wc -l < " .. logfile)) or 0 - + if total_lines == log_len and log_len > 0 then luci.http.write_json({ len = total_lines, @@ -1407,24 +1461,24 @@ function action_refresh_log() }) return end - + local exclude_pattern = "UDP%-Receive%-Buffer%-Size|^Sec%-Fetch%-Mode|^User%-Agent|^Access%-Control|^Accept|^Origin|^Referer|^Connection|^Pragma|^Cache%-" local core_pattern = " DBG | INF |level=| WRN | ERR | FTL " local limit = 1000 local start_line = (log_len > 0 and total_lines > log_len) and (log_len + 1) or 1 - + local core_cmd = string.format( "tail -n +%d '%s' | grep -v -E '%s' | grep -E '%s' | tail -n %d", start_line, logfile, exclude_pattern, core_pattern, limit ) local core_raw = luci.sys.exec(core_cmd) - + local oc_cmd = string.format( "tail -n +%d '%s' | grep -v -E '%s' | grep -v -E '%s' | tail -n %d", start_line, logfile, exclude_pattern, core_pattern, limit ) local oc_raw = luci.sys.exec(oc_cmd) - + local core_log = "" if core_raw and core_raw ~= "" then local core_logs = {} @@ -1439,7 +1493,7 @@ function action_refresh_log() core_log = table.concat(core_logs, "\n") end end - + local oc_log = "" if oc_raw and oc_raw ~= "" then local oc_logs = {} @@ -1456,7 +1510,7 @@ function action_refresh_log() oc_log = table.concat(oc_logs, "\n") end end - + luci.http.write_json({ len = total_lines, update = true, @@ -1828,7 +1882,7 @@ function trans_line_nolabel(data) if data == nil or data == "" then return "" end - + local line_trans = "" if string.len(data) >= 19 and string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then line_trans = string.sub(data, 0, 20)..luci.i18n.translate(string.sub(data, 21, -1)) @@ -1842,11 +1896,11 @@ function trans_line(data) if data == nil or data == "" then return "" end - + local no_trans = {} local line_trans = "" local a = string.find(data, "【") - + if not a then if string.len(data) >= 19 and string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then return string.sub(data, 0, 20) .. luci.i18n.translate(string.sub(data, 21, -1)) @@ -1854,25 +1908,25 @@ function trans_line(data) return luci.i18n.translate(data) end end - + local b_pos = string.find(data, "】") if not b_pos then return luci.i18n.translate(data) end - + local b = b_pos + 2 local c = 21 local d = 0 local v local x - + while true do table.insert(no_trans, a) table.insert(no_trans, b) - + local next_a = string.find(data, "【", b+1) local next_b = string.find(data, "】", b+1) - + if next_a and next_b then a = next_a b = next_b + 2 @@ -1880,15 +1934,15 @@ function trans_line(data) break end end - + if #no_trans % 2 ~= 0 then table.remove(no_trans) end - + for k = 1, #no_trans, 2 do x = no_trans[k] v = no_trans[k+1] - + if x and v then if x <= 21 or not string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then line_trans = line_trans .. luci.i18n.translate(string.sub(data, d, x - 1)) .. string.sub(data, x, v) @@ -1899,7 +1953,7 @@ function trans_line(data) c = v + 1 end end - + if c > string.len(data) then if d == 0 then if string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then @@ -1915,7 +1969,7 @@ function trans_line(data) line_trans = line_trans .. luci.i18n.translate(string.sub(data, c, -1)) end end - + return line_trans end @@ -1948,7 +2002,7 @@ end function action_myip_check() local result = {} local random = math.random(100000000) - + local services = { { name = "upaiyun", @@ -1972,7 +2026,7 @@ function action_myip_check() table.insert(geo_parts, upaiyun_json.remote_addr_location.isp) end end - + return { ip = upaiyun_json.remote_addr, geo = table.concat(geo_parts, " ") @@ -1989,11 +2043,11 @@ function action_myip_check() if data and data ~= "" then local ip = string.match(data, "当前 IP:([%d%.]+)") local geo = string.match(data, "来自于:(.+)") - + if ip and geo then geo = string.gsub(geo, "%s+", " ") geo = string.gsub(geo, "^%s*(.-)%s*$", "%1") - + return { ip = ip, geo = geo @@ -2017,7 +2071,7 @@ function action_myip_check() if ipsb_json.isp and ipsb_json.isp ~= "" then table.insert(geo_parts, ipsb_json.isp) end - + return { ip = ipsb_json.ip, geo = table.concat(geo_parts, " ") @@ -2044,15 +2098,15 @@ function action_myip_check() end } } - + local function create_concurrent_query(service) local fdi, fdo = nixio.pipe() if not fdi or not fdo then return nil end - + local pid = nixio.fork() - + if pid > 0 then fdo:close() return { @@ -2079,7 +2133,7 @@ function action_myip_check() nixio.dup(fdo, nixio.stdout) fdi:close() fdo:close() - + local cmd = string.format( 'curl -SsL -m 5 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "%s" 2>/dev/null', service.url @@ -2091,9 +2145,9 @@ function action_myip_check() return nil end end - + local queries = {} - + for _, service in ipairs(services) do local query = create_concurrent_query(service) if query then @@ -2104,7 +2158,7 @@ function action_myip_check() } end end - + if next(queries) == nil then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -2112,62 +2166,62 @@ function action_myip_check() }) return end - + local max_iterations = 140 local iteration = 0 local completed = {} - + while iteration < max_iterations do iteration = iteration + 1 - + for name, info in pairs(queries) do if not completed[name] then local wpid, stat = nixio.waitpid(info.query.pid, "nohang") local buffer = info.query.reader() - + if buffer then info.data = info.data .. buffer end - + if wpid then pcall(info.query.close) completed[name] = true - + local parsed_result = info.parser(info.data) if parsed_result then result[name] = parsed_result end - + queries[name] = nil else local still_running = luci.sys.call(string.format("kill -0 %d 2>/dev/null", info.query.pid)) == 0 if not still_running then pcall(info.query.close) completed[name] = true - + local parsed_result = info.parser(info.data) if parsed_result then result[name] = parsed_result end - + queries[name] = nil end end end end - + local remaining_count = 0 for _ in pairs(queries) do remaining_count = remaining_count + 1 end - + if remaining_count == 0 then break end - + nixio.nanosleep(0, 50000000) end - + for name, info in pairs(queries) do if not completed[name] then result[name] = { ip = "", geo = "", error = "timeout" } @@ -2176,14 +2230,14 @@ function action_myip_check() pcall(info.query.close) end end - + if result.ipify and result.ipify.ip then local geo_cmd = string.format( 'curl -sL -m 5 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "https://api-ipv4.ip.sb/geoip/%s" 2>/dev/null', result.ipify.ip ) local geo_data = luci.sys.exec(geo_cmd) - + if geo_data and geo_data ~= "" then local ok_geo, geo_json = pcall(json.parse, geo_data) if ok_geo and geo_json and geo_json.ip then @@ -2198,7 +2252,7 @@ function action_myip_check() end end end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2210,7 +2264,7 @@ function action_website_check() response_time = 0, error = "" } - + if not domain then result.error = "Missing domain parameter" luci.http.prepare_content("application/json") @@ -2235,12 +2289,12 @@ function action_website_check() 'curl -sL -m 5 --connect-timeout 3 -w "%%{http_code},%%{time_total},%%{time_connect},%%{time_appconnect}" "%s" -o /dev/null 2>/dev/null', test_url ) - + local output = luci.sys.exec(cmd) - + if output and output ~= "" then local http_code, time_total, time_connect, time_appconnect = output:match("(%d+),([%d%.]+),([%d%.]+),([%d%.]+)") - + if http_code and tonumber(http_code) then local code = tonumber(http_code) local response_time = 0 @@ -2251,7 +2305,7 @@ function action_website_check() else response_time = math.floor((tonumber(time_total) or 0) * 1000) end - + if code >= 200 and code < 400 then result.success = true result.response_time = response_time @@ -2270,7 +2324,7 @@ function action_website_check() fallback_url ) local fallback_output = luci.sys.exec(fallback_cmd) - + if fallback_output and fallback_output ~= "" then local fb_code, fb_total, fb_appconnect = fallback_output:match("(%d+),([%d%.]+),([%d%.]+)") if fb_code and tonumber(fb_code) then @@ -2281,7 +2335,7 @@ function action_website_check() else fb_response_time = math.floor((tonumber(fb_total) or 0) * 1000) end - + if fb_code_num >= 200 and fb_code_num < 400 then result.success = true result.response_time = fb_response_time @@ -2310,7 +2364,7 @@ function action_website_check() result.success = false result.error = "No response" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2321,103 +2375,27 @@ function action_proxy_info() auth_user = "", auth_pass = "" } - - local function get_info_from_uci() - local mixed_port = fs.uci_get_config("config", "mixed_port") - if mixed_port and mixed_port ~= "" then - result.mixed_port = mixed_port - else - result.mixed_port = "7893" - end - - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and result.auth_user == "" then - if section.username and section.username ~= "" then - result.auth_user = section.username - end - if section.password and section.password ~= "" then - result.auth_pass = section.password - end - return false - end - end) + + + local mixed_port = fs.uci_get_config("config", "mixed_port") + if mixed_port and mixed_port ~= "" then + result.mixed_port = mixed_port + else + result.mixed_port = "7893" end - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - mixed_port = '' - auth_user = '' - auth_pass = '' - - if config - if config['mixed-port'] - mixed_port = config['mixed-port'].to_s - end - - if config['authentication'] && config['authentication'].is_a?(Array) && !config['authentication'].empty? - auth_entry = config['authentication'][0] - if auth_entry.is_a?(String) && auth_entry.include?(':') - username, password = auth_entry.split(':', 2) - auth_user = username || '' - auth_pass = password || '' - end - end - end - - puts \"#{mixed_port},#{auth_user},#{auth_pass}\" - rescue - puts ',,' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local runtime_mixed_port, runtime_auth_user, runtime_auth_pass = ruby_result:match("([^,]*),([^,]*),([^,]*)") - - if runtime_mixed_port and runtime_mixed_port ~= "" then - result.mixed_port = runtime_mixed_port - else - local uci_mixed_port = fs.uci_get_config("config", "mixed_port") - if uci_mixed_port and uci_mixed_port ~= "" then - result.mixed_port = uci_mixed_port - else - result.mixed_port = "7893" - end - end - - if runtime_auth_user and runtime_auth_user ~= "" and runtime_auth_pass and runtime_auth_pass ~= "" then - result.auth_user = runtime_auth_user - result.auth_pass = runtime_auth_pass - else - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and result.auth_user == "" then - if section.username and section.username ~= "" then - result.auth_user = section.username - end - if section.password and section.password ~= "" then - result.auth_pass = section.password - end - return false - end - end) - end - luci.http.prepare_content("application/json") - luci.http.write_json(result) - return + uci:foreach("openclash", "authentication", function(section) + if section.enabled == "1" and result.auth_user == "" then + if section.username and section.username ~= "" then + result.auth_user = section.username end + if section.password and section.password ~= "" then + result.auth_pass = section.password + end + return false end - end + end) - get_info_from_uci() - luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2430,61 +2408,14 @@ function action_oc_settings() stream_unlock = "0" } - local function get_uci_settings() - local meta_sniffer = fs.uci_get_config("config", "enable_meta_sniffer") - if meta_sniffer == "1" then - result.meta_sniffer = "1" - end - - local respect_rules = fs.uci_get_config("config", "enable_respect_rules") - if respect_rules == "1" then - result.respect_rules = "1" - end + local meta_sniffer = fs.uci_get_config("config", "enable_meta_sniffer") + if meta_sniffer == "1" then + result.meta_sniffer = "1" end - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - sniffer_enabled = config['sniffer'] && config['sniffer']['enable'] == true ? '1' : '0' - respect_rules_enabled = config['dns'] && config['dns']['respect-rules'] == true ? '1' : '0' - puts \"#{sniffer_enabled},#{respect_rules_enabled}\" - else - puts '0,0' - end - rescue - puts '0,0' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local sniffer_result, respect_rules_result = ruby_result:match("(%d),(%d)") - if sniffer_result and respect_rules_result then - result.meta_sniffer = sniffer_result - result.respect_rules = respect_rules_result - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() + local respect_rules = fs.uci_get_config("config", "enable_respect_rules") + if respect_rules == "1" then + result.respect_rules = "1" end local oversea = fs.uci_get_config("config", "china_ip_route") @@ -2500,7 +2431,7 @@ function action_oc_settings() if stream_unlock == "1" then result.stream_unlock = "1" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2508,12 +2439,12 @@ end function action_switch_oc_setting() local setting = luci.http.formvalue("setting") local value = luci.http.formvalue("value") - + if not setting or not value then luci.http.status(400, "Missing parameters") return end - + local function get_runtime_config_path() local config_path = fs.uci_get_config("config", "config_path") if not config_path then @@ -2522,20 +2453,20 @@ function action_switch_oc_setting() local config_filename = fs.basename(config_path) return "/etc/openclash/" .. config_filename end - + local function update_runtime_config(ruby_cmd) local runtime_config_path = get_runtime_config_path() if not runtime_config_path then luci.http.status(500, "No config path found") return false end - + local ruby_result = luci.sys.call(ruby_cmd) if ruby_result ~= 0 then luci.http.status(500, "Failed to modify config file") return false end - + local daip = daip() local dase = dase() or "" local cn_port = cn_port() @@ -2543,43 +2474,43 @@ function action_switch_oc_setting() luci.http.status(500, "Switch Failed") return false end - + local reload_result = luci.sys.exec(string.format('curl -sL -m 5 --connect-timeout 2 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPUT http://"%s":"%s"/configs?force=true -d \'{"path":"%s"}\' 2>&1', dase, daip, cn_port, runtime_config_path)) - + if reload_result ~= "" then luci.http.status(500, "Switch Failed") return false end - + return true end - + if setting == "meta_sniffer" then if is_running() then local runtime_config_path = get_runtime_config_path() local ruby_cmd - + if value == "1" then ruby_cmd = string.format([[ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' - + config = File.exist?(config_path) ? YAML.load_file(config_path) : {} config ||= {} - + if config['sniffer']&.dig('enable') == true && config['sniffer']&.dig('parse-pure-ip') == true && config['sniffer']&.dig('sniff') exit 0 end - + config['sniffer'] = { 'enable' => true, 'parse-pure-ip' => true, 'override-destination' => false } - + custom_sniffer_path = '/etc/openclash/custom/openclash_custom_sniffer.yaml' if File.exist?(custom_sniffer_path) begin @@ -2590,7 +2521,7 @@ function action_switch_oc_setting() rescue end end - + unless config['sniffer']['sniff'] config['sniffer']['sniff'] = { 'QUIC' => { 'ports' => [443] }, @@ -2598,19 +2529,19 @@ function action_switch_oc_setting() 'HTTP' => { 'ports' => [80, '8080-8880'], 'override-destination' => true } } end - + unless config['sniffer']['force-domain'] config['sniffer']['force-domain'] = ['+.netflix.com', '+.nflxvideo.net', '+.amazonaws.com'] end - + unless config['sniffer']['skip-domain'] config['sniffer']['skip-domain'] = ['+.apple.com', 'Mijia Cloud', 'dlg.io.mi.com'] end - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 @@ -2622,7 +2553,7 @@ function action_switch_oc_setting() ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' - + if File.exist?(config_path) config = YAML.load_file(config_path) if config&.dig('sniffer', 'enable') == false @@ -2631,14 +2562,14 @@ function action_switch_oc_setting() else config = {} end - + config ||= {} config['sniffer'] = { 'enable' => false } - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 @@ -2646,7 +2577,7 @@ function action_switch_oc_setting() " 2>/dev/null ]], runtime_config_path) end - + if not update_runtime_config(ruby_cmd) then return end @@ -2660,13 +2591,13 @@ function action_switch_oc_setting() if is_running() then local runtime_config_path = get_runtime_config_path() local target_value = (value == "1") and "true" or "false" - + local ruby_cmd = string.format([[ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' target_value = %s - + if File.exist?(config_path) config = YAML.load_file(config_path) if config&.dig('dns', 'respect-rules') == target_value @@ -2678,28 +2609,28 @@ function action_switch_oc_setting() else config = {} end - + config ||= {} config['dns'] ||= {} config['dns']['respect-rules'] = target_value - + if target_value == true if !config['dns']['proxy-server-nameserver'] || config['dns']['proxy-server-nameserver'].empty? config['dns']['proxy-server-nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1'] end end - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 end " 2>/dev/null ]], runtime_config_path, target_value) - + if not update_runtime_config(ruby_cmd) then return end @@ -2746,7 +2677,7 @@ function action_switch_oc_setting() luci.http.status(400, "Invalid setting") return end - + luci.http.prepare_content("application/json") luci.http.write_json({ status = "success", @@ -2760,81 +2691,35 @@ function action_generate_pac() pac_url = "", error = "" } - + local auth_user = "" local auth_pass = "" - local auth_exists = false - - local function get_auth_from_uci() - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and section.username and section.username ~= "" - and section.password and section.password ~= "" then - auth_user = section.username - auth_pass = section.password - auth_exists = true - return false - end - end) - end - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config && config['authentication'] && config['authentication'].is_a?(Array) && !config['authentication'].empty? - auth_entry = config['authentication'][0] - if auth_entry.is_a?(String) && auth_entry.include?(':') - username, password = auth_entry.split(':', 2) - puts \"#{username},#{password}\" - else - puts ',' - end - else - puts ',' - end - rescue - puts ',' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local runtime_user, runtime_pass = ruby_result:match("([^,]*),([^,]*)") - if runtime_user and runtime_user ~= "" and runtime_pass and runtime_pass ~= "" then - auth_user = runtime_user - auth_pass = runtime_pass - auth_exists = true - end - end + uci:foreach("openclash", "authentication", function(section) + if section.enabled == "1" and section.username and section.username ~= "" + and section.password and section.password ~= "" then + auth_user = section.username + auth_pass = section.password + return false end - end + end) - if not auth_exists then - get_auth_from_uci() - end - local proxy_ip = daip() local mixed_port = fs.uci_get_config("config", "mixed_port") or "7893" - + if not proxy_ip then result.error = "Unable to get proxy IP" luci.http.prepare_content("application/json") luci.http.write_json(result) return end - + local function generate_random_string() local random_cmd = "tr -cd 'a-zA-Z0-9' /dev/null| head -c16 || date +%N| md5sum |head -c16" local random_string = luci.sys.exec(random_cmd):gsub("\n", "") return random_string end - + local function count_pac_lines(content) if not content or content == "" then return 0 @@ -2848,11 +2733,11 @@ function action_generate_pac() end return lines end - + local new_proxy_string = string.format("PROXY %s:%s; DIRECT", proxy_ip, mixed_port) local new_pac_content = generate_pac_content(proxy_ip, mixed_port, auth_user, auth_pass) local new_pac_lines = count_pac_lines(new_pac_content) - + local pac_dir = "/www/luci-static/resources/openclash/pac/" local pac_filename = nil local pac_file_path = nil @@ -2872,7 +2757,7 @@ function action_generate_pac() if not existing_proxy then existing_proxy = string.match(file_content, 'return%s*"(PROXY%s+[^"]*)"') end - + if existing_proxy and existing_proxy == new_proxy_string then local existing_lines = count_pac_lines(file_content) if existing_lines == new_pac_lines then @@ -2887,7 +2772,7 @@ function action_generate_pac() file:write(new_pac_content) file:close() luci.sys.call("chmod 644 " .. file_path) - + pac_filename = file_path:match("([^/]+)$") pac_file_path = file_path random_suffix = pac_filename:match("^pac_(.+)$") @@ -2899,23 +2784,23 @@ function action_generate_pac() local updated_content = string.gsub(file_content, 'return%s*"PROXY%s+[^"]*"', 'return "' .. new_proxy_string .. '"') - + if updated_content ~= file_content then local updated_lines = count_pac_lines(updated_content) local final_content - + if updated_lines == new_pac_lines then final_content = updated_content else final_content = new_pac_content end - + local file = io.open(file_path, "w") if file then file:write(final_content) file:close() luci.sys.call("chmod 644 " .. file_path) - + pac_filename = file_path:match("([^/]+)$") pac_file_path = file_path random_suffix = pac_filename:match("^pac_(.+)$") @@ -2928,19 +2813,19 @@ function action_generate_pac() end end end - + if need_update then luci.sys.call("rm -f " .. pac_dir .. "pac_* 2>/dev/null") - + random_suffix = generate_random_string() pac_filename = "pac_" .. random_suffix pac_file_path = pac_dir .. pac_filename - + local file = io.open(pac_file_path, "w") if file then file:write(new_pac_content) file:close() - + luci.sys.call("chmod 644 " .. pac_file_path) else result.error = "Failed to write PAC file" @@ -2951,14 +2836,14 @@ function action_generate_pac() else luci.sys.call(string.format("find %s -name 'pac_*' -type f ! -name '%s' -delete 2>/dev/null", pac_dir, pac_filename)) end - + local pac_url = generate_pac_url_with_client_info(pac_filename, random_suffix) result.pac_url = pac_url - + if not auth_exists then result.error = "warning: No authentication configured, please be aware of the risk of information leakage!" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2968,10 +2853,10 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) local client_hostname = luci.http.formvalue("client_hostname") local client_host = luci.http.formvalue("client_host") local client_port = luci.http.formvalue("client_port") - + local request_scheme = "http" local host = "localhost" - + if client_protocol and (client_protocol == "http" or client_protocol == "https") then request_scheme = client_protocol else @@ -2981,7 +2866,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) request_scheme = "https" end end - + if client_host and client_host ~= "" then host = client_host elseif client_hostname and client_hostname ~= "" then @@ -2997,7 +2882,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) local http_host = luci.http.getenv("HTTP_HOST") local server_port = luci.http.getenv("SERVER_PORT") local proxy_ip = daip() - + if http_host and http_host ~= "" then host = http_host elseif server_name and server_name ~= "" then @@ -3018,7 +2903,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) end end end - + local random_param = "" if random_suffix and #random_suffix >= 8 then math.randomseed(os.time()) @@ -3029,15 +2914,15 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) else random_param = random_suffix or tostring(os.time()) end - + local pac_url = request_scheme .. "://" .. host .. "/luci-static/resources/openclash/pac/" .. pac_filename .. "?v=" .. random_param - + return pac_url end function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) local proxy_string = string.format("PROXY %s:%s; DIRECT", proxy_ip, proxy_port) - + local ipv4_networks = {} local ipv4_file = "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" if fs.access(ipv4_file) then @@ -3076,7 +2961,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) end end end - + local ipv6_networks = {} local ipv6_file = "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" if fs.access(ipv6_file) then @@ -3098,7 +2983,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) end end end - + local ipv4_checks = {} for _, net in ipairs(ipv4_networks) do table.insert(ipv4_checks, string.format('isInNet(resolved_ip, "%s", "%s")', net.network, net.mask)) @@ -3107,7 +2992,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) if #ipv4_checks > 0 then ipv4_check_code = "if (" .. table.concat(ipv4_checks, " ||\n ") .. ") {\n return \"DIRECT\";\n }" end - + local ipv6_checks = {} for _, net in ipairs(ipv6_networks) do if net.prefix_len == 128 then @@ -3121,7 +3006,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) if #ipv6_checks > 0 then ipv6_check_code = "if (" .. table.concat(ipv6_checks, " ||\n ") .. ") {\n return \"DIRECT\";\n }" end - + local pac_script = string.format([[ // OpenClash PAC File var _failureCount = 0; @@ -3132,17 +3017,17 @@ var _checkInterval = 300000; // 5分钟 = 300000毫秒 // Access Check function _checkNetworkConnectivity() { var currentTime = Date.now(); - + if (currentTime - _lastCheckTime < _checkInterval) { return !_isProxyDown; } - + _lastCheckTime = currentTime; - + try { var test1 = dnsResolve("www.gstatic.com"); var test2 = dnsResolve("captive.apple.com"); - + if (test1 || test2) { if (_isProxyDown) { _isProxyDown = false; @@ -3172,19 +3057,19 @@ function FindProxyForURL(url, host) { host === "localhost") { return "DIRECT"; } - + // IPv4 var resolved_ip = dnsResolve(host); if (resolved_ip) { %s } - + // IPv6 var resolved_ipv6 = dnsResolveEx(host); if (resolved_ipv6) { %s } - + if (_checkNetworkConnectivity()) { return "%s"; } else { @@ -3196,7 +3081,7 @@ function FindProxyForURLEx(url, host) { return FindProxyForURL(url, host); } ]], ipv4_check_code, ipv6_check_code, proxy_string) - + return pac_script end @@ -3219,26 +3104,36 @@ function action_oc_action() luci.http.status(404, "Config file not found") return end - - uci:set("openclash", "config", "config_path", config_path) + + if uci:get("openclash", "config", "config_path") ~= config_path then + uci:set("openclash", "config", "config_path", config_path) + end end - + if action == "start" then - uci:set("openclash", "config", "enable", "1") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "1" then + uci:set("openclash", "config", "enable", "1") + uci:commit("openclash") + end if not is_running() then + luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash start >/dev/null 2>&1") else luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1") end elseif action == "stop" then - uci:set("openclash", "config", "enable", "0") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "0" then + uci:set("openclash", "config", "enable", "0") + uci:commit("openclash") + end luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash stop >/dev/null 2>&1") elseif action == "restart" then - uci:set("openclash", "config", "enable", "1") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "1" then + uci:set("openclash", "config", "enable", "1") + uci:commit("openclash") + end + luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1") else luci.http.status(400, "Invalid action parameter") @@ -3252,12 +3147,12 @@ end function action_config_file_list() local config_files = {} local current_config = "" - + local config_path = fs.uci_get_config("config", "config_path") if config_path then current_config = config_path end - + local config_dir = "/etc/openclash/config/" if fs.access(config_dir) then local files = fs.dir(config_dir) @@ -3277,12 +3172,12 @@ function action_config_file_list() end end end - + table.sort(config_files, function(a, b) return a.mtime > b.mtime end) end - + luci.http.prepare_content("application/json") luci.http.write_json({ config_files = config_files, @@ -3294,9 +3189,9 @@ end function action_upload_config() local upload = luci.http.formvalue("config_file") local filename = luci.http.formvalue("filename") - + luci.http.prepare_content("application/json") - + if not upload or upload == "" then luci.http.write_json({ status = "error", @@ -3304,7 +3199,7 @@ function action_upload_config() }) return end - + if not filename or filename == "" then filename = "upload_" .. os.date("%Y%m%d_%H%M%S") end @@ -3320,10 +3215,10 @@ function action_upload_config() if not string.match(filename, "%.ya?ml$") then filename = filename .. ".yaml" end - + local config_dir = "/etc/openclash/config/" local target_path = config_dir .. filename - + if string.len(upload) == 0 then luci.http.write_json({ status = "error", @@ -3331,7 +3226,7 @@ function action_upload_config() }) return end - + local file_size = string.len(upload) if file_size > 10 * 1024 * 1024 then luci.http.write_json({ @@ -3340,10 +3235,10 @@ function action_upload_config() }) return end - + local yaml_valid = false - local content_start = string.sub(upload, 1, 1000) - + local content_start = string.sub(upload, 1, 5000) + if string.find(content_start, "proxy%-providers:") or string.find(content_start, "proxies:") or string.find(content_start, "rules:") or @@ -3351,7 +3246,7 @@ function action_upload_config() string.find(content_start, "mode:") then yaml_valid = true end - + if not yaml_valid then luci.http.write_json({ status = "error", @@ -3359,17 +3254,17 @@ function action_upload_config() }) return end - + luci.sys.call("mkdir -p " .. config_dir) - + local fp = io.open(target_path, "w") if fp then fp:write(upload) fp:close() - + luci.sys.call(string.format("chmod 644 '%s'", target_path)) luci.sys.call(string.format("chown root:root '%s'", target_path)) - + local written_content = fs.readfile(target_path) if not written_content or string.len(written_content) ~= file_size then fs.unlink(target_path) @@ -3379,7 +3274,7 @@ function action_upload_config() }) return end - + luci.http.write_json({ status = "success", message = "Config file uploaded successfully", @@ -3407,11 +3302,11 @@ function action_config_file_read() local allow = false if config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" then allow = true - elseif config_file:match("^/etc/openclash/overwrite/[^/]+$") then + elseif config_file:match("^/etc/openclash/overwrite/[^/]+$") and not string.find(config_file, "%.%.") then allow = true elseif config_file:match("^/etc/openclash/[^/]+%.ya?ml$") then allow = true - elseif config_file:match("^/etc/openclash/config/[^/]+%.ya?ml$") then + elseif config_file:match("^/etc/openclash/config/[^/]+%.ya?ml$") and not string.find(config_file, "%.%.") then allow = true end @@ -3503,8 +3398,7 @@ function action_config_file_save() local is_overwrite = (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or config_file:match("^/etc/openclash/overwrite/[^/]+$")) if not is_overwrite then - if not string.match(config_file, "^/etc/openclash/config/[^/%.]+%.ya?ml$") then - luci.http.prepare_content("application/json") + if not string.match(config_file, "^/etc/openclash/config/[^/]+%.ya?ml$") or string.find(config_file, "%.%.") then luci.http.write_json({ status = "error", message = "Invalid config file path" @@ -3512,7 +3406,7 @@ function action_config_file_save() return end else - if not (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or config_file:match("^/etc/openclash/overwrite/[^/]+$")) then + if not (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or (config_file:match("^/etc/openclash/overwrite/[^/]+$") and not string.find(config_file, "%.%."))) then luci.http.prepare_content("application/json") luci.http.write_json({ status = "error", @@ -3627,9 +3521,9 @@ function action_add_subscription() local keyword = luci.http.formvalue("keyword") or "" local ex_keyword = luci.http.formvalue("ex_keyword") or "" local de_ex_keyword = luci.http.formvalue("de_ex_keyword") or "" - + luci.http.prepare_content("application/json") - + if not name or not address then luci.http.write_json({ status = "error", @@ -3637,9 +3531,9 @@ function action_add_subscription() }) return end - + local is_valid_url = false - + if sub_convert == "1" then if string.find(address, "^https?://") and not string.find(address, "\n") and not string.find(address, "|") then is_valid_url = true @@ -3654,7 +3548,7 @@ function action_add_subscription() table.insert(links, link:match("^%s*(.-)%s*$")) end end - + for _, link in ipairs(links) do if link and link ~= "" then if string.find(link, "^https?://") or string.find(link, "^[a-zA-Z]+://") then @@ -3674,7 +3568,7 @@ function action_add_subscription() is_valid_url = true end end - + if not is_valid_url then local error_msg if sub_convert == "1" then @@ -3682,14 +3576,14 @@ function action_add_subscription() else error_msg = "Invalid subscription URL format. Only single HTTP/HTTPS subscription URL is supported when subscription conversion is disabled" end - + luci.http.write_json({ status = "error", message = error_msg }) return end - + local exists = false uci:foreach("openclash", "config_subscribe", function(s) if s.name == name then @@ -3697,7 +3591,7 @@ function action_add_subscription() return false end end) - + if exists then luci.http.write_json({ status = "error", @@ -3705,7 +3599,7 @@ function action_add_subscription() }) return end - + local normalized_address = address if sub_convert == "1" and (string.find(address, "\n") or string.find(address, "|")) then local links = {} @@ -3728,7 +3622,7 @@ function action_add_subscription() else normalized_address = address:match("^%s*(.-)%s*$") end - + local section_id = uci:add("openclash", "config_subscribe") if section_id then uci:set("openclash", section_id, "name", name) @@ -3743,7 +3637,7 @@ function action_add_subscription() uci:set("openclash", section_id, "sort", sort) uci:set("openclash", section_id, "node_type", node_type) uci:set("openclash", section_id, "rule_provider", rule_provider) - + if custom_params and custom_params ~= "" then local params = {} for line in custom_params:gmatch("[^\n]+") do @@ -3758,7 +3652,7 @@ function action_add_subscription() end end end - + if keyword and keyword ~= "" then local keywords = {} for line in keyword:gmatch("[^\n]+") do @@ -3773,7 +3667,7 @@ function action_add_subscription() end end end - + if ex_keyword and ex_keyword ~= "" then local ex_keywords = {} for line in ex_keyword:gmatch("[^\n]+") do @@ -3788,7 +3682,7 @@ function action_add_subscription() end end end - + if de_ex_keyword and de_ex_keyword ~= "" then local de_ex_keywords = {} for line in de_ex_keyword:gmatch("[^\n]+") do @@ -3803,9 +3697,9 @@ function action_add_subscription() end end end - + uci:commit("openclash") - + luci.http.write_json({ status = "success", message = "Subscription added successfully", diff --git a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua index 75f05e7cb3..84a254d261 100644 --- a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua +++ b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua @@ -227,6 +227,7 @@ o.description = translate("Fake-IP is not returned if the matching succeeds when o.default = "blacklist" o:value("blacklist", translate("Blacklist Mode")) o:value("whitelist", translate("Whitelist Mode")) +o:value("rule", translate("Rule Mode")) o:depends("custom_fakeip_filter", "1") custom_fake_black = s:taboption("dns", Value, "custom_fake_filter") @@ -376,13 +377,6 @@ o = s:taboption("smart", Flag, "auto_smart_switch", font_red..bold_on..translate o.description = font_red..bold_on..translate("Auto Switch Url-test and Load-balance Group to Smart Group")..bold_off..font_off o.default = 0 -o = s:taboption("smart", ListValue, "smart_strategy", translate("Node Select Strategy")) -o:value("0", translate("Disable")) -o:value("sticky-sessions", translate("Sticky-sessions")) -o:value("round-robin", translate("Round-robin")) -o.default = "0" -o.description = translate("Before Node Data Collect Completely, The Default is Sticky-sessions") - o = s:taboption("smart", Value, "smart_policy_priority", translate("Policy Priority")) o.default = "" o.placeholder = "Premium:0.9;SG:1.3" diff --git a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua index e5f2b55e3d..5093ef2fbd 100644 --- a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua +++ b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua @@ -138,7 +138,7 @@ function(s) o:value(s.name) end end) - + o:value("DIRECT") o:value("GLOBAL") o:value("Disable", translate("Disable")) diff --git a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua index 73bb627156..e1d0fc6a7f 100644 --- a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua +++ b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua @@ -57,7 +57,6 @@ o:value("smart", translate("Smart-Select")) o:value("url-test", translate("URL-Test")) o:value("fallback", translate("Fallback")) o:value("load-balance", translate("Load-Balance")) -o:value("relay", translate("Relay-Traffic")) o = s:option(Value, "name", translate("Group Name")) o.rmempty = false @@ -95,13 +94,6 @@ o:value("consistent-hashing", translate("Consistent-hashing")) o:value("sticky-sessions", translate("Sticky-sessions")) o:depends("type", "load-balance") -o = s:option(ListValue, "strategy_smart", translate("Strategy Type")) -o.rmempty = true -o.description = translate("Choose The Smart's Strategy Type") -o:value("round-robin", translate("Round-robin")) -o:value("sticky-sessions", translate("Sticky-sessions")) -o:depends("type", "smart") - o = s:option(ListValue, "uselightgbm", translate("Uselightgbm")) o.description = translate("Use LightGBM Model For Smart Group Weight Prediction") o:value("false", translate("Disable")) diff --git a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua index 0d64e1bf93..6698bddd65 100644 --- a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua +++ b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua @@ -148,6 +148,7 @@ o:value("tuic", translate("Tuic")) o:value("snell", translate("Snell")) o:value("mieru", translate("Mieru")) o:value("anytls", translate("AnyTLS")) +o:value("sudoku", translate("Sudoku")) o:value("socks5", translate("Socks5")) o:value("http", translate("HTTP(S)")) o:value("direct", translate("DIRECT")) @@ -174,6 +175,7 @@ o:depends("type", "wireguard") o:depends("type", "tuic") o:depends("type", "mieru") o:depends("type", "anytls") +o:depends("type", "sudoku") o:depends("type", "snell") o:depends("type", "socks5") o:depends("type", "http") @@ -194,6 +196,7 @@ o:depends("type", "wireguard") o:depends("type", "tuic") o:depends("type", "mieru") o:depends("type", "anytls") +o:depends("type", "sudoku") o:depends("type", "snell") o:depends("type", "socks5") o:depends("type", "http") @@ -223,6 +226,46 @@ o:depends("type", "hysteria2") o:depends("type", "mieru") o:depends("type", "anytls") +-- [[ Sudoku ]]-- +o = s:option(Value, "sudoku_key", translate("Key")) +o.rmempty = true +o.placeholder = translate("") +o:depends("type", "sudoku") + +o = s:option(ListValue, "aead_method", translate("Aead-method")) +o.rmempty = true +o.default = "chacha20-poly1305" +o:value("chacha20-poly1305") +o:value("aes-128-gcm") +o:value("none") +o:depends("type", "sudoku") + +o = s:option(Value, "padding_min", translate("Padding-min")) +o.rmempty = true +o.datatype = "uinteger" +o.placeholder = translate("2") +o:depends("type", "sudoku") + +o = s:option(Value, "padding_max", translate("Padding-max")) +o.rmempty = true +o.datatype = "uinteger" +o.placeholder = translate("7") +o:depends("type", "sudoku") + +o = s:option(ListValue, "table_type", translate("Table-type")) +o.rmempty = true +o.default = "prefer_ascii" +o:value("prefer_ascii") +o:value("prefer_entropy") +o:depends("type", "sudoku") + +o = s:option(ListValue, "http_mask", translate("Http-mask")) +o.rmempty = true +o.default = "true" +o:value("true") +o:value("false") +o:depends("type", "sudoku") + -- [[ Mieru ]]-- o = s:option(Value, "port_range", translate("Port Range")) o.datatype = "portrange" @@ -1118,16 +1161,26 @@ function o.validate(self, value) return value end +o = s:option(Value, "dialer_proxy", translate("Dialer-proxy")) +o.rmempty = true +o.description = font_red..bold_on..translate("The added Dialer Proxy or Group Must Exist")..bold_off..font_off +m.uci:foreach("openclash", "groups", +function(s) + if s.name ~= "" and s.name ~= nil then + o:value(s.name) + end +end) + o = s:option(DynamicList, "groups", translate("Proxy Group (Support Regex)")) o.description = font_red..bold_on..translate("No Need Set when Config Create, The added Proxy Groups Must Exist")..bold_off..font_off o.rmempty = true o:value("all", translate("All Groups")) m.uci:foreach("openclash", "groups", - function(s) - if s.name ~= "" and s.name ~= nil then - o:value(s.name) - end - end) +function(s) + if s.name ~= "" and s.name ~= nil then + o:value(s.name) + end +end) local t = { {Commit, Back} diff --git a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua index 629d66131e..fad304bd9f 100644 --- a/openclash/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua +++ b/openclash/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua @@ -252,7 +252,7 @@ ip_ac:value("localnetwork", translate("Local Network")) o = s2:option(Value, "src_port", translate("Internal ports")) o.datatype = "or(port, portrange)" o.placeholder = translate("5000 or 1234-2345") -o.rmempty = false +o.rmempty = true o = s2:option(ListValue, "proto", translate("Proto")) o:value("udp", translate("UDP")) @@ -299,10 +299,10 @@ local function ip_compare(a, b) end return 0 end - + local a_is_ipv4 = datatype.ip4addr(a.dest) local b_is_ipv4 = datatype.ip4addr(b.dest) - + if a_is_ipv4 and not b_is_ipv4 then return true elseif not a_is_ipv4 and b_is_ipv4 then @@ -318,14 +318,20 @@ local all_neighbors = {} luci.ip.neighbors({ family = 4 }, function(n) if n.mac and n.dest then - table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, family = 4}) + if n.hostname then + hostname = " [".. n.hostname .."]" + end + table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, hostname = hostname or "", family = 4}) end end) if string.len(SYS.exec("/usr/share/openclash/openclash_get_network.lua 'gateway6'")) ~= 0 then luci.ip.neighbors({ family = 6 }, function(n) if n.mac and n.dest then - table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, family = 6}) + if n.hostname then + hostname = " [".. n.hostname .."]" + end + table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, hostname = hostname or "", family = 6}) end end) end @@ -334,16 +340,20 @@ table.sort(all_neighbors, ip_compare) local mac_ip_map = {} local mac_order = {} +local mac_hostname_map = {} for _, item in ipairs(all_neighbors) do - ip_b:value(item.dest) - ip_w:value(item.dest) - ip_ac:value(item.dest) + ip_b:value(item.dest, "%s%s" %{ item.dest, item.hostname }) + ip_w:value(item.dest, "%s%s" %{ item.dest, item.hostname }) + ip_ac:value(item.dest, "%s%s" %{ item.dest, item.hostname }) if not mac_ip_map[item.mac] then mac_ip_map[item.mac] = {} table.insert(mac_order, item.mac) end table.insert(mac_ip_map[item.mac], item.dest) + if not mac_hostname_map[item.mac] then + mac_hostname_map[item.mac] = item.hostname + end end for _, mac in ipairs(mac_order) do @@ -366,8 +376,8 @@ for _, mac in ipairs(mac_order) do end end) local ip_str = table.concat(ips, "|") - mac_b:value(mac, "%s (%s)" %{ mac, ip_str }) - mac_w:value(mac, "%s (%s)" %{ mac, ip_str }) + mac_b:value(mac, "%s%s (%s)" %{ mac, mac_hostname_map[mac], ip_str }) + mac_w:value(mac, "%s%s (%s)" %{ mac, mac_hostname_map[mac], ip_str }) end ---- Traffic Control diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/config_edit.htm b/openclash/luci-app-openclash/luasrc/view/openclash/config_edit.htm index 70fc3625ad..1b7ceeff0a 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/config_edit.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/config_edit.htm @@ -573,7 +573,7 @@ - +
@@ -586,7 +586,7 @@ - + @@ -747,7 +747,7 @@
<%:URI and subscription address is supported when online subscription conversion enabled, multiple links should be one per line or separated by%> |
- +
@@ -958,64 +958,64 @@ var ConfigUploader = { selectedFile: null, isProcessing: false, currentMode: 'file', - + init: function() { this.overlay = document.getElementById('config-upload-overlay'); this.model = document.getElementById('config-upload-model'); - + if (!this.overlay || !this.model) { return; } - + this.bindEvents(); }, - + bindEvents: function() { var self = this; var uploadZone = document.getElementById('upload-zone'); var fileInput = document.getElementById('config-file-input'); - + document.getElementById('upload-mode-file').addEventListener('click', function() { self.switchMode('file'); }); - + document.getElementById('upload-mode-subscribe').addEventListener('click', function() { self.switchMode('subscribe'); }); - + uploadZone.addEventListener('click', function() { if (!self.isProcessing && self.currentMode === 'file') { fileInput.click(); } }); - + fileInput.addEventListener('change', function(e) { if (e.target.files.length > 0) { self.handleFileSelect(e.target.files[0]); } }); - + uploadZone.addEventListener('dragover', function(e) { e.preventDefault(); if (!self.isProcessing && self.currentMode === 'file') { uploadZone.classList.add('dragover'); } }); - + uploadZone.addEventListener('dragleave', function(e) { e.preventDefault(); uploadZone.classList.remove('dragover'); }); - + uploadZone.addEventListener('drop', function(e) { e.preventDefault(); uploadZone.classList.remove('dragover'); - + if (!self.isProcessing && self.currentMode === 'file' && e.dataTransfer.files.length > 0) { self.handleFileSelect(e.dataTransfer.files[0]); } }); - + var subscribeUrlInput = document.getElementById('subscribe-url-input'); var filenameInput = document.getElementById('config-filename-input'); var subscribeUaSelect = document.getElementById('subscribe-ua-input'); @@ -1033,9 +1033,9 @@ var ConfigUploader = { self.updateSubmitButton(); self.autoFillConfigName(); }); - + filenameInput.addEventListener('input', this.updateSubmitButton.bind(this)); - + subscribeUaSelect.addEventListener('change', function() { if (this.value === 'custom') { subscribeUaCustom.style.display = 'block'; @@ -1078,7 +1078,7 @@ var ConfigUploader = { customTemplateGroup.style.display = 'none'; } }); - + document.getElementById('config-upload-submit').addEventListener('click', function() { if (self.currentMode === 'file') { self.uploadFile(); @@ -1086,37 +1086,37 @@ var ConfigUploader = { self.processSubscription(); } }); - + document.getElementById('config-upload-cancel').addEventListener('click', function() { if (!self.isProcessing) { self.hide(); } }); - + document.getElementById('config-upload-close').addEventListener('click', function() { if (!self.isProcessing) { self.hide(); } }); - + this.overlay.addEventListener('click', function(e) { if (e.target === self.overlay && !self.isProcessing) { self.hide(); } }); - + document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && !self.isProcessing && self.overlay.classList.contains('show')) { self.hide(); } }); }, - + show: function() { this.overlay.classList.add('show'); this.reset(); }, - + hide: function() { this.overlay.classList.remove('show'); this.reset(); @@ -1128,15 +1128,15 @@ var ConfigUploader = { document.getElementById('convert-address-input').value = 'https://api.dler.io/sub'; document.getElementById('convert-address-custom').style.display = 'none'; document.getElementById('convert-address-custom').value = ''; - + var templateSelect = document.getElementById('template-select'); if (templateSelect && templateSelect.options.length > 1) { templateSelect.selectedIndex = 0; } - + document.getElementById('custom-template-group').style.display = 'none'; document.getElementById('custom-template-input').value = ''; - + document.getElementById('emoji-enable').checked = false; document.getElementById('udp-enable').checked = false; document.getElementById('skip-cert-verify').checked = false; @@ -1144,7 +1144,7 @@ var ConfigUploader = { document.getElementById('node-type-enable').checked = false; document.getElementById('rule-provider-enable').checked = false; document.getElementById('custom-params-input').value = ''; - + document.getElementById('keyword-input').value = ''; document.getElementById('exclude-keyword-input').value = ''; document.getElementById('exclude-expire').checked = false; @@ -1152,42 +1152,42 @@ var ConfigUploader = { document.getElementById('exclude-tg').checked = false; document.getElementById('exclude-website').checked = false; }, - + reset: function() { this.selectedFile = null; this.isProcessing = false; this.currentMode = 'file'; - + this.switchMode('file'); document.getElementById('config-filename-input').value = ''; document.getElementById('subscribe-url-input').value = ''; document.getElementById('subscribe-ua-input').value = 'clash.meta'; document.getElementById('subscribe-ua-custom').style.display = 'none'; - + document.getElementById('advanced-options-enable').checked = false; document.getElementById('advanced-options-container').style.display = 'none'; this.resetAdvancedOptions(); - + var templateSelect = document.getElementById('template-select'); if (templateSelect && templateSelect.options.length > 1) { templateSelect.selectedIndex = 0; } - + document.getElementById('upload-progress').style.display = 'none'; document.getElementById('config-upload-status-text').textContent = '<%:Ready to add config%>'; this.updateSubmitButton(); }, - + switchMode: function(mode) { this.currentMode = mode; - + var modeFileTab = document.getElementById('upload-mode-file'); var modeSubscribeTab = document.getElementById('upload-mode-subscribe'); var modeFileContent = document.getElementById('mode-file-content'); var modeSubscribeContent = document.getElementById('mode-subscribe-content'); var statusText = document.getElementById('config-upload-status-text'); var uploadZone = document.getElementById('upload-zone'); - + if (mode === 'file') { modeFileTab.classList.add('active'); modeSubscribeTab.classList.remove('active'); @@ -1201,49 +1201,49 @@ var ConfigUploader = { modeSubscribeContent.style.display = 'block'; statusText.textContent = '<%:Ready to add subscription%>'; } - + this.selectedFile = null; uploadZone.classList.remove('has-file'); uploadZone.querySelector('.upload-primary').textContent = '<%:Click to select file or drag and drop%>'; uploadZone.querySelector('.upload-secondary').textContent = '<%:Support YAML file, max size 10MB%>'; - + this.updateSubmitButton(); }, - + handleFileSelect: function(file) { this.selectedFile = file; var uploadZone = document.getElementById('upload-zone'); var filenameInput = document.getElementById('config-filename-input'); var statusText = document.getElementById('config-upload-status-text'); - + if (!file) { uploadZone.classList.remove('has-file'); this.updateSubmitButton(); statusText.textContent = '<%:Ready to upload file%>'; return; } - + if (!file.name.match(/\.(yaml|yml)$/i)) { alert('<%:Please select a YAML file%>'); return; } - + if (file.size > 10 * 1024 * 1024) { alert('<%:File size exceeds 10MB limit%>'); return; } - + uploadZone.classList.add('has-file'); uploadZone.querySelector('.upload-primary').textContent = '<%:File selected:%> ' + file.name; uploadZone.querySelector('.upload-secondary').textContent = '<%:Size:%> ' + this.formatFileSize(file.size); - + var defaultName = file.name.replace(/\.(yaml|yml)$/i, ''); filenameInput.value = defaultName; - + this.updateSubmitButton(); statusText.textContent = '<%:File ready to upload%>'; }, - + formatFileSize: function(bytes) { if (bytes === 0) return '0 B'; var k = 1024; @@ -1251,19 +1251,19 @@ var ConfigUploader = { var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; }, - + updateSubmitButton: function() { var filename = document.getElementById('config-filename-input').value.trim(); var submitBtn = document.getElementById('config-upload-submit'); var isValid = false; - + if (this.currentMode === 'file') { isValid = this.selectedFile && filename; } else if (this.currentMode === 'subscribe') { var url = document.getElementById('subscribe-url-input').value.trim(); var advancedEnabled = document.getElementById('advanced-options-enable').checked; var subConvert = advancedEnabled && document.getElementById('sub-convert-enable').checked; - + if (url && filename) { if (subConvert) { if (url.indexOf('\n') !== -1 || url.indexOf('|') !== -1) { @@ -1283,39 +1283,39 @@ var ConfigUploader = { } } } - + submitBtn.disabled = !isValid || this.isProcessing; }, - + uploadFile: function() { if (!this.selectedFile || this.isProcessing) return; - + var filename = document.getElementById('config-filename-input').value.trim(); if (!filename) { alert('<%:Please enter a filename%>'); return; } - + if (!/^[a-zA-Z0-9_\-\s\u4e00-\u9fa5\.]+$/.test(filename)) { alert('<%:Filename contains invalid characters%>'); return; } - + var self = this; this.isProcessing = true; - + var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var statusText = document.getElementById('config-upload-status-text'); var progressContainer = document.getElementById('upload-progress'); var progressFill = document.getElementById('upload-progress-fill'); var progressText = document.getElementById('upload-progress-text'); - + submitBtn.disabled = true; cancelBtn.disabled = true; statusText.textContent = '<%:Uploading...%>'; progressContainer.style.display = 'block'; - + var progress = 0; var progressInterval = setInterval(function() { if (progress < 90) { @@ -1324,22 +1324,22 @@ var ConfigUploader = { progressText.textContent = '<%:Uploading...%> ' + Math.floor(Math.min(progress, 90)) + '%'; } }, 100); - + var reader = new FileReader(); reader.onload = function(e) { var fileContent = e.target.result; - + var formData = new FormData(); formData.append('config_file', fileContent); formData.append('filename', filename); - + fetch('<%=luci.dispatcher.build_url("admin", "services", "openclash", "upload_config")%>', { method: 'POST', body: formData }) .then(function(response) { clearInterval(progressInterval); - + if (!response.ok) { throw new Error('HTTP error! status: ' + response.status); } @@ -1348,10 +1348,10 @@ var ConfigUploader = { .then(function(data) { progressFill.style.width = '100%'; progressText.textContent = '<%:Upload completed%> 100%'; - + if (data.status === 'success') { statusText.textContent = '<%:Upload successful%>'; - + setTimeout(function() { self.hide(); if (typeof ConfigFileManager !== 'undefined' && ConfigFileManager.refreshConfigList) { @@ -1366,24 +1366,24 @@ var ConfigUploader = { self.handleError('<%:Upload failed:%> ' + error.message); }); }; - + reader.onerror = function() { clearInterval(progressInterval); self.handleError('<%:Failed to read file%>'); }; - + reader.readAsText(this.selectedFile, 'UTF-8'); }, - + processSubscription: function() { var url = document.getElementById('subscribe-url-input').value.trim(); var filename = document.getElementById('config-filename-input').value.trim(); var userAgent = document.getElementById('subscribe-ua-input').value; var subscribeUaCustom = document.getElementById('subscribe-ua-custom'); - + var advancedEnabled = document.getElementById('advanced-options-enable').checked; var subConvert = advancedEnabled && document.getElementById('sub-convert-enable').checked; - + var convertAddress = 'https://api.dler.io/sub'; var template = ''; var emoji = false; @@ -1396,7 +1396,7 @@ var ConfigUploader = { var keywords = ''; var excludeKeywords = ''; var excludeDefaults = []; - + if (advancedEnabled) { convertAddress = document.getElementById('convert-address-input').value; var convertAddressCustom = document.getElementById('convert-address-custom').value; @@ -1411,32 +1411,32 @@ var ConfigUploader = { customParams = document.getElementById('custom-params-input').value; keywords = document.getElementById('keyword-input').value; excludeKeywords = document.getElementById('exclude-keyword-input').value; - + if (document.getElementById('exclude-expire').checked) excludeDefaults.push('过期时间'); if (document.getElementById('exclude-traffic').checked) excludeDefaults.push('剩余流量'); if (document.getElementById('exclude-tg').checked) excludeDefaults.push('TG群'); if (document.getElementById('exclude-website').checked) excludeDefaults.push('官网'); - + if (convertAddress === 'custom') { convertAddress = convertAddressCustom.trim() || 'https://api.dler.io/sub'; } - + if (template === '0') { template = customTemplate.trim(); } } - + if (userAgent === 'custom') { userAgent = subscribeUaCustom.value.trim() || 'clash.meta'; } - + if (!url || !filename) { alert('<%:Please enter subscription URL and config name%>'); return; } - + var isValidFormat = false; - + if (subConvert) { if (url.indexOf('\n') !== -1 || url.indexOf('|') !== -1) { var links = []; @@ -1445,7 +1445,7 @@ var ConfigUploader = { } else { links = url.split('|'); } - + for (var i = 0; i < links.length; i++) { var link = links[i].trim(); if (link && (/^https?:\/\//.test(link) || /^[a-zA-Z]+:\/\//.test(link))) { @@ -1463,7 +1463,7 @@ var ConfigUploader = { isValidFormat = true; } } - + if (!isValidFormat) { var errorMsg = subConvert ? '<%:Invalid subscription URL format. Support HTTP/HTTPS subscription URLs or protocol links, can be separated by newlines or |%>' : @@ -1471,7 +1471,7 @@ var ConfigUploader = { alert(errorMsg); return; } - + var requestData = { name: filename, address: url, @@ -1490,22 +1490,22 @@ var ConfigUploader = { ex_keyword: excludeKeywords, de_ex_keyword: excludeDefaults.join('\n') }; - + var self = this; this.isProcessing = true; - + var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var statusText = document.getElementById('config-upload-status-text'); var progressContainer = document.getElementById('upload-progress'); var progressFill = document.getElementById('upload-progress-fill'); var progressText = document.getElementById('upload-progress-text'); - + submitBtn.disabled = true; cancelBtn.disabled = true; statusText.textContent = '<%:Adding subscription...%>'; progressContainer.style.display = 'block'; - + var progress = 0; var progressInterval = setInterval(function() { if (progress < 90) { @@ -1514,7 +1514,7 @@ var ConfigUploader = { progressText.textContent = '<%:Processing...%> ' + Math.floor(Math.min(progress, 90)) + '%'; } }, 100); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "add_subscription")%>', { name: filename, address: url, @@ -1538,12 +1538,12 @@ var ConfigUploader = { filename: filename }, function(x2, data2) { clearInterval(progressInterval); - + if (x2 && x2.status == 200) { progressFill.style.width = '100%'; progressText.textContent = '<%:Subscription added successfully%> 100%'; statusText.textContent = '<%:Subscription added successfully%>'; - + setTimeout(function() { self.hide(); if (typeof ConfigFileManager !== 'undefined' && ConfigFileManager.refreshConfigList) { @@ -1564,34 +1564,34 @@ var ConfigUploader = { autoFillConfigName: function() { var url = document.getElementById('subscribe-url-input').value.trim(); var filenameInput = document.getElementById('config-filename-input'); - + if (!filenameInput.value.trim() && url) { try { var urlObj = new URL(url); var hostname = urlObj.hostname; - + var configName = hostname .replace(/^(www\.|api\.|sub\.|subscribe\.)/, '') .replace(/\.(com|net|org|cn|io|me|cc|xyz|top)$/, '') .replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_') .replace(/_{2,}/g, '_') .replace(/^_|_$/g, ''); - + if (!configName || configName.length < 2) { configName = 'subscription_' + Date.now().toString().slice(-6); } - + if (configName.length > 30) { configName = configName.substring(0, 30); } - + filenameInput.value = configName; this.updateSubmitButton(); } catch (e) { } } }, - + handleError: function(message) { var statusText = document.getElementById('config-upload-status-text'); var progressText = document.getElementById('upload-progress-text'); @@ -1599,13 +1599,13 @@ var ConfigUploader = { var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var progressContainer = document.getElementById('upload-progress'); - + statusText.textContent = '<%:Process failed%>'; progressText.textContent = '<%:Process failed%>'; progressFill.style.width = '0%'; - + alert(message); - + this.isProcessing = false; submitBtn.disabled = false; cancelBtn.disabled = false; diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/developer.htm b/openclash/luci-app-openclash/luasrc/view/openclash/developer.htm index 80510e3423..f94f05d9eb 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/developer.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/developer.htm @@ -173,18 +173,18 @@ .oc .developer-grid { gap: 10px 35px; } - + .oc .developer-avatar { width: 60px; height: 60px; border-width: 3px; } - + .oc .developer-avatar-container { min-width: 60px; width: 60px; } - + .oc .developer-label { font-size: 11px; padding: 3px 8px; @@ -196,18 +196,18 @@ .oc .developer-grid { gap: 6px 25px; } - + .oc .developer-avatar { width: 45px; height: 45px; border-width: 2px; } - + .oc .developer-avatar-container { min-width: 45px; width: 45px; } - + .oc .developer-label { font-size: 9px; padding: 2px 4px; @@ -219,17 +219,17 @@ .oc .developer-grid { gap: 4px 20px; } - + .oc .developer-avatar { width: 40px; height: 40px; } - + .oc .developer-avatar-container { min-width: 40px; width: 40px; } - + .oc .developer-label { font-size: 8px; padding: 1px 4px; @@ -241,17 +241,17 @@ .oc .developer-grid { gap: 3px 15px; } - + .oc .developer-avatar { width: 35px; height: 35px; } - + .oc .developer-avatar-container { min-width: 35px; width: 35px; } - + .oc .developer-label { font-size: 7px; padding: 1px 3px; @@ -263,17 +263,17 @@ .oc .developer-grid { gap: 2px 10px; } - + .oc .developer-avatar { width: 30px; height: 30px; } - + .oc .developer-avatar-container { min-width: 30px; width: 30px; } - + .oc .developer-label { font-size: 6px; padding: 1px 2px; @@ -364,7 +364,7 @@ window.addEventListener('resize', function() { setAvatars(); }); - + function Dreamacro_rediret() { window.open('https://github.com/Dreamacro'); } @@ -410,7 +410,7 @@ function MetaCubeX_rediret() { window.open('https://github.com/MetaCubeX'); } - + function imgerrorfun(imgobj, imgSrc) { setTimeout(function() { imgobj.src = imgSrc; diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/dlercloud.htm b/openclash/luci-app-openclash/luasrc/view/openclash/dlercloud.htm index d8f552b654..5d1ed41f65 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/dlercloud.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/dlercloud.htm @@ -428,28 +428,28 @@ .oc .dler-main-container { width: calc(100% - 32px); } - + .oc .card .additional.collapsed { width: 140px; } - + .oc .card .additional .user-card { width: 140px; } - + .oc .card .additional .more-info h1 { font-size: 1.8rem; } - + .oc .card .additional .coords { font-size: 0.95rem; } - + .oc .card .general { margin-left: 120px; padding-right: 8px; } - + .oc .card .general .more { bottom: 6px; padding-right: 12px; @@ -461,34 +461,34 @@ .oc .dler-main-container { width: 100%; } - + .oc .card .additional.collapsed { width: 125px; } - + .oc .card .additional .user-card { width: 125px; } - + .oc .card .additional .more-info h1 { font-size: 1.5rem; } - + .oc .card .additional .coords { font-size: 0.8rem; } - + .oc .card .general { margin-left: 110px; padding-right: 6px; } - + .oc .card .general h1 { font-size: 24px; line-height: 30px; margin: 0; } - + .oc .card .general .dler-info { grid-template-columns: 1fr; grid-template-rows: auto auto auto; @@ -496,31 +496,31 @@ padding-right: 8px; height: 50%; } - + .oc .card .general .dler-info-right { justify-content: flex-start; padding-top: 8px; gap: 12px; } - + .oc .card .general .btn { width: 80px !important; height: 80px !important; font-size: 14px; padding: 0 !important; } - + .oc .card .general .dler-title { font-size: 14px; width: 50%; } - + .oc .card .general .dler-result, .oc .card .general .dler-result2 { font-size: 14px; width: 50%; } - + .oc .card .general .more { bottom: 4px; padding-right: 10px; @@ -536,23 +536,23 @@ .oc .center { padding: 8px; } - + .oc .card .additional.collapsed { width: 115px; } - + .oc .card .additional .user-card { width: 115px; } - + .oc .card .additional .more-info h1 { font-size: 1.3rem; } - + .oc .card .additional .coords { font-size: 0.7rem; } - + .oc .card .general { margin-left: 120px; padding-right: 4px; @@ -561,7 +561,7 @@ .oc .card .general .dler-info { height: 50%; } - + .oc .card .general h1 { font-size: 18px; line-height: 26px; @@ -578,7 +578,7 @@ font-size: 12px; width: 50%; } - + .oc .card .general .more { bottom: 2px; padding-right: 8px; @@ -637,7 +637,7 @@

- +

@@ -654,7 +654,7 @@

- +
@@ -695,7 +695,7 @@ obj.classList.remove('collapsed'); obj.classList.add('expanded'); }); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_info")%>', null, function(x, status) { if (x && x.status == 200 && status.dler_info != "error") { dler_plan.innerHTML = status.dler_info.plan; @@ -721,7 +721,7 @@ show_less(); } }); - + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_info")%>', null, function(x, status) { if (x && x.status == 200 && status.dler_info != "error") { dler_plan.innerHTML = status.dler_info.plan; @@ -752,7 +752,7 @@ show_less(); } }); - + function dler_checkin_btn(btn) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_checkin")%>', null, function(x, status) { @@ -774,13 +774,13 @@ } }); } - + function web_dler() { url='https://bit.ly/32mrABp'; window.open(url); } - + function show_more() { if (obj.classList.contains('expanded')) { @@ -804,7 +804,7 @@ obj.classList.add('expanded'); obj.classList.remove('collapsed'); } - + var rdmdl = Math.floor(Math.random() * 6) + 1; if (rdmdl == 1) { dler_it.innerHTML = '<%:Simple & trustworthy%>'; diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/log.htm b/openclash/luci-app-openclash/luasrc/view/openclash/log.htm index f775da0407..f0286ef982 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/log.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/log.htm @@ -148,7 +148,7 @@ ul{ .radio-button input[type="radio"] { display: none; } - + .radio-button label { display: flex; align-items: center; @@ -358,7 +358,7 @@ function createAndDownloadFile(fileName, content) { function download_log(){ var dt = new Date(); var timestamp = dt.getFullYear()+"-"+(dt.getMonth()+1)+"-"+dt.getDate()+"-"+dt.getHours()+"-"+dt.getMinutes()+"-"+dt.getSeconds(); - + var oc_content = ""; if (typeof oc_editor !== 'undefined' && oc_editor) { oc_content = oc_editor.getValue(); @@ -367,7 +367,7 @@ function download_log(){ } else if (lv && lv.innerHTML) { oc_content = lv.innerHTML; } - + var core_content = ""; if (typeof core_editor !== 'undefined' && core_editor) { core_content = core_editor.getValue(); @@ -376,15 +376,15 @@ function download_log(){ } else if (cl && cl.innerHTML) { core_content = cl.innerHTML; } - + oc_content = oc_content.split('\n').filter(function(line) { return line.indexOf("】订阅的下载链接为【") === -1 && line.indexOf("】Downloading URL【") === -1; }).join('\n'); - + if (!oc_content.trim() && !core_content.trim()) { return; } - + var downloadContent = ""; if (oc_content.trim()) { downloadContent += "<%:OpenClash Log%>:\n" + oc_content + "\n\n"; @@ -392,7 +392,7 @@ function download_log(){ if (core_content.trim()) { downloadContent += "<%:Core Log%>:\n" + core_content; } - + createAndDownloadFile("OpenClash-"+timestamp+".log", downloadContent); return; }; @@ -418,15 +418,15 @@ function line_tolocal(str) { var trans_local = new Array(); var local_count = 0; - + str.trim().split('\n').forEach(function(v, i) { var regex = /(time=)"([^"]*)"/g; var res = regex.exec(v); - + try { if (res) { var dt = new Date(res[2]); - + if (!isNaN(dt.getTime())) { if (v.indexOf("level=") != -1) { var log_info = v.substring(res[2].length + 7); @@ -443,7 +443,7 @@ function line_tolocal(str) { } else { try { var dtt = new Date(v.substring(0, 19)); - + if (!isNaN(dtt.getTime()) && v.substring(0, 19).match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)) { trans_local[local_count] = v; local_count++; @@ -461,7 +461,7 @@ function line_tolocal(str) { local_count++; } }); - + return trans_local; }; @@ -470,16 +470,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv var isAtTop = false; var cursorPos = null; var selectionRange = null; - + var isFirstLoad = !currentContent || currentContent.trim() === ""; - + if (isEditor && target) { scrollPosition = target.getScrollInfo(); isAtTop = (scrollPosition.top < 20); - + if (target.hasFocus()) { cursorPos = target.getCursor(); - + if (cursorPos.line === 0) { cursorPos = null; selectionRange = null; @@ -499,7 +499,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv scrollPosition = target.scrollTop; isAtTop = (target.scrollTop < 20); } - + if ((target === oc_editor && animatingOC) || (target === core_editor && animatingCore) || !isActiveTab) { var content = ""; var lines = newLines.slice().reverse(); @@ -507,33 +507,33 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv content += lines[i] + "\n"; } content = content + (currentContent || ""); - + var allLines = content.split("\n"); if (allLines.length > 2000) { allLines = allLines.slice(0, 1999); allLines.push("..."); content = allLines.join("\n"); } - + if (isEditor) { var addedLines = lines.length; target.setValue(content); - + if (!isAtTop && scrollPosition) { if (cursorPos) { cursorPos.line += addedLines; target.setCursor(cursorPos); - + target.scrollIntoView({line: cursorPos.line, ch: cursorPos.ch}, 300); } else { target.scrollTo(scrollPosition.left, scrollPosition.top); } - + if (selectionRange) { selectionRange.from.line += addedLines; selectionRange.to.line += addedLines; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -545,7 +545,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv target.setCursor({line: 0, ch: 0}); } } - + target.refresh(); } else { var oldScrollTop = scrollPosition; @@ -556,16 +556,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } return; } - + if (target === oc_editor || target === lv) { animatingOC = true; } else { animatingCore = true; } - + var totalLines = newLines.length; var batchSize, interval; - + if (totalLines <= 10) { batchSize = 2; interval = 90; @@ -588,12 +588,12 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv batchSize = 250; interval = 5; } - + var displayedContent = currentContent || ""; var logLines = newLines.slice(); var currentBatchCount = 0; var accumulatedContent = ""; - + function displayNextBatch() { if (currentBatchCount >= logLines.length) { if (target === oc_editor || target === lv) { @@ -601,16 +601,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } else { animatingCore = false; } - + if (isEditor && !isAtTop && cursorPos) { cursorPos.line += logLines.length; target.setCursor(cursorPos); - + if (selectionRange) { selectionRange.from.line += logLines.length; selectionRange.to.line += logLines.length; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -621,31 +621,31 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } return; } - + var nextBatchSize = Math.min(batchSize, logLines.length - currentBatchCount); - + var batchLines = logLines.slice(currentBatchCount, currentBatchCount + nextBatchSize).reverse(); currentBatchCount += nextBatchSize; - + if (accumulatedContent) { accumulatedContent = batchLines.join("\n") + "\n" + accumulatedContent; } else { accumulatedContent = batchLines.join("\n"); } - + var content = accumulatedContent + (displayedContent ? "\n" + displayedContent : ""); - + var contentLines = content.split("\n"); if (contentLines.length > 2000) { contentLines = contentLines.slice(0, 1999); contentLines.push("..."); content = contentLines.join("\n"); } - + if (isEditor) { var currentScrollInfo = isAtTop ? null : target.getScrollInfo(); target.setValue(content); - + if (!isAtTop && currentScrollInfo) { target.scrollTo(currentScrollInfo.left, currentScrollInfo.top); } @@ -657,7 +657,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv target.scrollTop = currentScrollTop; } } - + if (currentBatchCount < logLines.length) { setTimeout(displayNextBatch, interval); } else { @@ -666,16 +666,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } else { animatingCore = false; } - + if (isEditor && !isAtTop && cursorPos) { cursorPos.line += logLines.length; target.setCursor(cursorPos); - + if (selectionRange) { selectionRange.from.line += logLines.length; selectionRange.to.line += logLines.length; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -686,7 +686,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } } } - + displayNextBatch(); } @@ -702,11 +702,11 @@ function poll_log(){ r = setTimeout("poll_log()", 2000); return; } - + if (status.len) { log_len = status.len; } - + var activeTabId = 0; var titles = document.getElementsByName('tab-header'); for(var i=0; i 0) { if (oc_editor) { var currentContent = oc_editor.getValue(); @@ -729,10 +729,10 @@ function poll_log(){ } } } - + if (status.core_log && status.core_log !== "") { var core_logs = line_tolocal(status.core_log); - + if (core_logs && core_logs.length > 0) { if (core_editor) { var currentCoreContent = core_editor.getValue(); @@ -778,7 +778,7 @@ window.onload = function(){ } }; } - + li.onclick = handleTabSwitch(li); li.ontouchstart = handleTabSwitch(li); } diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/myip.htm b/openclash/luci-app-openclash/luasrc/view/openclash/myip.htm index ec4469a347..d5d845c411 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/myip.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/myip.htm @@ -5,7 +5,7 @@ - + @@ -13,7 +13,7 @@ - + @@ -419,48 +419,48 @@ --card-item-padding: 8px 6px; --card-item-min-height: 80px; } - + .oc .myip-content-grid { grid-template-columns: 1fr; } - + .oc .myip-section-title { font-size: 22px; margin-bottom: 12px; } - + .oc .myip-ip-list, .oc .myip-check-list { grid-template-columns: repeat(2, 1fr); } - + .oc .ip-title, .oc .ip-state_title { font-size: 13px; } - + .oc .ip-title::after, .oc .ip-state_title::after { width: 25px; } - + .oc .ip-result { font-size: 12px; } - + .oc .ip-geo { font-size: 12px; } - + .oc .sk-text-success, .oc .sk-text-error { font-size: 12px; } - + .oc .sk-load-success { font-size: 12px; } - + .oc .myip-footer p { font-size: 13px !important; line-height: 18px !important; @@ -472,44 +472,44 @@ --card-item-padding: 6px 4px; --card-item-min-height: 70px; } - + .oc .myip-content-grid { padding: 2px; } - + .oc .myip-section-title { font-size: 20px; margin-bottom: 10px; } - + .oc .ip-title, .oc .ip-state_title { font-size: 12px; margin-bottom: 6px; } - + .oc .ip-title::after, .oc .ip-state_title::after { width: 20px; } - + .oc .ip-result { font-size: 11px; } - + .oc .ip-geo { font-size: 11px; } - + .oc .sk-text-success, .oc .sk-text-error { font-size: 11px; } - + .oc .sk-load-success { font-size: 11px; } - + .oc .myip-footer p { font-size: 11px !important; line-height: 16px !important; @@ -543,7 +543,7 @@

- +
UpaiYun @@ -552,7 +552,7 @@
- +
IPIP.NET
@@ -560,7 +560,7 @@
- +
IP.SB
@@ -568,7 +568,7 @@
- +
IPIFY
@@ -578,7 +578,7 @@
- +

<%:Access Check%> @@ -598,7 +598,7 @@

- +
<%:Baidu Search%> @@ -607,7 +607,7 @@
- +
<%:NetEase Music%>
@@ -615,7 +615,7 @@
- +
GitHub
@@ -623,7 +623,7 @@
- +
YouTube
@@ -633,7 +633,7 @@
- + @@ -657,8 +657,8 @@ } function ip_skk() { - url2='https://ip.skk.moe'; - window.open(url2); + url2='https://ip.skk.moe'; + window.open(url2); } const $$ = document; var ip_ipip_ip; @@ -728,6 +728,18 @@ } }) }, + getPcolIP: () => { + fetch(`https://whois.pconline.com.cn/ipJson.jsp?z=${random}`) + .then(response => response.json()) + .then(data => { + let pcisp = data.addr.split(' '); + if (localStorage.getItem('privacy_my_ip') != 'true') { + $$.getElementById('ip-pcol').innerHTML = data.ip; + }; + $$.getElementById('ip-pcol-geo').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`; + addTitleOnOverflow(); + }) + }, getUpaiIP: () => { IP.get(`https://pubstatic.b0.upaiyun.com/?_upnode&z=${random}`, 'json') .then(resp => { @@ -743,7 +755,7 @@ .then(resp => { const ipMatch = resp.data.match(/当前 IP:([0-9.]+)/); const geoMatch = resp.data.match(/来自于:(.+)/); - + if (ipMatch && geoMatch) { if (localStorage.getItem('privacy_my_ip') != 'true') { $$.getElementById('ip-ipip').innerHTML = ipMatch[1]; @@ -765,9 +777,20 @@ IP.parseIPIpip(ip, 'ip-ipify-geo'); addTitleOnOverflow(); }) + }, + getIpsbIP: () => { + fetch(`https://api.ip.sb/geoip?z=${random}`) + .then(response => response.json()) + .then(data => { + if (localStorage.getItem('privacy_my_ip') != 'true') { + $$.getElementById('ip-ipsb').innerHTML = data.ip; + }; + $$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.isp}`; + addTitleOnOverflow(); + }) } }; - + $$.getElementById('http-baidu').innerHTML = '<%:Testing...%>'; $$.getElementById('http-163').innerHTML = '<%:Testing...%>'; $$.getElementById('http-github').innerHTML = '<%:Testing...%>'; @@ -820,15 +843,15 @@ }, checker_router: (domain, cbElID, cbLoID) => { let start_time = (+new Date()); - + var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/website_check?domain=' + encodeURIComponent(domain), true); xhr.timeout = 10000; - + xhr.onreadystatechange = function() { if (xhr.readyState === 4) { let response_time = (new Date()) - start_time; - + if (xhr.status === 200) { try { var response = JSON.parse(xhr.responseText); @@ -836,7 +859,7 @@ if ($$.getElementById(cbLoID).style.display == 'none') { $$.getElementById(cbLoID).style.display = ''; } - + let load_time = response.response_time || response_time; if (load_time <= 500) { $$.getElementById(cbLoID).innerHTML = '' + load_time + ' ms' @@ -865,17 +888,17 @@ } } }; - + xhr.ontimeout = function() { $$.getElementById(cbLoID).style.display = 'none'; $$.getElementById(cbElID).innerHTML = '<%:Access Timed Out%>' }; - + xhr.onerror = function() { $$.getElementById(cbLoID).style.display = 'none'; $$.getElementById(cbElID).innerHTML = '<%:Access Denied%>' }; - + xhr.send(); }, runcheck: () => { @@ -886,53 +909,13 @@ } }; - //function getPcolIP(data){ - // let pcisp = data.addr.split(' '); - // if (localStorage.getItem('privacy_my_ip') != 'true') { - // $$.getElementById('ip-pcol').innerHTML = data.ip; - // }; - // $$.getElementById('ip-pcol-geo').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`; - // addTitleOnOverflow(); - //}; - - function getIpsbIP(data){ - if (localStorage.getItem('privacy_my_ip') != 'true') { - $$.getElementById('ip-ipsb').innerHTML = data.ip; - }; - $$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.isp}`; - addTitleOnOverflow(); - }; - - function delete_ip_script() - { - var scripts = document.getElementsByTagName('script'); - for (var i = scripts.length; i--; ) { - if (document.getElementsByTagName("script")[i]['src'] && - (document.getElementsByTagName("script")[i]['src'].indexOf('whois.pconline.com.cn') > -1 - || document.getElementsByTagName("script")[i]['src'].indexOf('api-ipv4.ip.sb') > -1)) { - scripts[i].parentNode.removeChild(scripts[i]); - }; - }; - }; - function myip_Load() { - delete_ip_script(); - var mypage = document.getElementsByTagName('HEAD').item(0); - var random = parseInt(Math.random() * 100000000); - //var pcipScript= document.createElement("script"); - //pcipScript.defer = "defer"; - //pcipScript.src=`https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP&z=${random}`; - //mypage.appendChild(pcipScript); - - var sbipScript= document.createElement("script"); - sbipScript.defer = "defer"; - sbipScript.src=`https://api-ipv4.ip.sb/geoip?callback=getIpsbIP&z=${random}`; - mypage.appendChild(sbipScript); - + //IP.getPcolIP(); IP.getUpaiIP(); IP.getIpipIP(); IP.getIpifyIP(); + IP.getIpsbIP(); }; function show_my_ip() { @@ -968,7 +951,7 @@ var eyeOpenCircle = document.getElementById('eye-open-circle'); var eyeClosed = document.getElementById('eye-closed'); var titleElement = eyeIcon.querySelector('title'); - + if (isOpen) { eyeOpen.style.display = ''; eyeOpenCircle.style.display = ''; @@ -984,14 +967,13 @@ function privacy_my_ip(svgElement) { var isCurrentlyOpen = document.getElementById('eye-open').style.display !== 'none'; - + if (isCurrentlyOpen) { - delete_ip_script(); clearInterval(refresh_ip); refresh_ip = null; localStorage.setItem('privacy_my_ip', 'true'); update_eye_icon(false); - + ip_ipip_ip = $$.getElementById('ip-ipip').innerHTML; ip_ipsb_ip = $$.getElementById('ip-ipsb').innerHTML; ip_upaiyun_ip = $$.getElementById('ip-upaiyun').innerHTML; @@ -1032,7 +1014,7 @@ }; var use_router_mode = true; - + function toggle_mode_by_icon(svgElement) { var rect = svgElement.querySelector('rect[fill="#2F88FF"]'); if (rect && rect.getAttribute('fill') === '#2F88FF') { @@ -1049,14 +1031,14 @@ init_router_mode(); } } - + function update_mode_icon() { var modeIcon = document.getElementById('mode-icon'); var rect = modeIcon.querySelector('rect[x="4"]'); var paths = modeIcon.querySelectorAll('path'); var smallRect = modeIcon.querySelector('rect[x="30"]'); var titleElement = modeIcon.querySelector('title'); - + if (use_router_mode) { rect.setAttribute('fill', '#2F88FF'); rect.setAttribute('stroke', '#333'); @@ -1075,30 +1057,29 @@ if (titleElement) titleElement.textContent = '<%:Browser Mode%>'; } } - + function init_router_mode() { if (refresh_ip) { clearInterval(refresh_ip); refresh_ip = null; } - delete_ip_script(); - + if (localStorage.getItem('privacy_my_ip') === 'true') { $$.getElementById('ip-ipip').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***'; $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipify').innerHTML = '***.***.***.***'; } - + get_router_ip_info(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("get_router_ip_info()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + function init_browser_mode() { if (localStorage.getItem('privacy_my_ip') === 'true') { $$.getElementById('ip-ipip').innerHTML = '***.***.***.***'; @@ -1112,16 +1093,16 @@ } else { reset_display(); } - + myip_Load(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + function get_router_ip_info() { var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/myip_check', true); @@ -1189,7 +1170,7 @@ $$.getElementById('ip-upaiyun-geo').innerHTML = ''; $$.getElementById('ip-ipify-geo').innerHTML = ''; } - + function update_ip_display(data) { const ipFields = [ { id: 'ip-upaiyun', geo: 'ip-upaiyun-geo', key: 'upaiyun' }, @@ -1233,19 +1214,19 @@ } addTitleOnOverflow(); } - + function reset_display() { $$.getElementById('ip-ipip').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-upaiyun').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>'; - + $$.getElementById('ip-ipip-geo').innerHTML = ''; $$.getElementById('ip-ipify-geo').innerHTML = ''; $$.getElementById('ip-upaiyun-geo').innerHTML = ''; $$.getElementById('ip-ipsb-geo').innerHTML = ''; } - + function clearAllIntervals() { if (refresh_http) { clearInterval(refresh_http); @@ -1256,15 +1237,15 @@ refresh_ip = null; } } - + function refresh_myip(svgElement) { svgElement.style.transform = 'rotate(360deg)'; setTimeout(function() { svgElement.style.transform = ''; }, 500); - + clearAllIntervals(); - + if (use_router_mode) { get_router_ip_info(); HTTP.runcheck(); @@ -1283,19 +1264,19 @@ $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipify').innerHTML = '***.***.***.***'; } - + myip_Load(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + return false; } - + function init_page() { var saved_mode = localStorage.getItem('myip_check_mode'); if (saved_mode === 'true' || saved_mode === null) { @@ -1307,18 +1288,18 @@ update_mode_icon(); init_browser_mode(); } - + if (localStorage.getItem('privacy_my_ip') === 'true') { update_eye_icon(false); } else { update_eye_icon(true); } } - + window.addEventListener('load', function() { init_page(); }); - + window.addEventListener('beforeunload', function() { clearAllIntervals(); }); diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm b/openclash/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm index 9a39fbf1d8..e5bf26c579 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm @@ -21,7 +21,7 @@ --radius-lg: 8px; --transition-fast: 0.15s ease; --transition-normal: 0.3s ease; - + --control-height: 36px; --card-padding: 6px 8px; --gap-size: 16px; @@ -369,12 +369,12 @@ grid-template-columns: 1fr; gap: 12px; } - + .config-item { width: 100%; max-width: 100%; } - + .select-class { max-width: 100%; font-size: 13px; @@ -389,38 +389,38 @@ max-height: 90vh; overflow-y: auto; } - + .config-grid { grid-template-columns: 1fr; gap: 12px; } - + .config-item { text-align: center; } - + .select-popup-header { font-size: 16px; margin-bottom: 16px; padding-bottom: 12px; } - + .select-config-section { padding: 12px; margin-bottom: 16px; } - + .select-popup-body { max-height: 200px; } - + .select-option { padding: 10px 12px; font-size: 13px; align-items: flex-start; gap: 4px; } - + .custom-option-input { font-size: 13px; padding: 10px; @@ -433,32 +433,32 @@ width: 80%; padding: 12px; } - + .select-popup-header { font-size: 15px; margin-bottom: 12px; } - + .select-config-section { padding: 10px; } - + .config-label { font-size: 12px; } - + .select-class { font-size: 12px; padding: 6px 28px 6px 10px; } - + .config-item::after { right: 10px; border-left: 3px solid transparent; border-right: 3px solid transparent; border-top: 3px solid var(--text-secondary); } - + .select-option { padding: 8px 10px; font-size: 12px; @@ -578,7 +578,7 @@
- +
<%:Release Branch%>
- +
<%:Smart Core%> @@ -605,7 +605,7 @@
- +
https://raw.githubusercontent.com/ (<%:RAW address%>) @@ -642,9 +642,9 @@ function initDarkMode() { var ocContainer = document.querySelector('.oc'); if (!ocContainer) return; - + var shouldUseDark = isDarkBackground(document.body); - + if (shouldUseDark) { ocContainer.setAttribute('data-darkmode', 'true'); } else { @@ -691,7 +691,7 @@ } }); } - + function isValidURL(str) { var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name @@ -701,7 +701,7 @@ '(\\#[-a-z\\d_]*)?'+'\/$','i'); // fragment locator return !!pattern.test(str); } - + function HTTP_delay(domain, ID) { var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/website_check?domain=' + encodeURIComponent(domain), true); @@ -751,13 +751,13 @@ xhr.send(); } - + function updateCDNStatus(element, status, text) { var existingStatus = element.querySelector('.cdn-status'); if (existingStatus) { existingStatus.remove(); } - + var statusSpan = document.createElement('span'); statusSpan.className = 'cdn-status ' + status; statusSpan.textContent = text; @@ -790,7 +790,7 @@ } }, Math.floor(Math.random()*(7-3+1)+3)*1000); } - + function select_window_close(event) { var selectPopup = document.getElementById('selectPopup'); if (!selectPopup.contains(event.target)) { diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/server_url.htm b/openclash/luci-app-openclash/luasrc/view/openclash/server_url.htm index e91ec0187e..70ab99c64a 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/server_url.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/server_url.htm @@ -115,13 +115,13 @@ function setFormValue(sid, field, value) { function export_url(btn, urlname, sid) { var s = document.getElementById(urlname + '-status'); if (!s) return false; - + var v_type = document.getElementsByName('cbid.openclash.' + sid + '.type')[0]; if (!v_type) return false; - + var type = v_type.value.toLowerCase(); var url = null; - + try { switch (type) { case "ss": @@ -161,7 +161,7 @@ function export_url(btn, urlname, sid) { s.innerHTML = "<%:Unsupported protocol type%>"; return false; } - + if (url) { var textarea = document.createElement("textarea"); textarea.textContent = url; @@ -183,7 +183,7 @@ function export_url(btn, urlname, sid) { s.innerHTML = "<%:Export error%>"; return false; } - + return false; } @@ -202,17 +202,17 @@ function exportSS(sid) { var host = getFormValue(sid, 'host'); var path = getFormValue(sid, 'path'); var tls = getFormValue(sid, 'tls'); - + if (!server || !port || !password || !cipher) { return null; } - + // SIP002 format var userInfo = b64encsafe(cipher + ':' + password); var url = userInfo + '@' + server + ':' + port + '/?'; - + var params = []; - + if (obfs && obfs !== 'none') { var plugin = ''; if (obfs === 'http' || obfs === 'tls') { @@ -236,13 +236,13 @@ function exportSS(sid) { params.push('plugin=' + encodeURIComponent(plugin)); } } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'ss://' + url; } @@ -256,15 +256,15 @@ function exportSSR(sid) { var obfs_param = getFormValue(sid, 'obfs_param'); var protocol_param = getFormValue(sid, 'protocol_param'); var name = getFormValue(sid, 'name'); - + if (!server || !port || !password || !method) { return null; } - + var ssr_str = server + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + b64encsafe(password) + "/?obfsparam=" + b64encsafe(obfs_param) + "&protoparam=" + b64encsafe(protocol_param) + "&remarks=" + b64encutf8safe(name); - + return "ssr://" + b64encsafe(ssr_str); } @@ -278,11 +278,11 @@ function exportVmess(sid) { var obfs = getFormValue(sid, 'obfs_vmess'); var tls = getFormValue(sid, 'tls'); var servername = getFormValue(sid, 'servername'); - + if (!server || !port || !uuid) { return null; } - + var info = { "v": "2", "ps": name || "", @@ -297,11 +297,11 @@ function exportVmess(sid) { "path": "", "tls": tls === 'true' ? "tls" : "" }; - + if (tls === 'true' && servername) { info.sni = servername; } - + // Handle network type if (obfs === 'websocket') { info.net = "ws"; @@ -318,7 +318,7 @@ function exportVmess(sid) { info.net = "grpc"; info.path = getFormValue(sid, 'grpc_service_name') || ''; } - + return "vmess://" + b64EncodeUnicode(JSON.stringify(info)); } @@ -331,16 +331,16 @@ function exportVless(sid) { var servername = getFormValue(sid, 'servername'); var obfs = getFormValue(sid, 'obfs_vless'); var flow = getFormValue(sid, 'vless_flow'); - + if (!server || !port || !uuid) { return null; } - + var url = uuid + '@' + server + ':' + port + '?'; var params = []; - + params.push('encryption=none'); - + if (tls === 'true') { if (flow && flow.includes('xtls')) { params.push('security=xtls'); @@ -352,7 +352,7 @@ function exportVless(sid) { params.push('sni=' + encodeURIComponent(servername)); } } - + if (obfs === 'ws') { params.push('type=ws'); var path = getFormValue(sid, 'ws_opts_path'); @@ -373,13 +373,13 @@ function exportVless(sid) { } else { params.push('type=tcp'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'vless://' + url; } @@ -391,32 +391,32 @@ function exportTrojan(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port || !password) { return null; } - + var url = encodeURIComponent(password) + '@' + server + ':' + port + '/?'; var params = []; - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('allowInsecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'trojan://' + url; } @@ -432,52 +432,52 @@ function exportHysteria(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'hysteria_alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = server + ':' + port + '?'; var params = []; - + if (auth) { params.push('auth=' + encodeURIComponent(auth)); } - + if (protocol) { params.push('protocol=' + protocol); } - + if (up) { params.push('up=' + up); } - + if (down) { params.push('down=' + down); } - + if (obfs) { params.push('obfsParam=' + encodeURIComponent(obfs)); } - + if (sni) { params.push('peer=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'hysteria://' + url; } @@ -493,53 +493,53 @@ function exportHysteria2(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'hysteria_alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = ''; if (password) { url += encodeURIComponent(password) + '@'; } url += server + ':' + port + '?'; - + var params = []; - + if (obfs) { params.push('obfs=' + encodeURIComponent(obfs)); } - + if (obfs_password) { params.push('obfs-password=' + encodeURIComponent(obfs_password)); } - + if (up) { params.push('up=' + up); } - + if (down) { params.push('down=' + down); } - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'hysteria2://' + url; } @@ -555,11 +555,11 @@ function exportTuic(sid) { var sni = getFormValue(sid, 'sni'); var disable_sni = getFormValue(sid, 'disable_sni'); var udp_relay = getFormValue(sid, 'udp_relay_mode'); - + if (!server || !port) { return null; } - + var url = ''; if (password) { // TUIC v5 @@ -568,37 +568,37 @@ function exportTuic(sid) { // TUIC v4 url += encodeURIComponent(token) + '@'; } - + url += server + ':' + port + '?'; - + var params = []; - + if (cc) { params.push('congestion_control=' + encodeURIComponent(cc)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (disable_sni === 'true') { params.push('disable_sni=1'); } - + if (udp_relay) { params.push('udp_relay_mode=' + encodeURIComponent(udp_relay)); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'tuic://' + url; } @@ -608,21 +608,21 @@ function exportSocks(sid) { var username = getFormValue(sid, 'auth_name'); var password = getFormValue(sid, 'auth_pass'); var name = getFormValue(sid, 'name'); - + if (!server || !port) { return null; } - + var url = ''; if (username && password) { url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@'; } url += server + ':' + port; - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'socks5://' + url; } @@ -633,23 +633,23 @@ function exportHttp(sid) { var password = getFormValue(sid, 'auth_pass'); var name = getFormValue(sid, 'name'); var tls = getFormValue(sid, 'tls'); - + if (!server || !port) { return null; } - + var scheme = tls === 'true' ? 'https' : 'http'; var url = ''; - + if (username && password) { url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@'; } url += server + ':' + port; - + if (name) { url += '#' + encodeURIComponent(name); } - + return scheme + '://' + url; } @@ -662,11 +662,11 @@ function exportAnyTLS(sid) { var sni = getFormValue(sid, 'sni'); var fingerprint = getFormValue(sid, 'fingerprint'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = ''; if (username) { url += encodeURIComponent(username); @@ -676,51 +676,51 @@ function exportAnyTLS(sid) { url += '@'; } url += server + ':' + port + '?'; - + var params = []; - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (fingerprint) { params.push('hpkp=' + encodeURIComponent(fingerprint)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'anytls://' + url; } function import_url(btn, urlname, sid) { var s = document.getElementById(urlname + '-status'); if (!s) return false; - + var ssrurl = prompt("<%:Paste sharing link here%>", ""); if (ssrurl == null || ssrurl == "") { s.innerHTML = "<%:User cancelled%>"; return false; } s.innerHTML = ""; - + var ssu = ssrurl.split('://'); if (ssu.length < 2) { s.innerHTML = "<%:Invalid format%>"; return false; } - + var scheme = ssu[0].toLowerCase(); var event = document.createEvent("HTMLEvents"); event.initEvent("change", true, true); - + try { switch (scheme) { case "ss": @@ -730,7 +730,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "ssr": if (parseSSR(ssu[1], sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -738,7 +738,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "vmess": if (parseVmess(ssu[1], sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -746,7 +746,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "vless": if (parseVless(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -754,7 +754,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "trojan": if (parseTrojan(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -762,7 +762,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "hysteria": if (parseHysteria(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -770,7 +770,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "hysteria2": case "hy2": if (parseHysteria2(ssrurl, sid)) { @@ -779,7 +779,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "tuic": if (parseTuic(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -787,7 +787,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "socks": case "socks5": case "socks5h": @@ -797,7 +797,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "http": case "https": if (parseHttp(ssrurl, sid)) { @@ -806,7 +806,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "anytls": if (parseAnyTLS(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -814,7 +814,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + default: s.innerHTML = "<%:Invalid format%>"; return false; @@ -823,7 +823,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Parse error%>"; return false; } - + return false; } @@ -831,16 +831,16 @@ function parseSS(body, sid) { var url0, param = ""; var sipIndex = body.indexOf("@"); var ploc = body.indexOf("#"); - + if (ploc > 0) { url0 = body.substr(0, ploc); param = body.substr(ploc + 1); } else { url0 = body; } - + setFormValue(sid, 'type', 'ss'); - + if (sipIndex !== -1) { // SIP002 format var userInfo = b64decsafe(url0.substr(0, sipIndex)); @@ -849,28 +849,28 @@ function parseSS(body, sid) { var server = serverInfo[0]; var port = serverInfo[1]; var method, password; - + if (temp[1]) { var query = parseQuery("?" + temp[1]); - + if (query.plugin) { var decodedPlugin = decodeURIComponent(query.plugin); - + var pluginParts = decodedPlugin.split(';'); var pluginName = pluginParts[0]; - + // obfs-local if (pluginName === 'obfs-local' || pluginName.includes('obfs')) { var obfsMode = 'http'; var obfsHost = ''; - + for (var i = 1; i < pluginParts.length; i++) { var opt = pluginParts[i]; var eqIndex = opt.indexOf('='); if (eqIndex !== -1) { var key = opt.substring(0, eqIndex).trim(); var value = opt.substring(eqIndex + 1).trim(); - + if (key === 'obfs') { obfsMode = value; } else if (key === 'obfs-host') { @@ -878,27 +878,27 @@ function parseSS(body, sid) { } } } - + setFormValue(sid, 'obfs', obfsMode); if (obfsHost) { setFormValue(sid, 'host', obfsHost); } } - + // v2ray-plugin if (pluginName === 'v2ray-plugin') { var v2rayMode = 'websocket'; var v2rayHost = ''; var v2rayPath = '/'; var v2rayTls = false; - + for (var i = 1; i < pluginParts.length; i++) { var opt = pluginParts[i]; var eqIndex = opt.indexOf('='); if (eqIndex !== -1) { var key = opt.substring(0, eqIndex).trim(); var value = opt.substring(eqIndex + 1).trim(); - + if (key === 'mode') { v2rayMode = value; } else if (key === 'host') { @@ -910,7 +910,7 @@ function parseSS(body, sid) { } } } - + setFormValue(sid, 'obfs', 'websocket'); if (v2rayHost) { setFormValue(sid, 'host', v2rayHost); @@ -923,18 +923,18 @@ function parseSS(body, sid) { } } } - + if (query['udp-over-tcp'] === 'true' || query['uot'] === '1') { setFormValue(sid, 'udp_over_tcp', 'true'); } } - + var userInfoSplitIndex = userInfo.indexOf(":"); if (userInfoSplitIndex !== -1) { method = userInfo.substr(0, userInfoSplitIndex); password = userInfo.substr(userInfoSplitIndex + 1); } - + setFormValue(sid, 'server', server); setFormValue(sid, 'port', port); setFormValue(sid, 'password', password || ""); @@ -945,17 +945,17 @@ function parseSS(body, sid) { var team = sstr.split('@'); var part1 = team[0].split(':'); var part2 = team[1].split(':'); - + setFormValue(sid, 'server', part2[0]); setFormValue(sid, 'port', part2[1]); setFormValue(sid, 'password', part1[1]); setFormValue(sid, 'cipher', part1[0]); } - + if (param) { setFormValue(sid, 'name', decodeURIComponent(param)); } - + return true; } @@ -966,7 +966,7 @@ function parseSSR(body, sid) { } catch (e) { return false; } - + setFormValue(sid, 'type', 'ssr'); // ssr://host:port:protocol:method:obfs:urlsafebase64pass/?obfsparam=... @@ -979,26 +979,26 @@ function parseSSR(body, sid) { before = dcBuf; after = ""; } - + var parts = before.split(':'); if (parts.length !== 6) { return false; } - + var host = parts[0]; var port = parts[1]; var protocol = parts[2]; var method = parts[3]; var obfs = parts[4]; var password = b64decsafe(parts[5]); - + setFormValue(sid, 'server', host); setFormValue(sid, 'port', port); setFormValue(sid, 'protocol', protocol); setFormValue(sid, 'cipher_ssr', method); setFormValue(sid, 'obfs_ssr', obfs); setFormValue(sid, 'password', password); - + if (after) { var params = {}; var paramPairs = after.split('&'); @@ -1010,20 +1010,20 @@ function parseSSR(body, sid) { params[key] = value; } } - + if (params.obfsparam) { setFormValue(sid, 'obfs_param', b64decsafe(params.obfsparam)); } - + if (params.protoparam) { setFormValue(sid, 'protocol_param', b64decsafe(params.protoparam)); } - + if (params.remarks) { setFormValue(sid, 'name', b64decutf8safe(params.remarks)); } } - + return true; } @@ -1032,25 +1032,25 @@ function parseVmess(body, sid) { // Try V2rayN format first var sstr = b64DecodeUnicode(body); var ssm = JSON.parse(sstr); - + setFormValue(sid, 'type', 'vmess'); setFormValue(sid, 'name', ssm.ps || ''); setFormValue(sid, 'server', ssm.add); setFormValue(sid, 'port', ssm.port); setFormValue(sid, 'alterId', ssm.aid || 0); setFormValue(sid, 'uuid', ssm.id); - + if (ssm.scy) { setFormValue(sid, 'securitys', ssm.scy); } - + if (ssm.tls === "tls") { setFormValue(sid, 'tls', 'true'); if (ssm.sni) { setFormValue(sid, 'servername', ssm.sni); } } - + var network = (ssm.net || 'tcp').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_vmess', 'websocket'); @@ -1080,27 +1080,27 @@ function parseVmess(body, sid) { setFormValue(sid, 'obfs_vmess', 'grpc'); setFormValue(sid, 'grpc_service_name', ssm.path || ''); } - + return true; } catch (e) { // Try Xray VMessAEAD format try { var parsed = parseUrl('vmess://' + body); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'vmess'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'uuid', parsed.username); setFormValue(sid, 'alterId', 0); setFormValue(sid, 'securitys', query.encryption || 'auto'); - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } catch (e2) { return false; @@ -1111,14 +1111,14 @@ function parseVmess(body, sid) { function parseVless(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'vless'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'uuid', parsed.username); - + if (query.security) { if (query.security === 'tls' || query.security === 'xtls') { setFormValue(sid, 'tls', 'true'); @@ -1141,7 +1141,7 @@ function parseVless(url, sid) { } } } - + var network = (query.type || 'tcp').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_vless', 'ws'); @@ -1155,34 +1155,34 @@ function parseVless(url, sid) { } else { setFormValue(sid, 'obfs_vless', 'tcp'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseTrojan(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'trojan'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'password', parsed.username); - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.alpn) { // Handle ALPN - multiple values support, decode properly setFormValue(sid, 'alpn', decodeURIComponent(query.alpn)); } - + var network = (query.type || '').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_trojan', 'ws'); @@ -1194,131 +1194,131 @@ function parseTrojan(url, sid) { setFormValue(sid, 'obfs_trojan', 'grpc'); setFormValue(sid, 'grpc_service_name', decodeURIComponent(query.serviceName || '')); } - + if (query.allowInsecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseHysteria(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'hysteria'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + if (query.auth) { setFormValue(sid, 'hysteria_auth_str', decodeURIComponent(query.auth)); } - + if (query.protocol) { setFormValue(sid, 'flag_transport', '1'); setFormValue(sid, 'hysteria_protocol', query.protocol); } - + if (query.up || query.upmbps) { var upSpeed = decodeURIComponent(query.up || query.upmbps); upSpeed = upSpeed.replace(/[^0-9]/g, ''); setFormValue(sid, 'hysteria_up', upSpeed); } - + if (query.down || query.downmbps) { var downSpeed = decodeURIComponent(query.down || query.downmbps); downSpeed = downSpeed.replace(/[^0-9]/g, ''); setFormValue(sid, 'hysteria_down', downSpeed); } - + if (query.obfs || query.obfsParam) { setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs || query.obfsParam)); } - + if (query.peer) { setFormValue(sid, 'sni', decodeURIComponent(query.peer)); } - + if (query.alpn) { setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn)); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseHysteria2(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'hysteria2'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + if (parsed.username) { setFormValue(sid, 'password', parsed.username); } - + if (query.obfs) { setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs)); } - + if (query['obfs-password']) { setFormValue(sid, 'hysteria_obfs_password', decodeURIComponent(query['obfs-password'])); } - + if (query.up) { setFormValue(sid, 'hysteria_up', decodeURIComponent(query.up)); } - + if (query.down) { setFormValue(sid, 'hysteria_down', decodeURIComponent(query.down)); } - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.alpn) { setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn)); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseTuic(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'tuic'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + // Check if it's v5 (has password) or v4 (token only) if (parsed.password) { setFormValue(sid, 'uuid', parsed.username); @@ -1326,42 +1326,42 @@ function parseTuic(url, sid) { } else { setFormValue(sid, 'tc_token', parsed.username); } - + if (query.congestion_control) { setFormValue(sid, 'congestion_controller', decodeURIComponent(query.congestion_control)); } - + if (query.alpn) { setFormValue(sid, 'tc_alpn', decodeURIComponent(query.alpn)); } - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.disable_sni === '1') { setFormValue(sid, 'disable_sni', 'true'); } - + if (query.udp_relay_mode) { setFormValue(sid, 'udp_relay_mode', decodeURIComponent(query.udp_relay_mode)); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseSocks(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + setFormValue(sid, 'type', 'socks5'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '1080'); - + if (parsed.username) { try { var decoded = atob(parsed.username); @@ -1375,28 +1375,28 @@ function parseSocks(url, sid) { } } } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } function parseHttp(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + setFormValue(sid, 'type', 'http'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || (parsed.protocol === 'https:' ? '443' : '80')); - + if (parsed.protocol === 'https:') { setFormValue(sid, 'tls', 'true'); } - + if (parsed.username) { try { var decoded = atob(parsed.username); @@ -1410,46 +1410,46 @@ function parseHttp(url, sid) { } } } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } function parseAnyTLS(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'anytls'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'auth_name', parsed.username); setFormValue(sid, 'password', parsed.password || parsed.username); - + if (query.sni) { setFormValue(sid, 'sni', query.sni); } - + if (query.hpkp) { setFormValue(sid, 'fingerprint', query.hpkp); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/status.htm b/openclash/luci-app-openclash/luasrc/view/openclash/status.htm index 8f8a520a43..ac6f3fdbb6 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/status.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/status.htm @@ -25,15 +25,15 @@ --radius-lg: 8px; --transition-fast: 0.15s ease; --transition-normal: 0.3s ease; - + --control-height: 32px; --card-padding: 6px 8px; --gap-size: 10px; - + --row-1-height: 160px; --row-2-height: 140px; --row-3-height: 140px; - --row-4-height: 250px; + --row-4-height: 280px; } .oc[data-darkmode="true"] { @@ -542,7 +542,8 @@ width: 100%; height: var(--control-height); padding: 5px 12px; - border: 1px solid var(--border-light); + border: 1px solid var(--border-light) !important; + background-color: var(--bg-white) !important; border-radius: var(--radius-sm); background: var(--bg-white); color: var(--text-primary); @@ -713,7 +714,7 @@ } .oc .dashboard-btn { - font-size: 11px !important; + font-size: 12px !important; font-weight: 500 !important; color: white !important; cursor: pointer !important; @@ -877,6 +878,7 @@ display: flex; flex-direction: column; width: 100%; + height: 180px; box-shadow: var(--shadow-sm); transition: all var(--transition-fast); position: relative; @@ -918,12 +920,13 @@ display: flex; flex-direction: column; gap: 10px; + margin: auto 0; } .oc .subscription-progress-bar { background: var(--bg-gray); border-radius: 4px; - height: 10px; + height: 12px; position: relative; overflow: hidden; } @@ -946,6 +949,17 @@ background: var(--error-color); } +.oc .subscription-info-title { + font-size: 15px; + font-weight: 600; + color: var(--text-secondary); + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; +} + .oc .subscription-info-text { font-size: 13px; color: var(--text-secondary); @@ -956,6 +970,69 @@ display: block; } +/* Multiple Providers Grid Layout */ +.oc .subscription-providers-grid { + display: flex; + gap: 12px; + padding: 8px 0; + max-width: 100%; + width: 100%; + overflow-x: auto; + overflow-y: hidden; + scrollbar-width: none; + -ms-overflow-style: none; + cursor: grab; + user-select: none; +} + +.oc .subscription-providers-grid::-webkit-scrollbar { + display: none; +} + +.oc .subscription-providers-grid.dragging { + cursor: grabbing; +} + +.oc .subscription-providers-grid[data-count="1"] { + overflow-x: hidden; +} + +.oc .subscription-providers-grid[data-count="2"], +.oc .subscription-providers-grid[data-count="3"] { + overflow-x: hidden; +} + +.oc .provider-card { + background: transparent; + padding: 0; + transition: all 0.2s ease; + min-width: calc(33.333% - 8px); + flex: 0 0 calc(33.333% - 8px); + box-sizing: border-box; + display: flex; + flex-direction: column; + gap: 6px; +} + +/* For 1-2 providers, allow them to fill available space */ +.oc .subscription-providers-grid[data-count="1"] .provider-card { + min-width: 100%; + flex: 1 1 100%; +} + +.oc .subscription-providers-grid[data-count="2"] .provider-card { + min-width: calc(50% - 6px); + flex: 1 1 calc(50% - 6px); +} + +/* For 3+ providers, fixed 33.333% width */ +/* data-count="3" uses the base rule: flex: 0 0 calc(33.333% - 8px) */ + +/* Dark mode support for provider cards */ +.oc[data-darkmode="true"] .provider-card { + background: transparent; +} + .oc .subscription-loading, .oc .subscription-error, .oc .subscription-no-info { @@ -1200,6 +1277,10 @@ transform: scaleX(-1); } +.oc .hidden { + display: none !important; +} + @media screen and (max-width: 1200px) { .oc .main-cards-container { grid-template-columns: 1fr; @@ -1207,7 +1288,7 @@ max-width: 95%; width: 95%; } - + .oc .announcement-banner { grid-column: 1; width: 80%; @@ -1219,7 +1300,7 @@ width: 100%; max-width: 100%; } - + .oc .main-card { grid-column: 1; grid-template-rows: auto auto auto auto; @@ -1231,7 +1312,7 @@ grid-column: 1; grid-row: 2; } - + .oc .main-card:last-of-type { grid-column: 1; grid-row: 3; @@ -1249,17 +1330,17 @@ min-width: 200px; flex: 1; } - + .oc .config-select { min-width: 200px; font-size: 14px; } - + .oc .config-select option { font-size: 14px; max-width: 100%; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1315,7 +1396,7 @@ padding: 6px 6px; font-size: 11px; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1338,12 +1419,12 @@ font-size: 13px; padding: 4px 10px; } - + .oc .config-select option { font-size: 13px; padding: 6px 10px; } - + .oc .config-selector::after { right: 10px; border-left: 3px solid transparent; @@ -1354,7 +1435,7 @@ .oc .config-subscription-info { margin-left: 12px; } - + .oc .subscription-info-container { padding: 8px; } @@ -1373,16 +1454,24 @@ align-items: stretch; gap: 8px; } - + .oc .config-file-bottom .card-actions { justify-content: center; gap: 5px; } - + .oc .subscription-info-text { font-size: 10px; } + .oc .subscription-info-title { + font-size: 13px; + } + + .oc .subscription-progress-bar { + height: 10px; + } + .oc .file-info { font-size: 10px; } @@ -1397,7 +1486,7 @@ font-size: 14px !important; padding: 0 24px !important; } - + .oc .config-file-empty-message { font-size: 14px; } @@ -1449,7 +1538,7 @@ } .oc .dashboard-btn { - font-size: 8px !important; + font-size: 9px !important; height: 25px !important; } @@ -1474,7 +1563,7 @@ align-items: stretch; gap: 12px; } - + .oc .config-subscription-info { margin-left: 0; justify-content: center; @@ -1483,7 +1572,7 @@ .oc .subscription-info-header { gap: 6px; } - + .oc .file-info { gap: 4px; font-size: 8px; @@ -1493,7 +1582,7 @@ flex-direction: row; gap: 8px; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1505,18 +1594,18 @@ min-width: 110px; flex: 1; } - + .oc .config-select { min-width: 110px; font-size: 12px; padding: 4px 8px; } - + .oc .config-select option { font-size: 12px; padding: 5px 8px; } - + .oc .config-selector::after { right: 8px; } @@ -1548,6 +1637,10 @@ font-size: 10px; } + .oc .subscription-info-title { + font-size: 13px; + } + .oc .config-file-name { font-size: 15px; } @@ -1603,12 +1696,12 @@ font-size: 13px !important; padding: 0 20px !important; } - + .oc .config-file-empty-state { padding: 30px 15px; gap: 15px; } - + .oc .config-file-empty-message { font-size: 13px; } @@ -1673,8 +1766,9 @@
- @@ -1828,10 +1930,10 @@ - <%:Upload Config File%> + <%:Add Config File%>
- +
@@ -1971,13 +2073,22 @@ init: function() { this.applyDarkMode(); }, - + applyDarkMode: function() { var ocContainers = document.querySelectorAll('.oc'); if (!ocContainers.length) return; - var shouldUseDark = isDarkBackground(document.body); - + var theme = localStorage.getItem('oc-theme') || 'auto'; + var shouldUseDark; + + if (theme === 'light') { + shouldUseDark = false; + } else if (theme === 'dark') { + shouldUseDark = true; + } else { + shouldUseDark = isDarkBackground(document.body); + } + ocContainers.forEach(function(ocContainer) { if (shouldUseDark) { ocContainer.setAttribute('data-darkmode', 'true'); @@ -1988,13 +2099,18 @@ var sunIcon = document.getElementById('sun-icon'); var moonIcon = document.getElementById('moon-icon'); - if (sunIcon && moonIcon) { - if (shouldUseDark) { - sunIcon.style.display = 'none'; + var autoIcon = document.getElementById('auto-icon'); + if (sunIcon && moonIcon && autoIcon) { + sunIcon.style.display = 'none'; + moonIcon.style.display = 'none'; + autoIcon.style.display = 'none'; + + if (theme === 'light') { + sunIcon.style.display = 'inline'; + } else if (theme === 'dark') { moonIcon.style.display = 'inline'; } else { - sunIcon.style.display = 'inline'; - moonIcon.style.display = 'none'; + autoIcon.style.display = 'inline'; } } } @@ -2007,7 +2123,7 @@ request_cache: {}, cache_ttl: 5000, pending_requests: new Map(), - + _cachedXHR: function(url, params, callback, force) { var cacheKey = params ? url + JSON.stringify(params) : url; var now = Date.now(); @@ -2026,7 +2142,7 @@ }, 0); return; } - + if (!force && cacheExists && isCacheStale) { setTimeout(function() { callback({ status: 200, fromCache: true, stale: true }, StateManager.request_cache[cacheKey]); @@ -2061,23 +2177,23 @@ cachedXHRGetWithParams: function(url, params, callback, force) { this._cachedXHR(url, params, callback, force); }, - + clearCache: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; delete this.request_cache[cacheKey]; delete this.last_request_time[cacheKey]; }, - + clearAllCache: function() { this.request_cache = {}; this.last_request_time = {}; }, - + hasCache: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; return !!this.request_cache[cacheKey]; }, - + getCacheAge: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; if (!this.last_request_time[cacheKey]) { @@ -2085,13 +2201,12 @@ } return Date.now() - this.last_request_time[cacheKey]; }, - + setCacheTTL: function(ttl) { this.cache_ttl = ttl; }, - + batchUpdateDOM: function(updates) { - var fragment = document.createDocumentFragment(); for (var i = 0; i < updates.length; i++) { var update = updates[i]; if (update.element && update.content !== undefined) { @@ -2099,12 +2214,12 @@ } } }, - + cachedXHRGetWithRetry: function(url, params, callback, force, maxRetries) { maxRetries = maxRetries || 3; var retryCount = 0; var self = this; - + function attemptRequest() { self.cachedXHRGetWithParams(url, params, function(x, data) { if (x && x.status == 200) { @@ -2117,7 +2232,7 @@ } }, force && retryCount === 0); } - + attemptRequest(); } }; @@ -2379,7 +2494,7 @@ currentConfigIndex: -1, selectElement: null, rawCurrentConfig: '', - + init: function() { this.selectElement = document.getElementById('config_file_select'); if (this.selectElement) { @@ -2387,16 +2502,16 @@ this.setupEventListeners(); } }, - + setupEventListeners: function() { if (this.selectElement) { this.selectElement.addEventListener('change', this.onConfigChange.bind(this)); } }, - + loadConfigFileList: function() { this.updateSelectOptions([{value: '', text: '<%:Collecting data...%>', disabled: true}]); - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "config_file_list")%>', function(x, data) { if (x && x.status == 200) { ConfigFileManager.handleConfigListResponse(data); @@ -2405,34 +2520,35 @@ } }, true); }, - + handleConfigListResponse: function(data) { try { var configFiles = []; var currentConfigFile = ''; var currentFileInfo = null; - + if (data.config_files && Array.isArray(data.config_files)) { configFiles = data.config_files; - } else if (data.files && Array.isArray(data.files)) { - configFiles = data.files; + configFiles.sort(function(a, b) { + var nameA = typeof a === 'string' ? a : (a.name || a.filename || a.path || a); + var nameB = typeof b === 'string' ? b : (b.name || b.filename || b.path || b); + return nameA.localeCompare(nameB); + }); } else { - configFiles = data.config_list || []; + configFiles = []; } - + if (data.current_config) { currentConfigFile = data.current_config; - } else if (data.current) { - currentConfigFile = data.current; } - + this.rawCurrentConfig = currentConfigFile; this.configList = configFiles; this.currentConfig = currentConfigFile; this.currentConfigIndex = -1; this.toggleEmptyState(configFiles.length === 0); - + this.updateConfigSelect(configFiles, currentConfigFile); if (configFiles.length > 0) { @@ -2440,7 +2556,7 @@ for (var i = 0; i < configFiles.length; i++) { var file = configFiles[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === currentConfigFile) { this.currentConfigIndex = i; if (typeof file === 'object' && file.mtime && file.size) { @@ -2453,9 +2569,9 @@ } } } - + this.updateSubscriptionDisplay(currentConfigFile, currentFileInfo); - + if (currentConfigFile && SubscriptionManager.currentConfigFile !== currentConfigFile) { SubscriptionManager.currentConfigFile = currentConfigFile; SubscriptionManager.getSubscriptionInfo(); @@ -2464,24 +2580,24 @@ this.hideSubscriptionDisplay(); SubscriptionManager.currentConfigFile = ''; } - + this.updateNavigationArrows(); if (this._retryGetConfigList) { clearInterval(this._retryGetConfigList); this._retryGetConfigList = null; } - + } catch (e) { this.handleConfigListError(); } }, - + handleConfigListError: function() { this.updateSelectOptions([ {value: '', text: '<%:Failed to load config files%>', disabled: true} ]); - + this.toggleEmptyState(true); this.hideSubscriptionDisplay(); @@ -2497,7 +2613,7 @@ var emptyStateElement = document.getElementById('config-file-empty-state'); var configFileBottom = document.querySelector('.config-file-bottom'); var configFileContent = document.querySelector('.config-file-content'); - + if (isEmpty) { if (emptyStateElement) { emptyStateElement.style.display = 'flex'; @@ -2521,17 +2637,17 @@ } } }, - + hideSubscriptionDisplay: function() { var subscriptionDisplay = document.getElementById('subscription-info-display'); if (subscriptionDisplay) { subscriptionDisplay.style.display = 'none'; } }, - + updateConfigSelect: function(configFiles, currentConfig) { var options = []; - + if (!configFiles || configFiles.length === 0) { options.push({ value: '', @@ -2544,10 +2660,10 @@ text: '<%:Please select a config file%>', disabled: false }); - + configFiles.forEach(function(file) { var fileName, filePath; - + if (typeof file === 'string') { fileName = file; filePath = file; @@ -2555,9 +2671,9 @@ fileName = file.name || file.filename || file.path || file; filePath = file.path || file.filepath || file.name || file; } - + var displayName = fileName; - + options.push({ value: filePath, text: displayName, @@ -2566,22 +2682,22 @@ }); }); } - + this.updateSelectOptions(options); }, - + updateSelectOptions: function(options) { if (!this.selectElement) return; - + this.selectElement.innerHTML = ''; - + options.forEach(function(option) { var optionElement = document.createElement('option'); optionElement.value = option.value; optionElement.textContent = option.text; optionElement.disabled = option.disabled || false; optionElement.selected = option.selected || false; - + this.selectElement.appendChild(optionElement); }, this); }, @@ -2591,25 +2707,25 @@ var configNameElement = document.getElementById('current-config-name'); var fileModifyTimeElement = document.getElementById('file-modify-time'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + if (this.configList.length === 0) { container.style.display = 'none'; return; } - + if (!configFile) { container.style.display = 'none'; return; } - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { container.style.display = 'none'; return; } - + container.style.display = 'flex'; if (configNameElement) { @@ -2628,7 +2744,7 @@ configNameElement.title = ''; } } - + if (fileInfo) { if (fileModifyTimeElement) { var modifyTime = this.formatUnixTime(fileInfo.mtime); @@ -2639,7 +2755,7 @@ fileModifyTimeElement.title = ''; } } - + if (detailsSection) { detailsSection.style.display = 'flex'; } @@ -2647,7 +2763,7 @@ if (fileModifyTimeElement) { fileModifyTimeElement.textContent = '<%:Update Time%> --'; } - + if (detailsSection) { detailsSection.style.display = 'none'; } @@ -2658,7 +2774,7 @@ if (!unixTimestamp || unixTimestamp === 0) { return '--'; } - + try { var date = new Date(unixTimestamp * 1000); var year = date.getFullYear(); @@ -2667,7 +2783,7 @@ var hour = String(date.getHours()).padStart(2, '0'); var minute = String(date.getMinutes()).padStart(2, '0'); var second = String(date.getSeconds()).padStart(2, '0'); - + return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second; } catch (e) { return '--'; @@ -2676,51 +2792,51 @@ formatFileSize: function(bytes) { if (!bytes || bytes === 0) return '--'; - + var sizes = ['B', 'KB', 'MB', 'GB', 'TB']; var i = Math.floor(Math.log(bytes) / Math.log(1024)); - + if (i === 0) { return bytes + ' ' + sizes[i]; } - + return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i]; }, - + formatDisplayName: function(fileName) { if (!fileName) return '<%:Unknown%>'; - + var name = fileName.split('/').pop().split('\\').pop(); - + //name = name.replace(/\.(yaml|yml)$/i, ''); - + if (name.length > 30) { name = name.substring(0, 27) + '...'; } - + return name; }, - + onConfigChange: function(event) { var selectedValue = event.target.value; - + if (selectedValue) { this.currentConfig = selectedValue; - + for (var i = 0; i < this.configList.length; i++) { var file = this.configList[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === selectedValue) { this.currentConfigIndex = i; break; } } - + var selectedFileInfo = this.getConfigFileInfo(selectedValue); this.updateSubscriptionDisplay(selectedValue, selectedFileInfo); this.updateNavigationArrows(); - + if (SubscriptionManager.currentConfigFile !== selectedValue) { SubscriptionManager.currentConfigFile = selectedValue; var detailsSection = document.getElementById('subscription-info-details'); @@ -2743,7 +2859,7 @@ for (var i = 0; i < this.configList.length; i++) { var file = this.configList[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === selectedValue) { if (typeof file === 'object' && file.mtime && file.size) { selectedFileInfo = { @@ -2756,54 +2872,54 @@ } return selectedFileInfo; }, - + updateNavigationArrows: function() { var prevArrow = document.getElementById('subscription-prev-arrow'); var nextArrow = document.getElementById('subscription-next-arrow'); - + if (!prevArrow || !nextArrow) return; - + var hasMultipleConfigs = this.configList.length > 1; var currentIndex = this.currentConfigIndex; - + if (!hasMultipleConfigs || currentIndex === -1) { prevArrow.style.display = 'none'; nextArrow.style.display = 'none'; return; } - + prevArrow.style.display = 'block'; nextArrow.style.display = 'block'; - + prevArrow.classList.remove('disabled'); nextArrow.classList.remove('disabled'); }, - + switchToConfigByIndex: function(index) { if (this.configList.length === 0) { return false; } - + if (index < 0) { index = this.configList.length - 1; } else if (index >= this.configList.length) { index = 0; } - + var file = this.configList[index]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (this.selectElement) { this.selectElement.value = filePath; } - + this.currentConfig = filePath; this.currentConfigIndex = index; - + var fileInfo = this.getConfigFileInfo(filePath); this.updateSubscriptionDisplay(filePath, fileInfo); this.updateNavigationArrows(); - + if (SubscriptionManager.currentConfigFile !== filePath) { SubscriptionManager.currentConfigFile = filePath; var detailsSection = document.getElementById('subscription-info-details'); @@ -2812,18 +2928,18 @@ } SubscriptionManager.getSubscriptionInfo(); } - + return true; }, - + refreshConfigList: function() { this.loadConfigFileList(); }, - + getCurrentConfig: function() { return this.currentConfig; }, - + getSelectedConfig: function() { return this.selectElement ? this.selectElement.value : ''; } @@ -2835,17 +2951,17 @@ maxRetries: 5, updateTimer: null, isInitialized: false, - + init: function() { if (this.isInitialized) return; this.isInitialized = true; - + setTimeout(function() { SubscriptionManager.loadSubscriptionInfo(); SubscriptionManager.startAutoUpdate(); }, 500); }, - + loadSubscriptionInfo: function() { var currentConfig = ConfigFileManager.getCurrentConfig() || ConfigFileManager.getSelectedConfig(); if (currentConfig && currentConfig !== this.currentConfigFile) { @@ -2853,21 +2969,21 @@ this.getSubscriptionInfo(); } }, - + getSubscriptionInfo: function() { if (ConfigFileManager.configList.length === 0) { return; } - + if (!this.currentConfigFile) return; - + var requestConfigFile = this.currentConfigFile; var filename = this.extractFilename(this.currentConfigFile); if (!filename) return; - + var cachedData = localStorage.getItem('sub_info_' + filename); var shouldFetchNew = true; - + if (cachedData) { try { var parsedData = JSON.parse(cachedData); @@ -2881,13 +2997,13 @@ this.showNoInfo(); } } - + if (parsedData.get_time) { var currentTime = Math.floor(Date.now() / 1000); var cacheTime = parseInt(parsedData.get_time); var timeDiff = currentTime - cacheTime; var halfHourInSeconds = 30 * 60; - + if (timeDiff <= halfHourInSeconds) { shouldFetchNew = false; } @@ -2896,8 +3012,10 @@ shouldFetchNew = true; } } - + if (shouldFetchNew) { + this.showLoading(); + StateManager.cachedXHRGetWithParams('<%=luci.dispatcher.build_url("admin", "services", "openclash", "sub_info_get")%>', {filename: filename}, function(x, status) { if (SubscriptionManager.currentConfigFile !== requestConfigFile) { return; @@ -2916,18 +3034,16 @@ }, true); } }, - + displaySubscriptionInfo: function(data) { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - var progressFill = document.getElementById('subscription-progress-fill'); - var infoText = document.getElementById('subscription-info-text'); - + if (!container) return; var configFileContent = document.querySelector('.config-file-content'); @@ -2936,101 +3052,241 @@ } container.style.display = 'flex'; - + if (data && data.sub_info && data.sub_info !== "No Sub Info Found") { - if (progressSection) { - progressSection.style.display = 'flex'; - } - - if (!progressFill || !infoText) return; - - var percent = data.percent || 0; - var used = data.surplus || data.used || '0 B'; - var total = data.total || '0 B'; - var expire = data.expire || ''; - var daysLeft = data.day_left || 0; - - progressFill.style.width = percent + '%'; - progressFill.className = 'subscription-progress-fill ' + - (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); - - var infoString = used + ' / ' + total + ' (' + percent + '%)'; - if (expire && daysLeft > 0) { - infoString += ' • ' + '<%:Remaining%> ' + daysLeft + ' <%:days%>'; - infoString += ' • ' + '<%:Expire Date%>: ' + expire; - } - - infoText.textContent = infoString; - if (infoText.scrollWidth > infoText.clientWidth) { - infoText.title = infoString; + if (data.providers && Array.isArray(data.providers) && data.providers.length > 0) { + if (data.providers.length > 1 || data.providers[0].provider_name) { + this.displayMultipleProviders(data.providers, progressSection); + } else { + this.displaySingleProvider(data.providers[0], progressSection); + } } else { - infoText.title = ''; - } - - } else { - if (progressSection) { progressSection.style.display = 'none'; } + } else { + progressSection.style.display = 'none'; } - + if (detailsSection) { detailsSection.style.display = 'flex'; } }, - + + displaySingleProvider: function(provider, progressSection) { + if (!progressSection) return; + + progressSection.innerHTML = ''; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; + + var progressBar = document.createElement('div'); + progressBar.className = 'subscription-progress-bar'; + + progressFill = document.createElement('div'); + progressFill.className = 'subscription-progress-fill'; + progressBar.appendChild(progressFill); + + infoText = document.createElement('div'); + infoText.className = 'subscription-info-text'; + + progressSection.appendChild(progressBar); + progressSection.appendChild(infoText); + + var percent = parseFloat(provider.percent) || 0; + var used = String(provider.surplus || provider.used || '0 B'); + var total = String(provider.total || '0 B'); + var expire = String(provider.expire || ''); + var daysLeft = parseInt(provider.day_left, 10); + if (isNaN(daysLeft)) daysLeft = 0; + + progressFill.style.width = percent + '%'; + progressFill.className = 'subscription-progress-fill ' + + (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); + + var infoString = used + ' / ' + total + ' (' + percent + '%)'; + var tooltipString = infoString; + if (expire && expire !== 'null' && daysLeft > 0) { + infoString += ' • ' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + tooltipString += '\n' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + infoText.textContent = infoString; + infoText.title = tooltipString; + }, + + displayMultipleProviders: function(providers, progressSection) { + if (!progressSection) return; + + var displayProviders = providers; + var providerCount = displayProviders.length; + + progressSection.innerHTML = ''; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-providers-grid'; + progressSection.setAttribute('data-count', providerCount); + + displayProviders.forEach(function(provider) { + var card = document.createElement('div'); + card.className = 'provider-card'; + + var cardName = document.createElement('div'); + var providerName = String(provider.provider_name || 'Unknown'); + cardName.className = 'subscription-info-title'; + cardName.textContent = providerName; + cardName.title = providerName; + card.appendChild(cardName); + + var progressBar = document.createElement('div'); + progressBar.className = 'subscription-progress-bar'; + + var progressFill = document.createElement('div'); + var percent = parseFloat(provider.percent) || 0; + progressFill.style.width = percent + '%'; + progressFill.className = 'subscription-progress-fill ' + + (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); + + progressBar.appendChild(progressFill); + card.appendChild(progressBar); + + var infoText = document.createElement('div'); + infoText.className = 'subscription-info-text'; + + var used = String(provider.used || '0 B'); + var total = String(provider.total || 'N/A'); + var expire = String(provider.expire || ''); + var daysLeft = parseInt(provider.day_left, 10); + if (isNaN(daysLeft)) daysLeft = 0; + + var infoString = used + ' / ' + total + ' (' + percent + '%)'; + if (expire && expire !== 'null' && daysLeft > 0) { + infoString += ' • ' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + var tooltipString = used + ' / ' + total + ' (' + percent + '%)'; + if (expire && expire !== 'null' && daysLeft > 0) { + tooltipString += '\n' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + infoText.textContent = infoString; + infoText.title = tooltipString; + + card.appendChild(infoText); + progressSection.appendChild(card); + }); + + if (providerCount > 3) { + this.initDragScroll(progressSection); + } + }, + + initDragScroll: function(element) { + var isDragging = false; + var startX; + var scrollLeft; + var hasMoved = false; + + var onMouseDown = function(e) { + if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { + return; + } + + isDragging = true; + hasMoved = false; + startX = e.pageX - element.offsetLeft; + scrollLeft = element.scrollLeft; + element.classList.add('dragging'); + }; + + var onMouseMove = function(e) { + if (!isDragging) return; + + var x = e.pageX - element.offsetLeft; + var walk = (x - startX) * 1.5; + + if (Math.abs(walk) > 5) { + hasMoved = true; + e.preventDefault(); + element.scrollLeft = scrollLeft - walk; + } + }; + + var onMouseUp = function() { + isDragging = false; + element.classList.remove('dragging'); + }; + + var onMouseLeave = function() { + if (isDragging) { + isDragging = false; + element.classList.remove('dragging'); + } + }; + + element.addEventListener('mousedown', onMouseDown); + element.addEventListener('mousemove', onMouseMove); + element.addEventListener('mouseup', onMouseUp); + element.addEventListener('mouseleave', onMouseLeave); + + element.addEventListener('dragstart', function(e) { + e.preventDefault(); + }); + }, + showNoInfo: function() { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { return; } - + container.style.display = 'flex'; - + if (progressSection) { - progressSection.style.display = 'none'; + progressSection.innerHTML = '
<%:No Sub Info Found%>
'; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; } - + if (detailsSection) { var fileModifyTimeElement = document.getElementById('file-modify-time'); - + var hasFileInfo = false; if (fileModifyTimeElement) { var modifyTimeText = fileModifyTimeElement.textContent || ''; hasFileInfo = !modifyTimeText.includes('--'); } - + detailsSection.style.display = hasFileInfo ? 'flex' : 'none'; } }, - + showError: function() { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { return; } - + container.style.display = 'flex'; - + if (progressSection) { progressSection.style.display = 'none'; } @@ -3038,7 +3294,36 @@ detailsSection.style.display = 'none'; } }, - + + showLoading: function() { + if (ConfigFileManager.configList.length === 0) { + return; + } + + var container = document.getElementById('subscription-info-display'); + var progressSection = document.getElementById('subscription-progress-section'); + var detailsSection = document.getElementById('subscription-info-details'); + + if (!container) return; + + var configFileContent = document.querySelector('.config-file-content'); + if (configFileContent && configFileContent.classList.contains('empty-state')) { + return; + } + + container.style.display = 'flex'; + + if (progressSection) { + progressSection.innerHTML = '
<%:Collecting data...%>
'; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; + } + + if (detailsSection) { + detailsSection.style.display = 'none'; + } + }, + handleError: function() { if (this.retryCount >= this.maxRetries) { this.showError(); @@ -3053,32 +3338,32 @@ }, 5000); } }, - + extractFilename: function(path) { if (!path) return ''; var parts = path.split('/'); var filename = parts[parts.length - 1]; - + if (filename.endsWith('.yaml')) { filename = filename.slice(0, -5); } else if (filename.endsWith('.yml')) { filename = filename.slice(0, -4); } - + return filename; }, - + startAutoUpdate: function() { if (this.updateTimer) { clearTimeout(this.updateTimer); } - + this.updateTimer = setTimeout(function() { SubscriptionManager.getSubscriptionInfo(); SubscriptionManager.startAutoUpdate(); }, 60000 * 15); }, - + stopAutoUpdate: function() { if (this.updateTimer) { clearTimeout(this.updateTimer); @@ -3090,7 +3375,7 @@ var LogManager = { isPolling: false, pollTimer: null, - maxPollTime: 15000, + maxPollTime: 60000, pollInterval: 1000, startTime: 0, lastLogContent: '', @@ -3113,12 +3398,12 @@ DOMCache.oclog.style.display = 'inline-flex'; DOMCache.oclog.innerHTML = '' + (initialMessage || '<%:Processing...%>') + ''; } - + this.isPolling = true; this.startTime = Date.now(); this.lastLogContent = ''; this.retryCount = 0; - + var self = this; setTimeout(function() { if (self.isPolling) { @@ -3126,7 +3411,7 @@ } }, 2000); }, - + stopLogDisplay: function() { this.isPolling = false; if (this.pollTimer) { @@ -3143,15 +3428,15 @@ }, 1000); } }, - + pollLog: function() { if (!this.isPolling) return; - + if (Date.now() - this.startTime > this.maxPollTime) { this.stopLogDisplay(); return; } - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "startlog")%>', function(x, status) { if (!self.isPolling) return; @@ -3175,7 +3460,7 @@ }, 3000); return; } - + if (logContent !== '') { self.retryCount = 0; self.scheduleNextPoll(self.pollInterval); @@ -3208,12 +3493,12 @@ self.pollLog(); }, delay); }, - + checkForErrors: function(log) { if (!log) return false; if (log.match(/level=fatal|level=error|FTL \[Config]/)) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "del_start_log")%>', null, function(x) {}); - + var errorMsg; if (log.match(/level=(fatal|error)/)) { var msgParts = log.split('msg='); @@ -3222,32 +3507,32 @@ var ftlParts = log.split('FTL [Config] '); errorMsg = ftlParts.length > 1 ? ftlParts[1] : log; } - + setTimeout(function() { alert('<%:OpenClash Start Failed%>:\n\n' + errorMsg); }, 500); - + return true; } return false; }, - + displayLog: function(logContent) { if (!this.isPolling || !DOMCache.oclog) return; - + var cleanLog = this.cleanLogContent(logContent); this.lastLogContent = cleanLog; var color = this.getLogColor(cleanLog); var displayText = this.formatLogText(cleanLog); - + DOMCache.oclog.innerHTML = '' + displayText + ''; }, - + cleanLogContent: function(content) { return content ? content.replace(/[\r\n]+/g, ' ').replace('##FINISH##', '').trim() : ''; }, - + getLogColor: function(log) { if (log.includes("Tip:") || log.includes("提示:")) { return 'var(--warning-color)'; @@ -3263,22 +3548,22 @@ return 'var(--text-secondary)'; } }, - + formatLogText: function(log) { if (!log) return '<%:Processing...%>'; - + var cleanText = log.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[.\d]*Z?\s*/, '') .replace(/^time="[^"]*"\s*/, '') .replace(/^level=\w+\s*/, '') .replace(/^msg="?([^"]*)"?\s*/, '$1'); - + if (cleanText.length > 60) { cleanText = cleanText.substring(0, 57) + '...'; } - + return this.escapeHtml(cleanText) || '<%:Processing...%>'; }, - + escapeHtml: function(text) { var div = document.createElement('div'); div.textContent = text; @@ -3292,14 +3577,14 @@ retryCount: 0, maxRetries: 3, isEnabled: false, - + start: function() { if (this.isEnabled) return; this.isEnabled = true; this.retryCount = 0; this.poll(); }, - + stop: function() { this.isEnabled = false; if (this.pollTimer) { @@ -3307,10 +3592,10 @@ this.pollTimer = null; } }, - + poll: function() { if (!this.isEnabled) return; - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "toolbar_show_sys")%>', function(x, status) { if (x && x.status == 200 && x.responseText != "") { @@ -3318,14 +3603,14 @@ var cpuColor = status.cpu <= 50 ? "var(--success-color)" : (status.cpu <= 80 ? "var(--warning-color)" : "var(--error-color)"); var cpuValue = status.cpu <= 100 ? status.cpu + " %" : "0 %"; document.getElementById("cpu_t").innerHTML = ""+cpuValue+""; - + var loadValue = parseFloat(status.load_avg) || 0; var loadColor = loadValue <= 50 ? "var(--success-color)" : (loadValue <= 80 ? "var(--warning-color)" : "var(--error-color)"); document.getElementById("load_a").innerHTML = ""+status.load_avg+" %"; } else { self.handleError(); } - + if (self.isEnabled) { self.pollTimer = setTimeout(function() { self.poll(); @@ -3333,17 +3618,17 @@ } }, true); }, - + handleError: function() { this.retryCount++; - + if (this.retryCount >= this.maxRetries) { document.getElementById("cpu_t").innerHTML = "0 %"; document.getElementById("load_a").innerHTML = "0 %"; this.retryCount = 0; } }, - + setPollInterval: function(interval) { this.pollInterval = interval; } @@ -3355,14 +3640,14 @@ retryCount: 0, maxRetries: 3, isEnabled: false, - + start: function() { if (this.isEnabled) return; this.isEnabled = true; this.retryCount = 0; this.poll(); }, - + stop: function() { this.isEnabled = false; if (this.pollTimer) { @@ -3370,10 +3655,10 @@ this.pollTimer = null; } }, - + poll: function() { if (!this.isEnabled) return; - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "toolbar_show")%>', function(x, status) { if (x && x.status == 200 && x.responseText != "") { @@ -3382,7 +3667,7 @@ } else { self.handleError(); } - + if (self.isEnabled) { self.pollTimer = setTimeout(function() { self.poll(); @@ -3390,7 +3675,7 @@ } }, true); }, - + updateNetworkStats: function(status) { var updates = [ {element: document.getElementById("upload_"), content: ""+status.up+""}, @@ -3400,23 +3685,23 @@ {element: document.getElementById("mem_t"), content: ""+status.mem+""}, {element: document.getElementById("connect_t"), content: ""+status.connections+""} ]; - + if (!SystemStatusManager.isEnabled) { var cpuColor = status.cpu <= 50 ? "var(--success-color)" : (status.cpu <= 80 ? "var(--warning-color)" : "var(--error-color)"); var cpuValue = status.cpu <= 100 ? status.cpu + " %" : "0 %"; updates.push({element: document.getElementById("cpu_t"), content: ""+cpuValue+""}); - + var loadValue = parseFloat(status.load_avg) || 0; var loadColor = loadValue <= 50 ? "var(--success-color)" : (loadValue <= 80 ? "var(--warning-color)" : "var(--error-color)"); updates.push({element: document.getElementById("load_a"), content: ""+status.load_avg+" %"}); } - + StateManager.batchUpdateDOM(updates); }, - + handleError: function() { this.retryCount++; - + if (this.retryCount >= this.maxRetries) { var fallbackUpdates = [ {element: document.getElementById("upload_"), content: "0 B/S"}, @@ -3426,17 +3711,17 @@ {element: document.getElementById("mem_t"), content: "0 KB"}, {element: document.getElementById("connect_t"), content: "0"} ]; - + if (!SystemStatusManager.isEnabled) { fallbackUpdates.push({element: document.getElementById("cpu_t"), content: "0 %"}); fallbackUpdates.push({element: document.getElementById("load_a"), content: "0 %"}); } - + StateManager.batchUpdateDOM(fallbackUpdates); this.retryCount = 0; } }, - + setPollInterval: function(interval) { this.pollInterval = interval; } @@ -3445,18 +3730,18 @@ var SettingsManager = { pendingOperations: new Set(), pausedPolls: new Set(), - + pausePoll: function(pollName, duration) { this.pausedPolls.add(pollName); setTimeout(() => { this.pausedPolls.delete(pollName); }, duration || 3000); }, - + isPollPaused: function(pollName) { return this.pausedPolls.has(pollName); }, - + updateUIState: function(setting, value) { setTimeout(() => { function setCheckedAndDisabled(elements, checkedIndex) { @@ -3532,7 +3817,7 @@ } }, 10); }, - + switchSetting: function(setting, value, endpoint, additionalParams) { var operationKey = setting + '_' + value; @@ -3627,7 +3912,7 @@ return false; }, - + getErrorMessage: function(setting) { var messages = { 'meta_sniffer': '<%:Sniffer setting failed%>', @@ -3665,20 +3950,20 @@ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) { if (x && x.status == 200) { var updates = []; - + if (!pluginToggleUserAction) { updates.push({ element: DOMCache.clash, content: status.clash ? '' + status.core_type +' <%:Running%>' : '<%:Not Running%>' }); - + updatePluginToggleState(status.clash); } get_run_mode(); get_rule_mode(); get_oc_settings(); - + var webContent = status.clash ? '' : ''; updates.push({element: DOMCache.web, content: webContent}); @@ -3698,7 +3983,7 @@ var reloadFwContent = status.clash ? '' : ''; updates.push({element: document.getElementById('_reload_firewall_btn'), content: reloadFwContent}); - var flushCacheContent = status.clash ? '' : ''; + var flushCacheContent = status.clash ? '' : ''; updates.push({element: document.getElementById('_flush_dns_cache_btn'), content: flushCacheContent}); var oneKeyUpdateContent = ''; @@ -3706,11 +3991,19 @@ StateManager.batchUpdateDOM(updates); + if (!status.yacd) { + DOMCache.web.classList.add('hidden'); + } + + if (!status.dashboard) { + DOMCache.webo.classList.add('hidden'); + } + StateManager.current_status = status; - + if (status.daip) { var daipContent, dapoContent; - + if (status.daip && window.location.hostname == status.daip) { dapoContent = status.cn_port ? ":"+status.cn_port : ""; daipContent = status.daip ? ""+status.daip+dapoContent+"" : ""+"<%:Not Set%>"+""; @@ -3721,7 +4014,7 @@ dapoContent = status.cn_port ? ":"+status.cn_port : ""; daipContent = status.daip ? ""+status.daip+dapoContent+"" : ""+"<%:Not Set%>"+""; } - + DOMCache.daip.innerHTML = daipContent; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "proxy_info")%>', function(x, proxy_info) { @@ -3745,7 +4038,7 @@ DOMCache.copy_mix_secret.style.display = "none"; DOMCache.copy_pac_config.style.display = "none"; } - + if (status.clash && status.daip) { if (!WSManager.hasActiveConnections()) { if (!WSManager._ws_error || WSManager._ws_retry < 3) { @@ -3759,7 +4052,7 @@ if (NetworkStatsManager && NetworkStatsManager.isEnabled) { NetworkStatsManager.stop(); } - + if (SystemStatusManager && !SystemStatusManager.isEnabled) { SystemStatusManager.start(); } @@ -3783,10 +4076,10 @@ if (!status || !status.clash || !status.daip) { return false; } - + var protocol = getWebSocketProtocol(status); var token = status.dase; - + var connections = [ { type: 'traffic', @@ -3804,19 +4097,19 @@ handler: ws_mmessage } ]; - + connections.forEach(function(conn) { var url = protocol + conn.endpoint + (token ? '?token=' + token : ''); WSManager.createConnection(conn.type, url, conn.handler); }); - + return true; } function getWebSocketProtocol(status) { var protocol = window.location.protocol === "https:" ? "wss://" : "ws://"; var host, port; - + if (status.daip && window.location.hostname === status.daip) { host = status.daip; port = status.cn_port; @@ -3828,14 +4121,14 @@ host = status.daip; port = status.cn_port; } - + return protocol + host + ":" + port; } function loadAnnouncement() { var userLang = navigator.language || navigator.userLanguage; var isChineseUser = userLang.indexOf('zh') === 0; - + var tips = [ '<%:Tip: You can modify the profile on the profile page (for content that is not taken over)%>', '<%:Tip: do not write configuration files? Try to create one click on the server page%>', @@ -3850,14 +4143,14 @@ '<%:Note: Some software will modify the device HOSTS, which will cause abnormal shunt, please pay attention to check%>', '<%:Note: The default proxy routes local traffic, BT, PT download, etc., please use Redir-Host mode as much as possible and pay attention to traffic avoidance%>' ]; - + function calculateAnimationDuration(bannerWidth, contentWidth) { var screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var refreshRate = window.screen && window.screen.refreshRate ? window.screen.refreshRate : 60; if (refreshRate <= 0) refreshRate = 60; - + if (refreshRate > 480) refreshRate = 480; - + var baseDuration; if (screenWidth <= 575) { baseDuration = 12000; @@ -3868,27 +4161,27 @@ } else { baseDuration = 9000; } - + var refreshRateMultiplier = 1; if (refreshRate > 60) { refreshRateMultiplier = 1 + (refreshRate - 60) / 240; } - + var duration = baseDuration * refreshRateMultiplier; - + return Math.max(4000, Math.min(duration, 18000)); } - + function updateScrollAnimation(banner, content, duration) { var bannerWidth = banner.offsetWidth; var contentWidth = content.offsetWidth; var scrollDistance = -(contentWidth + bannerWidth); - + banner.style.setProperty('--scroll-distance', scrollDistance + 'px'); - + content.style.animationDuration = duration + 'ms'; } - + function getRandomTips(count) { var shuffled = tips.slice(); for (var i = shuffled.length - 1; i > 0; i--) { @@ -3899,11 +4192,11 @@ } return shuffled.slice(0, count); } - + function updateIcon(isRandomTips) { var megaphoneElement = document.getElementById('megaphone'); if (!megaphoneElement) return; - + if (isRandomTips) { megaphoneElement.innerHTML = ''; megaphoneElement.setAttribute('viewBox', '0 0 256 256'); @@ -3913,22 +4206,22 @@ megaphoneElement.setAttribute('viewBox', '0 0 256 256'); } } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "announcement")%>', function(x, status) { var banner = document.getElementById('announcement-banner'); var content = document.getElementById('announcement-content'); var announcements = []; var isRandomTips = false; - + if (!banner || !content) return; - + if (x && x.status == 200 && status.content) { try { var contentData = status.content; if (typeof contentData === 'string') { contentData = JSON.parse(contentData); } - + if (Array.isArray(contentData)) { if (contentData.length > 0 && (contentData[0].zh || contentData[0].en)) { contentData.forEach(function(item) { @@ -3954,20 +4247,20 @@ } } } - + if (announcements.length === 0) { announcements = getRandomTips(3); isRandomTips = true; } - + updateIcon(isRandomTips); banner.style.display = 'block'; - + var currentIndex = 0; var isHovered = false; var pauseTimeout = null; var nextAnimationTimeout = null; - + banner.addEventListener('mouseenter', function() { isHovered = true; content.classList.add('paused'); @@ -3976,7 +4269,7 @@ isHovered = false; content.classList.remove('paused'); }); - + var resizeTimeout; window.addEventListener('resize', function() { clearTimeout(resizeTimeout); @@ -3987,50 +4280,50 @@ } }, 250); }); - + function startScrollAnimation() { if (nextAnimationTimeout) { clearTimeout(nextAnimationTimeout); nextAnimationTimeout = null; } - + content.textContent = announcements[currentIndex]; - + setTimeout(function() { var duration = calculateAnimationDuration(banner.offsetWidth, content.offsetWidth); updateScrollAnimation(banner, content, duration); - + content.classList.remove('scrolling'); content.offsetHeight; content.classList.add('scrolling'); - + var onAnimationEnd = function(e) { if (e.target === content && e.animationName === 'announceScroll') { content.removeEventListener('animationend', onAnimationEnd); - + pauseTimeout = setTimeout(function() { if (!isHovered) { currentIndex = (currentIndex + 1) % announcements.length; - + if (isRandomTips && currentIndex === 0) { announcements = getRandomTips(3); } - + startScrollAnimation(); } }, 2000); } }; - + content.addEventListener('animationend', onAnimationEnd); - + }, 50); } - + setTimeout(function() { startScrollAnimation(); }, 300); - + window.addEventListener('beforeunload', function() { if (pauseTimeout) clearTimeout(pauseTimeout); if (nextAnimationTimeout) clearTimeout(nextAnimationTimeout); @@ -4042,7 +4335,7 @@ if (SettingsManager.isPollPaused('rule_mode')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "rule_mode")%>', function(x, status) { if (x && x.status == 200 && status.mode != "") { if (!SettingsManager.pendingOperations.has('rule_mode_' + status.mode)) { @@ -4064,12 +4357,12 @@ '<%=luci.dispatcher.build_url("admin", "services", "openclash", "switch_rule_mode")%>' ); } - + function get_run_mode() { if (SettingsManager.isPollPaused('run_mode')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "get_run_mode")%>', function(x, status) { if (x && x.status == 200 && status.mode) { if (status.mode == "fake-ip" || status.mode == "fake-ip-tun" || status.mode == "fake-ip-mix") { @@ -4079,10 +4372,10 @@ DOMCache.mode.innerHTML = "<%:Redir-Host%>"; DOMCache.radio_run_normal.innerHTML = "<%:Compat%>"; } - + var expectedValue = status["mode"].split("-")[2] == undefined ? "" : ("-" + status["mode"].split("-")[2]); var operationKey = 'run_mode_' + status.mode; - + if (!SettingsManager.pendingOperations.has(operationKey)) { for (var i = 0; i < DOMCache.radio_ru.length; i++) { if (DOMCache.radio_ru[i].value == expectedValue && !DOMCache.radio_ru[i].checked) { @@ -4109,10 +4402,10 @@ window.location.href = url; } } - + function ws_terror() { WSManager._ws_error = true; - + NetworkStatsManager.start(); } @@ -4133,7 +4426,7 @@ uploadElement.innerHTML = data.up ? ""+bytesToSize(data.up)+"/S" : "0 B/S"; downloadElement.innerHTML = data.down ? ""+bytesToSize(data.down)+"/S" : "0 B/S"; } - + function ws_cmessage(event) { var dataObj = event && event.data !== undefined ? event.data : event; var data; @@ -4203,14 +4496,14 @@ return false; }; } - + var all_one_key_update = debounceButton(function(btn) { btn.value = '<%:Check Update%>'; btn.disabled = false; select_git_cdn(); return false; }); - + var b_flush_dns_cache = debounceButton(function(btn) { btn.disabled = true; btn.value = '<%:Flushing...%> '; @@ -4224,7 +4517,7 @@ btn.disabled = false; return false; }); - + var b_reload_firewall = debounceButton(function(btn) { btn.disabled = true; btn.value = '<%:Reloading...%>'; @@ -4245,7 +4538,7 @@ }); return false; }); - + function net_zashboard(btn) { if (StateManager.current_status) { var status = StateManager.current_status; @@ -4320,7 +4613,7 @@ winOpen(url1); return false; } - + function net_dashboard(btn) { if (StateManager.current_status) { var status = StateManager.current_status; @@ -4345,12 +4638,12 @@ winOpen(url2); return false; } - + function homepage() { url3 = 'https://github.com/vernesong/OpenClash'; winOpen(url3); } - + function gitbookpage() { url8 = 'https://wiki.metacubex.one'; winOpen(url8); @@ -4360,12 +4653,12 @@ url5 = 'https://github.com/vernesong/OpenClash/wiki'; winOpen(url5); } - + function telegrampage() { url6 = 'https://t.me/ctcgfw_openwrt_discuss'; winOpen(url6); } - + function sponsorpage() { url7 = 'https://ko-fi.com/vernesong'; winOpen(url7); @@ -4381,11 +4674,11 @@ if (!v1 || !v2) return 0; var ver1 = v1.replace(/^v/, '').split('.'); var ver2 = v2.replace(/^v/, '').split('.'); - + var maxLen = Math.max(ver1.length, ver2.length); while (ver1.length < maxLen) ver1.push('0'); while (ver2.length < maxLen) ver2.push('0'); - + for (var i = 0; i < maxLen; i++) { var num1 = parseInt(ver1[i], 10) || 0; var num2 = parseInt(ver2[i], 10) || 0; @@ -4404,7 +4697,7 @@ if (status.corelv && status.corelv !== "" && status.corelv !== "loading..." && status.corelv !== status.coremetacv) { hasUpdate = true; } - + DOMCache.core_version_text.textContent = coreVersionText; if (DOMCache.core_version_text.scrollWidth > DOMCache.core_version_text.clientWidth) { DOMCache.core_version_text.title = coreVersionText; @@ -4412,12 +4705,12 @@ DOMCache.core_version_text.title = ''; } DOMCache.core_version_display.style.display = 'flex'; - + var existingDot = DOMCache.core_version_display.querySelector('.update-dot'); if (existingDot) { existingDot.remove(); } - + if (hasUpdate) { var updateDot = document.createElement('span'); updateDot.className = 'update-dot'; @@ -4431,17 +4724,17 @@ DOMCache.core_version_display.style.display = 'none'; DOMCache.core_version_display.title = ''; } - + if (status.opcv && status.opcv !== "0") { var pluginVersionText = status.opcv; var hasUpdate = false; - + if (status.oplv && status.oplv !== "" && status.oplv !== "loading...") { if (compareVersions(status.oplv, status.opcv) > 0) { hasUpdate = true; } } - + DOMCache.plugin_version_text.textContent = pluginVersionText; if (DOMCache.plugin_version_text.scrollWidth > DOMCache.plugin_version_text.clientWidth) { DOMCache.plugin_version_text.title = pluginVersionText; @@ -4449,12 +4742,12 @@ DOMCache.plugin_version_text.title = ''; } DOMCache.plugin_version_display.style.display = 'flex'; - + var existingDot = DOMCache.plugin_version_display.querySelector('.update-dot'); if (existingDot) { existingDot.remove(); } - + if (hasUpdate) { var updateDot = document.createElement('span'); updateDot.className = 'update-dot'; @@ -4475,7 +4768,7 @@ function logo_error(imgobj, imgSrc) { imgobj.src = imgSrc; } - + function imgerrorfuns(imgobj, imgSrc) { setTimeout(function() { imgobj.src = imgSrc; @@ -4511,7 +4804,7 @@ function copyAddress() { var status = StateManager.current_status; var address; - + if (status.daip && window.location.hostname == status.daip) { address = 'http://' + status.daip + ':' + (status.cn_port || '9090') + '/ui/zashboard/#/setup?hostname=' + status.daip + '&port=' + (status.cn_port || '9090') + (status.dase ? '&secret=' + status.dase : ''); } else if (status.daip && window.location.hostname != status.daip && status.db_foward_domain && status.db_foward_port) { @@ -4520,7 +4813,7 @@ } else { address = 'http://' + (status.daip || 'unknown') + ':' + (status.cn_port || '9090') + '/ui/zashboard/#/'; } - + copyToClipboard(address, '<%:Control panel address copied:%> '); return false; } @@ -4565,19 +4858,19 @@ if (SettingsManager.isPollPaused('oc_settings')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "oc_settings")%>', function(x, info) { if (x && x.status == 200) { if (!SettingsManager.pendingOperations.has('meta_sniffer_' + info.meta_sniffer)) { DOMCache.meta_sniffer_on.checked = info.meta_sniffer == "1"; DOMCache.meta_sniffer_off.checked = info.meta_sniffer != "1"; } - + if (!SettingsManager.pendingOperations.has('respect_rules_' + info.respect_rules)) { DOMCache.respect_rules_on.checked = info.respect_rules == "1"; DOMCache.respect_rules_off.checked = info.respect_rules != "1"; } - + if (!SettingsManager.pendingOperations.has('oversea_' + info.oversea)) { if (info.oversea == "0") { DOMCache.oc_setting_oversea_0.checked = true; @@ -4638,7 +4931,7 @@ port: window.location.port, href: window.location.href }; - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "generate_pac")%>', { client_protocol: currentUrl.protocol.replace(':', ''), client_hostname: currentUrl.hostname, @@ -4681,15 +4974,15 @@ textArea.style.left = "0"; textArea.style.position = "fixed"; textArea.style.opacity = "0"; - + document.body.appendChild(textArea); textArea.focus(); textArea.select(); - + try { var successful = document.execCommand('copy'); document.body.removeChild(textArea); - + if (successful) { prompt(successMessage, text); } else { @@ -4703,7 +4996,7 @@ function togglePlugin(toggleElement) { var isEnabled = toggleElement.checked; - + if (isEnabled) { var currentConfig = ConfigFileManager.getCurrentConfig() || ConfigFileManager.getSelectedConfig(); if (!currentConfig) { @@ -4717,29 +5010,29 @@ pluginToggleUserAction = true; var action = isEnabled ? 'start' : 'stop'; var initialMessage = isEnabled ? '<%:Starting...%>' : '<%:Stopping...%>'; - + LogManager.startLogDisplay(initialMessage); - + var requestParams = { action: action }; - + if (isEnabled) { var currentConfig = ConfigFileManager.getCurrentConfig(); var selectedConfig = ConfigFileManager.getSelectedConfig(); - + if (!currentConfig && selectedConfig) { requestParams.config_file = configFileName; } } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "action")%>', requestParams, function(x, status) { if (x && x.status == 200) { setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 3000); + }, 2000); } else { toggleElement.checked = !isEnabled; - + var errorMessage = isEnabled ? '<%:Failed to start OpenClash%>' : '<%:Failed to stop OpenClash%>'; @@ -4748,7 +5041,7 @@ if (DOMCache.clash) { DOMCache.clash.innerHTML = '<%:Operation Failed%>'; } - + pluginToggleUserAction = false; } toggleElement.disabled = false; @@ -4759,22 +5052,22 @@ if (pluginToggleUserAction) { return; } - + var toggleElement = document.getElementById('plugin_toggle'); if (toggleElement) { toggleElement.checked = isRunning; toggleElement.disabled = false; - + if (DOMCache.clash && StateManager.current_status) { DOMCache.clash.innerHTML = isRunning ? '' + StateManager.current_status.core_type +' <%:Running%>' : '<%:Not Running%>'; } - + if (!isRunning && StateManager.current_status && !StateManager.current_status.clash) { setTimeout(function() { updatePluginToggleState(StateManager.current_status.clash || false); - }, 3000); + }, 2000); } } } @@ -4785,11 +5078,11 @@ alert('<%:Please select a config file first%>'); return false; } - + pluginToggleUserAction = true; - + LogManager.startLogDisplay('<%:Switching Config...%>'); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "switch_config")%>', { config_file: currentConfig }, function(x, status) { @@ -4798,28 +5091,28 @@ setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 4000); + }, 2000); } else { alert('<%:Failed to switch config file:%> ' + (status.message || '<%:Unknown error%>')); - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Switch Failed%>'; } - + pluginToggleUserAction = false; } }); return false; } - + function updateConfig() { var currentConfig = ConfigFileManager.getSelectedConfig(); if (!currentConfig) { alert('<%:Please select a config file first%>'); return false; } - + var filename = SubscriptionManager.extractFilename(currentConfig); if (!filename) { alert('<%:Invalid config file selected%>'); @@ -4827,7 +5120,7 @@ } pluginToggleUserAction = true; - + LogManager.startLogDisplay('<%:Updating Config...%>'); XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_config")%>', { @@ -4836,30 +5129,30 @@ if (x && x.status == 200) { if (status.status === 'success') { setTimeout(function() { - + refreshSubscriptionInfo(); - + ConfigFileManager.refreshConfigList(); - + pluginToggleUserAction = false; - + }, 2000); } else { pluginToggleUserAction = false; - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Update Failed%>'; } - + alert('<%:Failed to update config file:%> ' + (status.message || status.error || '<%:Unknown error%>')); } } else { pluginToggleUserAction = false; - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Update Failed%>'; } - + alert('<%:Failed to update config file, please try again later%>'); } }); @@ -4875,36 +5168,36 @@ } pluginToggleUserAction = true; - + var toggleElement = document.getElementById('plugin_toggle'); if (toggleElement) { toggleElement.disabled = true; } - + LogManager.startLogDisplay('<%:Restarting...%>'); - + var requestParams = { action: 'restart' }; - + var currentConfigValue = ConfigFileManager.getCurrentConfig(); var selectedConfig = ConfigFileManager.getSelectedConfig(); - + if (!currentConfigValue && selectedConfig) { requestParams.config_file = configFileName; } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "action")%>', requestParams, function(x, status) { if (x && x.status == 200) { setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 5000); + }, 2000); ConfigFileManager.refreshConfigList(); } else { if (toggleElement) { toggleElement.disabled = false; } alert('<%:Failed to restart core%>'); - + pluginToggleUserAction = false; } }); @@ -4917,34 +5210,34 @@ alert('<%:Please select a config file first%>'); return false; } - + SubscriptionManager.currentConfigFile = currentConfig; SubscriptionManager.retryCount = 0; - + var filename = SubscriptionManager.extractFilename(currentConfig); localStorage.removeItem('sub_info_' + filename); SubscriptionManager.getSubscriptionInfo(); return false; } - + function setSubscriptionUrl() { var currentConfig = ConfigFileManager.getSelectedConfig(); if (!currentConfig) { alert('<%:Please select a config file first%>'); return false; } - + var filename = SubscriptionManager.extractFilename(currentConfig); if (!filename) { alert('<%:Invalid config file selected%>'); return false; } - + var newUrl = prompt('<%:Paste the new url of subscribe infos sources here:%>', ''); if (newUrl === null) { return false; } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "set_subinfo_url")%>', { filename: filename, url: newUrl @@ -4957,7 +5250,7 @@ alert('<%:Specify subscribe infos sources url failed:%>\n' + (status.info || '<%:Unknown error%>')); } }); - + return false; } @@ -4973,7 +5266,7 @@ } }, 500); } - + return false; } @@ -4983,7 +5276,7 @@ alert('<%:Please select a config file first%>'); return false; } - + if (typeof ConfigEditor !== 'undefined' && ConfigEditor.show) { ConfigEditor.show(currentConfig); } else { @@ -4995,7 +5288,7 @@ } }, 500); } - + return false; } @@ -5011,7 +5304,7 @@ } }, 500); } - + return false; } @@ -5048,7 +5341,7 @@ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { return true; } - + var style = window.getComputedStyle(element); var bgColor = style.backgroundColor; let r, g, b; @@ -5074,9 +5367,13 @@ return luminance < 128; }; - function toggleTheme() { - var currentTheme = localStorage.getItem('oc-theme') || (isDarkBackground(document.body) ? 'dark' : 'light'); - var newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + function toggleThemeMode() { + var themes = ['light', 'dark', 'auto']; + var currentTheme = localStorage.getItem('oc-theme') || 'auto'; + var currentIndex = themes.indexOf(currentTheme); + if (currentIndex === -1) currentIndex = 2; + var newIndex = (currentIndex + 1) % themes.length; + var newTheme = themes[newIndex]; localStorage.setItem('oc-theme', newTheme); DarkModeDetector.init(); } diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm b/openclash/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm index db72bbca15..d359a94fa8 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm @@ -17,7 +17,7 @@ min-width: 0; } -.sub_tab{ +.sub_tab { display: block; white-space: nowrap; font-size: 12px; @@ -29,7 +29,7 @@ box-sizing: border-box; } -.sub_tab_show{ +.sub_tab_show { display: block; white-space: nowrap; font-size: 12px; @@ -46,7 +46,7 @@ box-sizing: border-box; } -.sub_setting{ +.sub_setting { display: inline-block; white-space: nowrap; margin: 0; @@ -67,7 +67,7 @@ opacity: 0.7; } -.text_show{ +.text_show { color: #333333; line-height: 1.2; } @@ -131,11 +131,11 @@ .sub_tab, .sub_tab_show { font-size: 11px; } - + .progress_bar_bg { min-width: 220px; } - + .sub_div { gap: 6px; width: calc(100% - 20px); @@ -147,15 +147,15 @@ .sub_tab, .sub_tab_show { font-size: 10px; } - + .progress_bar_bg { min-width: 200px; } - + .sub_setting img { height: 18px !important; } - + .sub_div { gap: 4px; width: calc(100% - 16px); @@ -167,15 +167,15 @@ .sub_tab, .sub_tab_show { font-size: 9px; } - + .progress_bar_bg { min-width: 180px !important; } - + .sub_setting img { height: 16px !important; } - + .sub_div { gap: 2px; width: calc(100% - 12px); @@ -187,15 +187,15 @@ .sub_tab, .sub_tab_show { font-size: 8px; } - + .progress_bar_bg { min-width: 160px !important; } - + .sub_setting img { height: 14px !important; } - + .sub_div { width: calc(100% - 8px); margin: 0 4px; @@ -209,6 +209,169 @@ .sub_div > span:first-child { flex-shrink: 1; } + +/* Multiple providers container */ +.sub_providers_container { + display: flex; + gap: 4px; + flex: 1; + min-width: 0; + overflow-x: auto; + scrollbar-width: thin; + cursor: grab; + user-select: none; +} + +.sub_providers_container.no-scroll { + overflow-x: hidden; + cursor: default; +} + +.sub_providers_container::-webkit-scrollbar { + height: 4px; +} + +.sub_providers_container::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 2px; +} + +.sub_providers_container::-webkit-scrollbar-thumb { + background: #888; + border-radius: 2px; +} + +.sub_providers_container::-webkit-scrollbar-thumb:hover { + background: #555; +} + +.sub_providers_container.dragging { + cursor: grabbing; +} + +.sub_provider_item { + flex: 0 0 auto; + width: 100px; + position: relative; + min-height: 36px; + background-color: #f5f5f5; + border: 1px solid #999999; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; +} + +.sub_provider_fill { + position: absolute; + left: 0; + top: 0; + bottom: 0; + transition: width 0.3s ease; + border-radius: 5px; +} + +.sub_provider_fill.progress_bar_high { + background-color: #9edd9e; +} + +.sub_provider_fill.progress_bar_medium { + background-color: #ffc99f; +} + +.sub_provider_fill.progress_bar_low { + background-color: #ffb9b9; +} + +.sub_provider_name { + position: relative; + z-index: 1; + font-size: 12px; + color: #333; + font-weight: 500; + text-align: center; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + padding: 0 4px; +} + +/* Dark mode support */ +:root[data-darkmode="true"] .sub_provider_item { + background-color: #333333; + border-color: #666666; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_high { + background-color: #5da05d; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_medium { + background-color: #cc8550; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_low { + background-color: #cc6262; +} + +:root[data-darkmode="true"] .sub_provider_name { + color: #e0e0e0; +} + +/* Responsive adjustments for multiple providers */ +@media (max-width: 1024px) { + .sub_providers_container { + gap: 3px; + } + + .sub_provider_item { + width: 90px; + } + + .sub_provider_name { + font-size: 11px; + } +} + +@media (max-width: 768px) { + .sub_providers_container { + gap: 2px; + } + + .sub_provider_item { + width: 80px; + min-height: 32px; + } + + .sub_provider_name { + font-size: 10px; + } +} + +@media (max-width: 480px) { + .sub_provider_item { + width: 70px; + min-height: 30px; + padding: 0 2px; + } + + .sub_provider_name { + font-size: 9px; + } +} + +@media (max-width: 320px) { + .sub_provider_item { + width: 60px; + min-height: 28px; + } + + .sub_provider_name { + font-size: 8px; + } +} <% @@ -245,7 +408,7 @@ function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) { var fontSize = '12px'; var minWidth = '220px'; var topPosition = tr == "null" ? '6px' : '2px'; - + if (screenWidth <= 320) { fontSize = '8px'; minWidth = '160px'; @@ -263,23 +426,135 @@ function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) { minWidth = '220px'; topPosition = tr == "null" ? '6px' : '2px'; } - + + // Build title for native tooltip (format: "v / m (pc%)\nt (Remaining tr days)") + var titleText = v + ' / ' + m + ' (' + pc + '%%)'; + if (t && t !== 'null' && tr && tr !== 'null' && parseInt(tr) > 0) { + titleText += '\n' + t + ' (<%:Remaining%> ' + tr + ' <%:days%>)'; + } + return String.format( - '
' + - (pc >= 50 ? '
' : - (pc < 50 && pc >= 20 ? '
' : + '
' + + (pc >= 50 ? '
' : + (pc < 50 && pc >= 20 ? '
' : '
')) + '
' + - '%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + - (tr == "null" ? '
' : '
') + + '%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + + (tr == "null" ? '
' : '
') + '%s (<%:Remaining%> %s <%:days%>)' + '
' + '
' + - '
', + '
', minWidth, pc, fontSize, v, m, pc, t, tr ); }; +function progressbar_multi_<%=idname%>(providers) { + if (!providers || !Array.isArray(providers) || providers.length === 0) { + return 'No Providers'; + } + + var providerCount = providers.length; + var itemWidth; + var containerClass = 'sub_providers_container'; + + if (providerCount === 2) { + itemWidth = 'calc(50% - 2px)'; + containerClass += ' no-scroll'; + } else if (providerCount === 3) { + itemWidth = 'calc(33.33% - 2.67px)'; + containerClass += ' no-scroll'; + } else { + itemWidth = '100px'; + } + + var container = '
'; + + providers.forEach(function(provider) { + var percent = parseFloat(provider.percent) || 0; + var providerName = provider.provider_name || 'Unknown'; + var used = provider.used || '0 B'; + var total = provider.total || 'N/A'; + var surplus = provider.surplus || used; + var expire = provider.expire || 'null'; + var dayLeft = parseInt(provider.day_left) || 0; + + // Determine background color based on percentage + var bgColorClass = percent >= 50 ? 'progress_bar_high' : + (percent >= 20 ? 'progress_bar_medium' : 'progress_bar_low'); + + // Build title for native tooltip (format: "surplus / total (percent%)\nexpire (Remaining dayLeft days)") + var titleText = surplus + ' / ' + total + ' (' + percent + '%)'; + if (expire !== 'null' && dayLeft > 0) { + titleText += '\n' + expire + ' (<%:Remaining%> ' + dayLeft + ' <%:days%>)'; + } + + container += '
' + + '
' + + '' + providerName + '' + + '
'; + }); + + container += '
'; + + if (providerCount > 3) { + setTimeout(function() { + initDragScroll_<%=idname%>(); + }, 100); + } + + return container; +} + +function initDragScroll_<%=idname%>() { + var container = document.getElementById('sub_providers_<%=idname%>'); + if (!container) return; + + var isDragging = false; + var startX; + var scrollLeft; + var hasMoved = false; + + container.addEventListener('mousedown', function(e) { + if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { + return; + } + + isDragging = true; + hasMoved = false; + startX = e.pageX - container.offsetLeft; + scrollLeft = container.scrollLeft; + container.classList.add('dragging'); + }); + + container.addEventListener('mousemove', function(e) { + if (!isDragging) return; + + var x = e.pageX - container.offsetLeft; + var walk = (x - startX) * 2; + + if (Math.abs(walk) > 5) { + hasMoved = true; + e.preventDefault(); + container.scrollLeft = scrollLeft - walk; + } + }); + + container.addEventListener('mouseup', function() { + isDragging = false; + container.classList.remove('dragging'); + }); + + container.addEventListener('mouseleave', function() { + isDragging = false; + container.classList.remove('dragging'); + }); + + container.addEventListener('dragstart', function(e) { + e.preventDefault(); + }); +} + function sub_info_refresh_<%=idname%>() { if (s_<%=idname%>) { clearTimeout(s_<%=idname%>);}; @@ -288,7 +563,31 @@ function sub_info_refresh_<%=idname%>() retry_<%=idname%> = 0; localStorage.setItem("sub_info_<%=filename%>",JSON.stringify(status)); document.getElementById('<%=idname%>').className = "sub_tab_show"; - document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>((status.surplus ? status.surplus : status.used), (status.total), (status.percent), false, false, (status.expire), (status.day_left)); + + if (status.providers && Array.isArray(status.providers) && status.providers.length > 0) { + if (status.providers.length === 1) { + var provider = status.providers[0]; + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (provider.surplus ? provider.surplus : provider.used), + (provider.total), + (provider.percent), + false, false, + (provider.expire), + (provider.day_left) + ); + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(status.providers); + } + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (status.surplus ? status.surplus : status.used), + (status.total), + (status.percent), + false, false, + (status.expire), + (status.day_left) + ); + } } else if ( x && x.status == 200 && status.sub_info == "No Sub Info Found" ) { retry_<%=idname%> = 0; @@ -310,7 +609,7 @@ function sub_info_refresh_<%=idname%>() s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*120); return } - + }; s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*1800); }); @@ -325,7 +624,30 @@ function sub_info_get_<%=idname%>() document.getElementById('<%=idname%>').innerHTML = "<%:No Sub Info Found%>"; } else { - document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>((save_info.surplus ? save_info.surplus : save_info.used), (save_info.total), (save_info.percent ? save_info.percent : 0), false, false, (save_info.expire), (save_info.day_left ? save_info.day_left : 0)); + if (save_info.providers && Array.isArray(save_info.providers) && save_info.providers.length > 0) { + if (save_info.providers.length === 1) { + var provider = save_info.providers[0]; + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (provider.surplus ? provider.surplus : provider.used), + (provider.total), + (provider.percent ? provider.percent : 0), + false, false, + (provider.expire), + (provider.day_left ? provider.day_left : 0) + ); + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(save_info.providers); + } + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (save_info.surplus ? save_info.surplus : save_info.used), + (save_info.total), + (save_info.percent ? save_info.percent : 0), + false, false, + (save_info.expire), + (save_info.day_left ? save_info.day_left : 0) + ); + } } } else { diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm b/openclash/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm index e838c25e80..60968ad4c9 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm @@ -32,7 +32,7 @@ } } }); - + function switch_dashboard(btn, name, type) { btn.disabled = true; @@ -82,5 +82,5 @@ } //]]> - + <%+cbi/valuefooter%> \ No newline at end of file diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/switch_mode.htm b/openclash/luci-app-openclash/luasrc/view/openclash/switch_mode.htm index d79dd258e1..7265eab8f7 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/switch_mode.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/switch_mode.htm @@ -21,7 +21,7 @@ } } }); - + function switch_modes(btn) { btn.disabled = true; @@ -42,4 +42,4 @@ } //]]> - + diff --git a/openclash/luci-app-openclash/luasrc/view/openclash/tblsection.htm b/openclash/luci-app-openclash/luasrc/view/openclash/tblsection.htm index 480c1bbfef..59c8ed55b4 100644 --- a/openclash/luci-app-openclash/luasrc/view/openclash/tblsection.htm +++ b/openclash/luci-app-openclash/luasrc/view/openclash/tblsection.htm @@ -55,7 +55,7 @@ local sectiontype = "_"..self.config.."_"..string.match(self.sectiontype, "[%w_] + <%+cbi/valuefooter%> diff --git a/sing-box/.fpm_openwrt b/sing-box/.fpm_openwrt index ab8b6db64b..3223ec8ad5 100644 --- a/sing-box/.fpm_openwrt +++ b/sing-box/.fpm_openwrt @@ -14,6 +14,7 @@ --depends kmod-inet-diag --depends kmod-tun --depends firewall4 +--depends kmod-nft-queue --before-remove release/config/openwrt.prerm diff --git a/sing-box/.github/workflows/build.yml b/sing-box/.github/workflows/build.yml index 0e960aa217..8ff37684e7 100644 --- a/sing-box/.github/workflows/build.yml +++ b/sing-box/.github/workflows/build.yml @@ -69,19 +69,19 @@ jobs: strategy: matrix: include: - - { os: linux, arch: amd64, variant: purego, naive: true, openwrt: "x86_64" } + - { os: linux, arch: amd64, variant: purego, naive: true } - { os: linux, arch: amd64, variant: glibc, naive: true } - { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, openwrt: "x86_64" } - - { os: linux, arch: arm64, variant: purego, naive: true, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" } + - { os: linux, arch: arm64, variant: purego, naive: true } - { os: linux, arch: arm64, variant: glibc, naive: true } - { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" } - - { os: linux, arch: "386", go386: sse2, openwrt: "i386_pentium4" } + - { os: linux, arch: "386", go386: sse2 } - { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 } - { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, openwrt: "i386_pentium4" } - - { os: linux, arch: arm, goarm: "7", openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" } + - { os: linux, arch: arm, goarm: "7" } - { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" } - { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" } @@ -206,7 +206,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "0" @@ -228,7 +228,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -243,7 +243,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -258,7 +258,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "0" @@ -278,7 +278,7 @@ jobs: export CXX="${CC}++" mkdir -p dist GOOS=$BUILD_GOOS GOARCH=$BUILD_GOARCH build go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -369,12 +369,8 @@ jobs: -p "dist/openwrt.deb" \ --architecture all \ dist/sing-box=/usr/bin/sing-box - SUFFIX="" - if [[ "${{ matrix.variant }}" == "musl" ]]; then - SUFFIX="_musl" - fi for architecture in ${{ matrix.openwrt }}; do - .github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}${SUFFIX}.ipk" + .github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk" done rm "dist/openwrt.deb" - name: Archive @@ -445,7 +441,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -505,7 +501,7 @@ jobs: run: | mkdir -p dist go build -v -trimpath -o dist/sing-box.exe -tags "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0" ` - -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0" ` + -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0" ` ./cmd/sing-box env: CGO_ENABLED: "0" @@ -517,7 +513,7 @@ jobs: run: | mkdir -p dist go build -v -trimpath -o dist/sing-box.exe -tags "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0" ` - -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0" ` + -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0" ` ./cmd/sing-box env: CGO_ENABLED: "0" diff --git a/sing-box/.github/workflows/docker.yml b/sing-box/.github/workflows/docker.yml index 5447457e26..e5ec3a201c 100644 --- a/sing-box/.github/workflows/docker.yml +++ b/sing-box/.github/workflows/docker.yml @@ -103,7 +103,7 @@ jobs: run: | set -xeuo pipefail go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \ - -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=${VERSION}\" -s -w -buildid= -checklinkname=0" \ + -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=${VERSION}\" -X 'internal/godebug.defaultGODEBUG=multipathtcp=0' -s -w -buildid= -checklinkname=0" \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -115,7 +115,7 @@ jobs: run: | set -xeuo pipefail go build -v -trimpath -o sing-box -tags "${BUILD_TAGS}" \ - -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=${VERSION}\" -s -w -buildid= -checklinkname=0" \ + -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=${VERSION}\" -X 'internal/godebug.defaultGODEBUG=multipathtcp=0' -s -w -buildid= -checklinkname=0" \ ./cmd/sing-box env: CGO_ENABLED: "0" diff --git a/sing-box/.github/workflows/lint.yml b/sing-box/.github/workflows/lint.yml index 6449686cab..e1485b38ff 100644 --- a/sing-box/.github/workflows/lint.yml +++ b/sing-box/.github/workflows/lint.yml @@ -32,7 +32,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: v2.4.0 + version: latest args: --timeout=30m install-mode: binary verify: false diff --git a/sing-box/.github/workflows/linux.yml b/sing-box/.github/workflows/linux.yml index 1f56467c76..e065d00dd8 100644 --- a/sing-box/.github/workflows/linux.yml +++ b/sing-box/.github/workflows/linux.yml @@ -127,7 +127,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "1" @@ -141,7 +141,7 @@ jobs: set -xeuo pipefail mkdir -p dist go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \ - -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \ + -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \ ./cmd/sing-box env: CGO_ENABLED: "0" diff --git a/sing-box/Dockerfile b/sing-box/Dockerfile index fb39e8b603..8589b3313a 100644 --- a/sing-box/Dockerfile +++ b/sing-box/Dockerfile @@ -15,7 +15,7 @@ RUN set -ex \ && go build -v -trimpath -tags \ "with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0" \ -o /go/bin/sing-box \ - -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" -s -w -buildid= -checklinkname=0" \ + -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" -X 'internal/godebug.defaultGODEBUG=multipathtcp=0' -s -w -buildid= -checklinkname=0" \ ./cmd/sing-box FROM --platform=$TARGETPLATFORM alpine AS dist LABEL maintainer="nekohasekai " diff --git a/sing-box/Makefile b/sing-box/Makefile index 1d3b0c53c2..121dbaec6c 100644 --- a/sing-box/Makefile +++ b/sing-box/Makefile @@ -6,7 +6,7 @@ GOHOSTOS = $(shell go env GOHOSTOS) GOHOSTARCH = $(shell go env GOHOSTARCH) VERSION=$(shell CGO_ENABLED=0 GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go run github.com/sagernet/sing-box/cmd/internal/read_tag@latest) -PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' -s -w -buildid= -checklinkname=0" +PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' -X 'internal/godebug.defaultGODEBUG=multipathtcp=0' -s -w -buildid= -checklinkname=0" MAIN_PARAMS = $(PARAMS) -tags "$(TAGS)" MAIN = ./cmd/sing-box PREFIX ?= $(shell go env GOPATH) @@ -41,7 +41,7 @@ fmt_docs: go run ./cmd/internal/format_docs fmt_install: - go install -v mvdan.cc/gofumpt@v0.8.0 + go install -v mvdan.cc/gofumpt@latest go install -v github.com/daixiang0/gci@latest lint: @@ -52,7 +52,7 @@ lint: GOOS=freebsd golangci-lint run ./... lint_install: - go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0 + go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest proto: @go run ./cmd/internal/protogen diff --git a/sing-box/cmd/internal/build_libbox/main.go b/sing-box/cmd/internal/build_libbox/main.go index 6a0ccd08fb..339cf28765 100644 --- a/sing-box/cmd/internal/build_libbox/main.go +++ b/sing-box/cmd/internal/build_libbox/main.go @@ -60,8 +60,8 @@ func init() { if err != nil { currentTag = "unknown" } - sharedFlags = append(sharedFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid= -checklinkname=0") - debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -checklinkname=0") + sharedFlags = append(sharedFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -X internal/godebug.defaultGODEBUG=multipathtcp=0 -s -w -buildid= -checklinkname=0") + debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0") sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_utls", "with_naive_outbound", "with_clash_api", "with_conntrack", "badlinkname", "tfogo_checklinkname0") darwinTags = append(darwinTags, "with_dhcp") diff --git a/sing-box/go.mod b/sing-box/go.mod index 6ebe728b88..884b34793a 100644 --- a/sing-box/go.mod +++ b/sing-box/go.mod @@ -38,7 +38,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 - github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251226064455-a850c4f8a1c8 + github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251230194736-a5db80d71081 github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 github.com/sagernet/smux v1.5.34-mod.2 github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.4 diff --git a/sing-box/go.sum b/sing-box/go.sum index d3ea2688fd..f6c51ff1b9 100644 --- a/sing-box/go.sum +++ b/sing-box/go.sum @@ -218,8 +218,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= -github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251226064455-a850c4f8a1c8 h1:aIgk6YzS/7fNm92CycFWzithdwIc+NAwXGHAJce1dyM= -github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251226064455-a850c4f8a1c8/go.mod h1:+HAK/y9GZljdT0KYKMYDR8MjjqnqDDQZYp5ZZQoRzS8= +github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251230194736-a5db80d71081 h1:ZFw+y1RIKasXENuy8jOYfwpyiKBh92HcSqzDFQLd7Yc= +github.com/sagernet/sing-tun v0.8.0-beta.11.0.20251230194736-a5db80d71081/go.mod h1:+HAK/y9GZljdT0KYKMYDR8MjjqnqDDQZYp5ZZQoRzS8= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o= github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4= diff --git a/sing-box/option/tailscale.go b/sing-box/option/tailscale.go index 05bdd38f4f..f8220df327 100644 --- a/sing-box/option/tailscale.go +++ b/sing-box/option/tailscale.go @@ -12,19 +12,19 @@ import ( type TailscaleEndpointOptions struct { DialerOptions - StateDirectory string `json:"state_directory,omitempty"` - AuthKey string `json:"auth_key,omitempty"` - ControlURL string `json:"control_url,omitempty"` - Ephemeral bool `json:"ephemeral,omitempty"` - Hostname string `json:"hostname,omitempty"` - AcceptRoutes bool `json:"accept_routes,omitempty"` - ExitNode string `json:"exit_node,omitempty"` - ExitNodeAllowLANAccess bool `json:"exit_node_allow_lan_access,omitempty"` - AdvertiseRoutes []netip.Prefix `json:"advertise_routes,omitempty"` - AdvertiseExitNode bool `json:"advertise_exit_node,omitempty"` - RelayServerPort *uint16 `json:"relay_server_port,omitempty"` - RelayServerStaticEndpoints []netip.AddrPort `json:"relay_server_static_endpoints,omitempty"` - UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` + StateDirectory string `json:"state_directory,omitempty"` + AuthKey string `json:"auth_key,omitempty"` + ControlURL string `json:"control_url,omitempty"` + Ephemeral bool `json:"ephemeral,omitempty"` + Hostname string `json:"hostname,omitempty"` + AcceptRoutes bool `json:"accept_routes,omitempty"` + ExitNode string `json:"exit_node,omitempty"` + ExitNodeAllowLANAccess bool `json:"exit_node_allow_lan_access,omitempty"` + AdvertiseRoutes []netip.Prefix `json:"advertise_routes,omitempty"` + AdvertiseExitNode bool `json:"advertise_exit_node,omitempty"` + RelayServerPort *uint16 `json:"relay_server_port,omitempty"` + RelayServerStaticEndpoints []netip.AddrPort `json:"relay_server_static_endpoints,omitempty"` + UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` } type TailscaleDNSServerOptions struct { diff --git a/sing-box/release/local/common.sh b/sing-box/release/local/common.sh index 68a494babd..b1fd367cf1 100755 --- a/sing-box/release/local/common.sh +++ b/sing-box/release/local/common.sh @@ -44,7 +44,7 @@ get_version() { get_ldflags() { local version version=$(get_version) - echo "-X 'github.com/sagernet/sing-box/constant.Version=${version}' -s -w -buildid= -checklinkname=0" + echo "-X 'github.com/sagernet/sing-box/constant.Version=${version}' -X 'internal/godebug.defaultGODEBUG=multipathtcp=0' -s -w -buildid= -checklinkname=0" } build_sing_box() { diff --git a/small/brook/Makefile b/small/brook/Makefile index aeb5b93a39..b569df9495 100644 --- a/small/brook/Makefile +++ b/small/brook/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=brook -PKG_VERSION:=20250808 +PKG_VERSION:=20260101 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/txthinking/brook/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=d78e8066ba5377c3841c8b6dcc6949cccbc04f3e475a3ac34587721438cde494 +PKG_HASH:=70e8310f31cef3b80e1696f364f12b2ab2aa0f1fb9fde00f25bda7620c21f096 PKG_MAINTAINER:=Tianling Shen PKG_LICENSE:=GPL-3.0 diff --git a/small/luci-app-openclash/Makefile b/small/luci-app-openclash/Makefile index d7e09e4c39..30c33d10d9 100644 --- a/small/luci-app-openclash/Makefile +++ b/small/luci-app-openclash/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-openclash -PKG_VERSION:=0.47.028 +PKG_VERSION:=0.47.038 PKG_MAINTAINER:=vernesong PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) diff --git a/small/luci-app-openclash/luasrc/controller/openclash.lua b/small/luci-app-openclash/luasrc/controller/openclash.lua index 814d5166fd..15d4b5a2b1 100644 --- a/small/luci-app-openclash/luasrc/controller/openclash.lua +++ b/small/luci-app-openclash/luasrc/controller/openclash.lua @@ -139,33 +139,6 @@ local function is_start() end local function cn_port() - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - port = config['external-controller'] - if port - port = port.to_s - if port:include?(':') - port = port.split(':')[-1] - end - puts port - end - end - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - return ruby_result - end - end - end return fs.uci_get_config("config", "cn_port") or "9090" end @@ -178,27 +151,6 @@ local function daip() end local function dase() - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - dase = config['secret'] - puts \"#{dase}\" - end - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - return ruby_result - end - end - end return fs.uci_get_config("config", "dashboard_password") end @@ -440,11 +392,11 @@ function action_update_config() -- filename or config_file is basename local filename = luci.http.formvalue("filename") local config_file = luci.http.formvalue("config_file") - + if not filename and config_file then filename = config_file end - + luci.http.prepare_content("application/json") if not filename then @@ -454,9 +406,9 @@ function action_update_config() }) return end - + local update_result = luci.sys.call(string.format("/usr/share/openclash/openclash.sh '%s' >/dev/null 2>&1", filename)) - + if update_result == 0 then luci.http.write_json({ status = "success", @@ -709,11 +661,11 @@ end function action_switch_config() local config_file = luci.http.formvalue("config_file") local config_name = luci.http.formvalue("config_name") - + if not config_file and config_name then config_file = "/etc/openclash/config/" .. config_name end - + if not config_file then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -722,7 +674,7 @@ function action_switch_config() }) return end - + if not fs.access(config_file) then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -731,13 +683,13 @@ function action_switch_config() }) return end - + uci:set("openclash", "config", "config_path", config_file) uci:set("openclash", "config", "enable", "1") uci:commit("openclash") luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1 &") - + luci.http.prepare_content("application/json") luci.http.write_json({ status = "success", @@ -788,12 +740,204 @@ function set_subinfo_url() }) end -function sub_info_get() - local sub_ua, filepath, filename, sub_url, sub_info, info, upload, download, total, expire, http_code, len, percent, day_left, day_expire, surplus, used +function fetch_sub_info(sub_url, sub_ua) + local info, upload, download, total, day_expire, http_code + local used, expire, day_left, percent, surplus + + info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code=%%{http_code}' -H 'User-Agent: %s' '%s'", sub_ua, sub_url)) + local http_match = string.match(info, "http_code=(%d+)") + if not info or not http_match or tonumber(http_match) ~= 200 then + info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code=%%{http_code}' -H 'User-Agent: Quantumultx' '%s'", sub_url)) + http_match = string.match(info, "http_code=(%d+)") + end + + if info and http_match then + http_code = http_match + if tonumber(http_code) == 200 then + info = string.lower(info) + if string.find(info, "subscription%-userinfo") then + local sub_info_line = "" + for line in info:gmatch("[^\r\n]+") do + if string.find(line, "subscription%-userinfo") then + sub_info_line = line + break + end + end + info = sub_info_line + local upload_match = string.match(info, "upload=(%d+)") + local download_match = string.match(info, "download=(%d+)") + local total_match = string.match(info, "total=(%d+)") + local expire_match = string.match(info, "expire=(%d+)") + + upload = upload_match and tonumber(upload_match) or nil + download = download_match and tonumber(download_match) or nil + total = total_match and tonumber(string.format("%.1f", total_match)) or nil + used = upload and download and tonumber(string.format("%.1f", upload + download)) or nil + day_expire = expire_match and tonumber(expire_match) or nil + + if day_expire and day_expire == 0 then + expire = luci.i18n.translate("Long-term") + elseif day_expire then + expire = os.date("%Y-%m-%d %H:%M:%S", day_expire) or "null" + else + expire = "null" + end + + if day_expire and day_expire ~= 0 and os.time() <= day_expire then + day_left = math.ceil((day_expire - os.time()) / (3600*24)) + if math.ceil(day_left / 365) > 50 then + day_left = "∞" + end + elseif day_expire and day_expire == 0 then + day_left = "∞" + elseif day_expire == nil then + day_left = "null" + else + day_left = 0 + end + + if used and total and used <= total and total > 0 then + percent = string.format("%.1f",((total-used)/total)*100) or "100" + surplus = fs.filesize(total - used) + elseif used and total and used > total and total > 0 then + percent = "0" + surplus = "-"..fs.filesize(total - used) + elseif used and total and used < total and total == 0.0 then + percent = "0" + surplus = fs.filesize(total - used) + elseif used and total and used == total and total == 0.0 then + percent = "0" + surplus = "0.0 KB" + elseif used and total and used > total and total == 0.0 then + percent = "100" + surplus = fs.filesize(total - used) + elseif used == nil and total and total > 0.0 then + percent = 100 + surplus = fs.filesize(total) + elseif used == nil and total and total == 0.0 then + percent = 100 + surplus = "∞" + else + percent = 0 + surplus = "null" + end + + local total_formatted, used_formatted + if total and total > 0 then + total_formatted = fs.filesize(total) + elseif total and total == 0.0 then + total_formatted = "∞" + else + total_formatted = "null" + end + used_formatted = fs.filesize(used) + + return { + http_code = http_code, + surplus = surplus, + used = used_formatted, + total = total_formatted, + percent = percent, + day_left = day_left, + expire = expire + } + end + end + end + + return nil +end + +-- Get subscription URL with priority (Priority 1: subscribe_info, Priority 2: YAML proxy-providers, Priority 3: config_subscribe) +function get_sub_url(filename) + local sub_url = nil local info_tb = {} + local providers = {} + + -- Priority 1: subscribe_info + uci:foreach("openclash", "subscribe_info", + function(s) + if s.name == filename and s.url and string.find(s.url, "http") then + string.gsub(s.url, '[^\n]+', function(w) table.insert(info_tb, w) end) + sub_url = info_tb[1] + end + end + ) + + if sub_url then + return {type = "single", url = sub_url} + end + + -- Priority 2: YAML proxy-providers (use actual config file content first) + local config_path = "/etc/openclash/config/" .. fs.basename(filename .. ".yaml") + + if fs.access(config_path) then + local ruby_result = luci.sys.exec(string.format([[ + ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e ' + begin + config = YAML.load_file("%s") + providers = [] + if config && config["proxy-providers"] + config["proxy-providers"].each do |name, provider| + # Only include providers with non-empty URLs + if provider && provider["url"] && !provider["url"].to_s.empty? + providers << {"name" => name, "url" => provider["url"].to_s} + end + end + end + # Manual JSON output (ruby-json is not a dependency) + result = "[" + providers.each_with_index do |p, i| + result << "," if i > 0 + # Escape quotes in name and URL + name_escaped = p["name"].gsub("\"", "\\\\\"") + url_escaped = p["url"].gsub("\"", "\\\\\"") + result << "{\"name\":\"#{name_escaped}\",\"url\":\"#{url_escaped}\"}" + end + result << "]" + puts result + rescue => e + puts "[]" + end + ' 2>/dev/null || echo '[]' + ]], config_path)):gsub("\n", "") + + if ruby_result and ruby_result ~= "" and ruby_result ~= "[]" then + local success, parsed_providers = pcall(function() + return json.parse(ruby_result) + end) + + if success and parsed_providers and #parsed_providers > 0 then + return {type = "multiple", providers = parsed_providers} + end + end + end + + -- Priority 3: config_subscribe table (last fallback) + uci:foreach("openclash", "config_subscribe", + function(s) + if s.name == filename and s.address and string.find(s.address, "http") then + string.gsub(s.address, '[^\n]+', function(w) table.insert(info_tb, w) end) + sub_url = info_tb[1] + end + end + ) + + if sub_url then + return {type = "single", url = sub_url} + end + + return nil +end + +function sub_info_get() + local sub_ua, filename, sub_info + local providers_data = {} + filename = luci.http.formvalue("filename") sub_info = "" sub_ua = "Clash" + uci:foreach("openclash", "config_subscribe", function(s) if s.name == filename and s.sub_ua then @@ -801,141 +945,49 @@ function sub_info_get() end end ) + if filename and not is_start() then - uci:foreach("openclash", "subscribe_info", - function(s) - if s.name == filename and s.url and string.find(s.url, "http") then - string.gsub(s.url, '[^\n]+', function(w) table.insert(info_tb, w) end) - sub_url = info_tb[1] - end - end - ) - if not sub_url then - uci:foreach("openclash", "config_subscribe", - function(s) - if s.name == filename and s.address and string.find(s.address, "http") then - string.gsub(s.address, '[^\n]+', function(w) table.insert(info_tb, w) end) - sub_url = info_tb[1] - end - end - ) - end - if not sub_url then + local url_result = get_sub_url(filename) + + if not url_result then sub_info = "No Sub Info Found" - else - info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code='%%{http_code} -H 'User-Agent: %s' '%s'", sub_ua, sub_url)) - if not info or tonumber(string.sub(string.match(info, "http_code=%d+"), 11, -1)) ~= 200 then - info = luci.sys.exec(string.format("curl -sLI -X GET -m 10 -w 'http_code='%%{http_code} -H 'User-Agent: Quantumultx' '%s'", sub_url)) - end + elseif url_result.type == "single" then + local info = fetch_sub_info(url_result.url, sub_ua) if info then - http_code=string.sub(string.match(info, "http_code=%d+"), 11, -1) - if tonumber(http_code) == 200 then - info = string.lower(info) - if string.find(info, "subscription%-userinfo") then - info = luci.sys.exec("echo '%s' |grep 'subscription-userinfo'" %info) - upload = string.sub(string.match(info, "upload=%d+"), 8, -1) or nil - download = string.sub(string.match(info, "download=%d+"), 10, -1) or nil - total = tonumber(string.format("%.1f",string.sub(string.match(info, "total=%d+"), 7, -1))) or nil - used = tonumber(string.format("%.1f",(upload + download))) or nil - if string.match(info, "expire=%d+") then - day_expire = tonumber(string.sub(string.match(info, "expire=%d+"), 8, -1)) or nil - end - - if day_expire and day_expire == 0 then - expire = luci.i18n.translate("Long-term") - elseif day_expire then - expire = os.date("%Y-%m-%d %H:%M:%S", day_expire) or "null" - else - expire = "null" - end - - if day_expire and day_expire ~= 0 and os.time() <= day_expire then - day_left = math.ceil((day_expire - os.time()) / (3600*24)) - if math.ceil(day_left / 365) > 50 then - day_left = "∞" - end - elseif day_expire and day_expire == 0 then - day_left = "∞" - elseif day_expire == nil then - day_left = "null" - else - day_left = 0 - end - - if used and total and used <= total and total > 0 then - percent = string.format("%.1f",((total-used)/total)*100) or "100" - surplus = fs.filesize(total - used) - elseif used and total and used > total and total > 0 then - percent = "0" - surplus = "-"..fs.filesize(total - used) - elseif used and total and used < total and total == 0.0 then - percent = "0" - surplus = fs.filesize(total - used) - elseif used and total and used == total and total == 0.0 then - percent = "0" - surplus = "0.0 KB" - elseif used and total and used > total and total == 0.0 then - percent = "100" - surplus = fs.filesize(total - used) - elseif used == nil and total and total > 0.0 then - percent = 100 - surplus = fs.filesize(total) - elseif used == nil and total and total == 0.0 then - percent = 100 - surplus = "∞" - else - percent = 0 - surplus = "null" - end - if total and total > 0 then - total = fs.filesize(total) - elseif total and total == 0.0 then - total = "∞" - else - total = "null" - end - used = fs.filesize(used) - sub_info = "Successful" - else - sub_info = "No Sub Info Found" - end + table.insert(providers_data, info) + sub_info = "Successful" + else + sub_info = "No Sub Info Found" + end + elseif url_result.type == "multiple" then + for i, provider in ipairs(url_result.providers) do + local info = fetch_sub_info(provider.url, sub_ua) + if info then + info.provider_name = provider.name + table.insert(providers_data, info) end end + + if #providers_data > 0 then + sub_info = "Successful" + else + sub_info = "No Sub Info Found" + end end end + luci.http.prepare_content("application/json") luci.http.write_json({ - http_code = http_code, sub_info = sub_info, - surplus = surplus, - used = used, - total = total, - percent = percent, - day_left = day_left, - expire = expire, - get_time = os.time(); + providers = providers_data, + get_time = os.time() }) end function action_rule_mode() - local mode, info - if is_running() then - local daip = daip() - local dase = dase() or "" - local cn_port = cn_port() - if not daip or not cn_port then return end - info = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/configs', dase, daip, cn_port))) - if info then - mode = info["mode"] - else - mode = fs.uci_get_config("config", "proxy_mode") or "rule" - end - else - mode = fs.uci_get_config("config", "proxy_mode") or "rule" - end luci.http.prepare_content("application/json") luci.http.write_json({ - mode = mode; + mode = fs.uci_get_config("config", "proxy_mode") or "rule"; }) end @@ -1025,7 +1077,7 @@ function action_switch_log() local dase = dase() or "" local cn_port = cn_port() level = luci.http.formvalue("log_level") - if not daip or not cn_port then luci.http.status(500, "Switch Faild") return end + if not daip or not cn_port or not level then luci.http.status(500, "Switch Faild") return end info = luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPATCH http://"%s":"%s"/configs -d \'{\"log-level\": \"%s\"}\'', dase, daip, cn_port, level)) if info ~= "" then luci.http.status(500, "Switch Faild") @@ -1057,9 +1109,9 @@ function action_toolbar_show_sys() local cpu = "0" local load_avg = "0" local cpu_count = luci.sys.exec("grep -c ^processor /proc/cpuinfo 2>/dev/null"):gsub("\n", "") or 1 - + local pid = luci.sys.exec("pgrep -f '^[^ ]*clash' | head -1 | tr -d '\n' 2>/dev/null") - + if pid and pid ~= "" then cpu = luci.sys.exec(string.format([[ top -b -n1 | awk -v pid="%s" ' @@ -1078,12 +1130,12 @@ function action_toolbar_show_sys() end load_avg = luci.sys.exec("awk '{print $2; exit}' /proc/loadavg 2>/dev/null"):gsub("\n", "") or "0" - + if not string.match(load_avg, "^[0-9]*%.?[0-9]*$") then load_avg = "0" end end - + luci.http.prepare_content("application/json") luci.http.write_json({ cpu = cpu, @@ -1099,10 +1151,10 @@ function action_toolbar_show() local dase = dase() or "" local cn_port = cn_port() if not daip or not cn_port then return end - + traffic = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/traffic', dase, daip, cn_port))) connections = json.parse(luci.sys.exec(string.format('curl -sL -m 3 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XGET http://"%s":"%s"/connections', dase, daip, cn_port))) - + if traffic and connections and connections.connections then connection = #(connections.connections) up = s(traffic.up) @@ -1116,7 +1168,7 @@ function action_toolbar_show() down_total = "0 KB" connection = "0" end - + mem = tonumber(luci.sys.exec(string.format("cat /proc/%s/status 2>/dev/null |grep -w VmRSS |awk '{print $2}'", pid))) cpu = luci.sys.exec(string.format([[ top -b -n1 | awk -v pid="%s" ' @@ -1128,7 +1180,7 @@ function action_toolbar_show() cpu_col>0 && $1==pid { print $cpu_col } ' ]], pid)) - + if mem and cpu then mem = fs.filesize(mem*1024) or "0 KB" cpu = string.match(cpu, "%d+%.?%d*") or "0" @@ -1146,7 +1198,7 @@ function action_toolbar_show() else return end - + luci.http.prepare_content("application/json") luci.http.write_json({ connections = connection, @@ -1280,13 +1332,15 @@ end function action_status() luci.http.prepare_content("application/json") luci.http.write_json({ - clash = is_running(), + clash = uci:get("openclash", "config", "enable") == "1", daip = daip(), dase = dase(), db_foward_port = db_foward_port(), db_foward_domain = db_foward_domain(), db_forward_ssl = db_foward_ssl(), cn_port = cn_port(), + yacd = fs.isdirectory("/usr/share/openclash/ui/yacd") , + dashboard = fs.isdirectory("/usr/share/openclash/ui/dashboard") , core_type = fs.uci_get_config("config", "core_type") or "Meta"; }) end @@ -1385,7 +1439,7 @@ function action_refresh_log() luci.http.prepare_content("application/json") local logfile = "/tmp/openclash.log" local log_len = tonumber(luci.http.formvalue("log_len")) or 0 - + if not fs.access(logfile) then luci.http.write_json({ len = 0, @@ -1395,9 +1449,9 @@ function action_refresh_log() }) return end - + local total_lines = tonumber(luci.sys.exec("wc -l < " .. logfile)) or 0 - + if total_lines == log_len and log_len > 0 then luci.http.write_json({ len = total_lines, @@ -1407,24 +1461,24 @@ function action_refresh_log() }) return end - + local exclude_pattern = "UDP%-Receive%-Buffer%-Size|^Sec%-Fetch%-Mode|^User%-Agent|^Access%-Control|^Accept|^Origin|^Referer|^Connection|^Pragma|^Cache%-" local core_pattern = " DBG | INF |level=| WRN | ERR | FTL " local limit = 1000 local start_line = (log_len > 0 and total_lines > log_len) and (log_len + 1) or 1 - + local core_cmd = string.format( "tail -n +%d '%s' | grep -v -E '%s' | grep -E '%s' | tail -n %d", start_line, logfile, exclude_pattern, core_pattern, limit ) local core_raw = luci.sys.exec(core_cmd) - + local oc_cmd = string.format( "tail -n +%d '%s' | grep -v -E '%s' | grep -v -E '%s' | tail -n %d", start_line, logfile, exclude_pattern, core_pattern, limit ) local oc_raw = luci.sys.exec(oc_cmd) - + local core_log = "" if core_raw and core_raw ~= "" then local core_logs = {} @@ -1439,7 +1493,7 @@ function action_refresh_log() core_log = table.concat(core_logs, "\n") end end - + local oc_log = "" if oc_raw and oc_raw ~= "" then local oc_logs = {} @@ -1456,7 +1510,7 @@ function action_refresh_log() oc_log = table.concat(oc_logs, "\n") end end - + luci.http.write_json({ len = total_lines, update = true, @@ -1828,7 +1882,7 @@ function trans_line_nolabel(data) if data == nil or data == "" then return "" end - + local line_trans = "" if string.len(data) >= 19 and string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then line_trans = string.sub(data, 0, 20)..luci.i18n.translate(string.sub(data, 21, -1)) @@ -1842,11 +1896,11 @@ function trans_line(data) if data == nil or data == "" then return "" end - + local no_trans = {} local line_trans = "" local a = string.find(data, "【") - + if not a then if string.len(data) >= 19 and string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then return string.sub(data, 0, 20) .. luci.i18n.translate(string.sub(data, 21, -1)) @@ -1854,25 +1908,25 @@ function trans_line(data) return luci.i18n.translate(data) end end - + local b_pos = string.find(data, "】") if not b_pos then return luci.i18n.translate(data) end - + local b = b_pos + 2 local c = 21 local d = 0 local v local x - + while true do table.insert(no_trans, a) table.insert(no_trans, b) - + local next_a = string.find(data, "【", b+1) local next_b = string.find(data, "】", b+1) - + if next_a and next_b then a = next_a b = next_b + 2 @@ -1880,15 +1934,15 @@ function trans_line(data) break end end - + if #no_trans % 2 ~= 0 then table.remove(no_trans) end - + for k = 1, #no_trans, 2 do x = no_trans[k] v = no_trans[k+1] - + if x and v then if x <= 21 or not string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then line_trans = line_trans .. luci.i18n.translate(string.sub(data, d, x - 1)) .. string.sub(data, x, v) @@ -1899,7 +1953,7 @@ function trans_line(data) c = v + 1 end end - + if c > string.len(data) then if d == 0 then if string.match(string.sub(data, 0, 19), "%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d") then @@ -1915,7 +1969,7 @@ function trans_line(data) line_trans = line_trans .. luci.i18n.translate(string.sub(data, c, -1)) end end - + return line_trans end @@ -1948,7 +2002,7 @@ end function action_myip_check() local result = {} local random = math.random(100000000) - + local services = { { name = "upaiyun", @@ -1972,7 +2026,7 @@ function action_myip_check() table.insert(geo_parts, upaiyun_json.remote_addr_location.isp) end end - + return { ip = upaiyun_json.remote_addr, geo = table.concat(geo_parts, " ") @@ -1989,11 +2043,11 @@ function action_myip_check() if data and data ~= "" then local ip = string.match(data, "当前 IP:([%d%.]+)") local geo = string.match(data, "来自于:(.+)") - + if ip and geo then geo = string.gsub(geo, "%s+", " ") geo = string.gsub(geo, "^%s*(.-)%s*$", "%1") - + return { ip = ip, geo = geo @@ -2017,7 +2071,7 @@ function action_myip_check() if ipsb_json.isp and ipsb_json.isp ~= "" then table.insert(geo_parts, ipsb_json.isp) end - + return { ip = ipsb_json.ip, geo = table.concat(geo_parts, " ") @@ -2044,15 +2098,15 @@ function action_myip_check() end } } - + local function create_concurrent_query(service) local fdi, fdo = nixio.pipe() if not fdi or not fdo then return nil end - + local pid = nixio.fork() - + if pid > 0 then fdo:close() return { @@ -2079,7 +2133,7 @@ function action_myip_check() nixio.dup(fdo, nixio.stdout) fdi:close() fdo:close() - + local cmd = string.format( 'curl -SsL -m 5 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "%s" 2>/dev/null', service.url @@ -2091,9 +2145,9 @@ function action_myip_check() return nil end end - + local queries = {} - + for _, service in ipairs(services) do local query = create_concurrent_query(service) if query then @@ -2104,7 +2158,7 @@ function action_myip_check() } end end - + if next(queries) == nil then luci.http.prepare_content("application/json") luci.http.write_json({ @@ -2112,62 +2166,62 @@ function action_myip_check() }) return end - + local max_iterations = 140 local iteration = 0 local completed = {} - + while iteration < max_iterations do iteration = iteration + 1 - + for name, info in pairs(queries) do if not completed[name] then local wpid, stat = nixio.waitpid(info.query.pid, "nohang") local buffer = info.query.reader() - + if buffer then info.data = info.data .. buffer end - + if wpid then pcall(info.query.close) completed[name] = true - + local parsed_result = info.parser(info.data) if parsed_result then result[name] = parsed_result end - + queries[name] = nil else local still_running = luci.sys.call(string.format("kill -0 %d 2>/dev/null", info.query.pid)) == 0 if not still_running then pcall(info.query.close) completed[name] = true - + local parsed_result = info.parser(info.data) if parsed_result then result[name] = parsed_result end - + queries[name] = nil end end end end - + local remaining_count = 0 for _ in pairs(queries) do remaining_count = remaining_count + 1 end - + if remaining_count == 0 then break end - + nixio.nanosleep(0, 50000000) end - + for name, info in pairs(queries) do if not completed[name] then result[name] = { ip = "", geo = "", error = "timeout" } @@ -2176,14 +2230,14 @@ function action_myip_check() pcall(info.query.close) end end - + if result.ipify and result.ipify.ip then local geo_cmd = string.format( 'curl -sL -m 5 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "https://api-ipv4.ip.sb/geoip/%s" 2>/dev/null', result.ipify.ip ) local geo_data = luci.sys.exec(geo_cmd) - + if geo_data and geo_data ~= "" then local ok_geo, geo_json = pcall(json.parse, geo_data) if ok_geo and geo_json and geo_json.ip then @@ -2198,7 +2252,7 @@ function action_myip_check() end end end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2210,7 +2264,7 @@ function action_website_check() response_time = 0, error = "" } - + if not domain then result.error = "Missing domain parameter" luci.http.prepare_content("application/json") @@ -2235,12 +2289,12 @@ function action_website_check() 'curl -sL -m 5 --connect-timeout 3 -w "%%{http_code},%%{time_total},%%{time_connect},%%{time_appconnect}" "%s" -o /dev/null 2>/dev/null', test_url ) - + local output = luci.sys.exec(cmd) - + if output and output ~= "" then local http_code, time_total, time_connect, time_appconnect = output:match("(%d+),([%d%.]+),([%d%.]+),([%d%.]+)") - + if http_code and tonumber(http_code) then local code = tonumber(http_code) local response_time = 0 @@ -2251,7 +2305,7 @@ function action_website_check() else response_time = math.floor((tonumber(time_total) or 0) * 1000) end - + if code >= 200 and code < 400 then result.success = true result.response_time = response_time @@ -2270,7 +2324,7 @@ function action_website_check() fallback_url ) local fallback_output = luci.sys.exec(fallback_cmd) - + if fallback_output and fallback_output ~= "" then local fb_code, fb_total, fb_appconnect = fallback_output:match("(%d+),([%d%.]+),([%d%.]+)") if fb_code and tonumber(fb_code) then @@ -2281,7 +2335,7 @@ function action_website_check() else fb_response_time = math.floor((tonumber(fb_total) or 0) * 1000) end - + if fb_code_num >= 200 and fb_code_num < 400 then result.success = true result.response_time = fb_response_time @@ -2310,7 +2364,7 @@ function action_website_check() result.success = false result.error = "No response" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2321,103 +2375,27 @@ function action_proxy_info() auth_user = "", auth_pass = "" } - - local function get_info_from_uci() - local mixed_port = fs.uci_get_config("config", "mixed_port") - if mixed_port and mixed_port ~= "" then - result.mixed_port = mixed_port - else - result.mixed_port = "7893" - end - - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and result.auth_user == "" then - if section.username and section.username ~= "" then - result.auth_user = section.username - end - if section.password and section.password ~= "" then - result.auth_pass = section.password - end - return false - end - end) + + + local mixed_port = fs.uci_get_config("config", "mixed_port") + if mixed_port and mixed_port ~= "" then + result.mixed_port = mixed_port + else + result.mixed_port = "7893" end - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - mixed_port = '' - auth_user = '' - auth_pass = '' - - if config - if config['mixed-port'] - mixed_port = config['mixed-port'].to_s - end - - if config['authentication'] && config['authentication'].is_a?(Array) && !config['authentication'].empty? - auth_entry = config['authentication'][0] - if auth_entry.is_a?(String) && auth_entry.include?(':') - username, password = auth_entry.split(':', 2) - auth_user = username || '' - auth_pass = password || '' - end - end - end - - puts \"#{mixed_port},#{auth_user},#{auth_pass}\" - rescue - puts ',,' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local runtime_mixed_port, runtime_auth_user, runtime_auth_pass = ruby_result:match("([^,]*),([^,]*),([^,]*)") - - if runtime_mixed_port and runtime_mixed_port ~= "" then - result.mixed_port = runtime_mixed_port - else - local uci_mixed_port = fs.uci_get_config("config", "mixed_port") - if uci_mixed_port and uci_mixed_port ~= "" then - result.mixed_port = uci_mixed_port - else - result.mixed_port = "7893" - end - end - - if runtime_auth_user and runtime_auth_user ~= "" and runtime_auth_pass and runtime_auth_pass ~= "" then - result.auth_user = runtime_auth_user - result.auth_pass = runtime_auth_pass - else - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and result.auth_user == "" then - if section.username and section.username ~= "" then - result.auth_user = section.username - end - if section.password and section.password ~= "" then - result.auth_pass = section.password - end - return false - end - end) - end - luci.http.prepare_content("application/json") - luci.http.write_json(result) - return + uci:foreach("openclash", "authentication", function(section) + if section.enabled == "1" and result.auth_user == "" then + if section.username and section.username ~= "" then + result.auth_user = section.username end + if section.password and section.password ~= "" then + result.auth_pass = section.password + end + return false end - end + end) - get_info_from_uci() - luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2430,61 +2408,14 @@ function action_oc_settings() stream_unlock = "0" } - local function get_uci_settings() - local meta_sniffer = fs.uci_get_config("config", "enable_meta_sniffer") - if meta_sniffer == "1" then - result.meta_sniffer = "1" - end - - local respect_rules = fs.uci_get_config("config", "enable_respect_rules") - if respect_rules == "1" then - result.respect_rules = "1" - end + local meta_sniffer = fs.uci_get_config("config", "enable_meta_sniffer") + if meta_sniffer == "1" then + result.meta_sniffer = "1" end - if is_running() then - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config - sniffer_enabled = config['sniffer'] && config['sniffer']['enable'] == true ? '1' : '0' - respect_rules_enabled = config['dns'] && config['dns']['respect-rules'] == true ? '1' : '0' - puts \"#{sniffer_enabled},#{respect_rules_enabled}\" - else - puts '0,0' - end - rescue - puts '0,0' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local sniffer_result, respect_rules_result = ruby_result:match("(%d),(%d)") - if sniffer_result and respect_rules_result then - result.meta_sniffer = sniffer_result - result.respect_rules = respect_rules_result - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() - end - else - get_uci_settings() + local respect_rules = fs.uci_get_config("config", "enable_respect_rules") + if respect_rules == "1" then + result.respect_rules = "1" end local oversea = fs.uci_get_config("config", "china_ip_route") @@ -2500,7 +2431,7 @@ function action_oc_settings() if stream_unlock == "1" then result.stream_unlock = "1" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2508,12 +2439,12 @@ end function action_switch_oc_setting() local setting = luci.http.formvalue("setting") local value = luci.http.formvalue("value") - + if not setting or not value then luci.http.status(400, "Missing parameters") return end - + local function get_runtime_config_path() local config_path = fs.uci_get_config("config", "config_path") if not config_path then @@ -2522,20 +2453,20 @@ function action_switch_oc_setting() local config_filename = fs.basename(config_path) return "/etc/openclash/" .. config_filename end - + local function update_runtime_config(ruby_cmd) local runtime_config_path = get_runtime_config_path() if not runtime_config_path then luci.http.status(500, "No config path found") return false end - + local ruby_result = luci.sys.call(ruby_cmd) if ruby_result ~= 0 then luci.http.status(500, "Failed to modify config file") return false end - + local daip = daip() local dase = dase() or "" local cn_port = cn_port() @@ -2543,43 +2474,43 @@ function action_switch_oc_setting() luci.http.status(500, "Switch Failed") return false end - + local reload_result = luci.sys.exec(string.format('curl -sL -m 5 --connect-timeout 2 -H "Content-Type: application/json" -H "Authorization: Bearer %s" -XPUT http://"%s":"%s"/configs?force=true -d \'{"path":"%s"}\' 2>&1', dase, daip, cn_port, runtime_config_path)) - + if reload_result ~= "" then luci.http.status(500, "Switch Failed") return false end - + return true end - + if setting == "meta_sniffer" then if is_running() then local runtime_config_path = get_runtime_config_path() local ruby_cmd - + if value == "1" then ruby_cmd = string.format([[ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' - + config = File.exist?(config_path) ? YAML.load_file(config_path) : {} config ||= {} - + if config['sniffer']&.dig('enable') == true && config['sniffer']&.dig('parse-pure-ip') == true && config['sniffer']&.dig('sniff') exit 0 end - + config['sniffer'] = { 'enable' => true, 'parse-pure-ip' => true, 'override-destination' => false } - + custom_sniffer_path = '/etc/openclash/custom/openclash_custom_sniffer.yaml' if File.exist?(custom_sniffer_path) begin @@ -2590,7 +2521,7 @@ function action_switch_oc_setting() rescue end end - + unless config['sniffer']['sniff'] config['sniffer']['sniff'] = { 'QUIC' => { 'ports' => [443] }, @@ -2598,19 +2529,19 @@ function action_switch_oc_setting() 'HTTP' => { 'ports' => [80, '8080-8880'], 'override-destination' => true } } end - + unless config['sniffer']['force-domain'] config['sniffer']['force-domain'] = ['+.netflix.com', '+.nflxvideo.net', '+.amazonaws.com'] end - + unless config['sniffer']['skip-domain'] config['sniffer']['skip-domain'] = ['+.apple.com', 'Mijia Cloud', 'dlg.io.mi.com'] end - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 @@ -2622,7 +2553,7 @@ function action_switch_oc_setting() ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' - + if File.exist?(config_path) config = YAML.load_file(config_path) if config&.dig('sniffer', 'enable') == false @@ -2631,14 +2562,14 @@ function action_switch_oc_setting() else config = {} end - + config ||= {} config['sniffer'] = { 'enable' => false } - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 @@ -2646,7 +2577,7 @@ function action_switch_oc_setting() " 2>/dev/null ]], runtime_config_path) end - + if not update_runtime_config(ruby_cmd) then return end @@ -2660,13 +2591,13 @@ function action_switch_oc_setting() if is_running() then local runtime_config_path = get_runtime_config_path() local target_value = (value == "1") and "true" or "false" - + local ruby_cmd = string.format([[ ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin config_path = '%s' target_value = %s - + if File.exist?(config_path) config = YAML.load_file(config_path) if config&.dig('dns', 'respect-rules') == target_value @@ -2678,28 +2609,28 @@ function action_switch_oc_setting() else config = {} end - + config ||= {} config['dns'] ||= {} config['dns']['respect-rules'] = target_value - + if target_value == true if !config['dns']['proxy-server-nameserver'] || config['dns']['proxy-server-nameserver'].empty? config['dns']['proxy-server-nameserver'] = ['114.114.114.114', '119.29.29.29', '8.8.8.8', '1.1.1.1'] end end - + temp_path = config_path + '.tmp' File.open(temp_path, 'w') { |f| YAML.dump(config, f) } File.rename(temp_path, config_path) - + rescue => e File.unlink(temp_path) if File.exist?(temp_path) exit 1 end " 2>/dev/null ]], runtime_config_path, target_value) - + if not update_runtime_config(ruby_cmd) then return end @@ -2746,7 +2677,7 @@ function action_switch_oc_setting() luci.http.status(400, "Invalid setting") return end - + luci.http.prepare_content("application/json") luci.http.write_json({ status = "success", @@ -2760,81 +2691,35 @@ function action_generate_pac() pac_url = "", error = "" } - + local auth_user = "" local auth_pass = "" - local auth_exists = false - - local function get_auth_from_uci() - uci:foreach("openclash", "authentication", function(section) - if section.enabled == "1" and section.username and section.username ~= "" - and section.password and section.password ~= "" then - auth_user = section.username - auth_pass = section.password - auth_exists = true - return false - end - end) - end - local config_path = fs.uci_get_config("config", "config_path") - if config_path then - local config_filename = fs.basename(config_path) - local runtime_config_path = "/etc/openclash/" .. config_filename - - if fs.access(runtime_config_path) then - local ruby_result = luci.sys.exec(string.format([[ - ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " - begin - config = YAML.load_file('%s') - if config && config['authentication'] && config['authentication'].is_a?(Array) && !config['authentication'].empty? - auth_entry = config['authentication'][0] - if auth_entry.is_a?(String) && auth_entry.include?(':') - username, password = auth_entry.split(':', 2) - puts \"#{username},#{password}\" - else - puts ',' - end - else - puts ',' - end - rescue - puts ',' - end - " 2>/dev/null || echo "__RUBY_ERROR__" - ]], runtime_config_path)):gsub("\n", "") - - if ruby_result and ruby_result ~= "" and ruby_result ~= "__RUBY_ERROR__" then - local runtime_user, runtime_pass = ruby_result:match("([^,]*),([^,]*)") - if runtime_user and runtime_user ~= "" and runtime_pass and runtime_pass ~= "" then - auth_user = runtime_user - auth_pass = runtime_pass - auth_exists = true - end - end + uci:foreach("openclash", "authentication", function(section) + if section.enabled == "1" and section.username and section.username ~= "" + and section.password and section.password ~= "" then + auth_user = section.username + auth_pass = section.password + return false end - end + end) - if not auth_exists then - get_auth_from_uci() - end - local proxy_ip = daip() local mixed_port = fs.uci_get_config("config", "mixed_port") or "7893" - + if not proxy_ip then result.error = "Unable to get proxy IP" luci.http.prepare_content("application/json") luci.http.write_json(result) return end - + local function generate_random_string() local random_cmd = "tr -cd 'a-zA-Z0-9' /dev/null| head -c16 || date +%N| md5sum |head -c16" local random_string = luci.sys.exec(random_cmd):gsub("\n", "") return random_string end - + local function count_pac_lines(content) if not content or content == "" then return 0 @@ -2848,11 +2733,11 @@ function action_generate_pac() end return lines end - + local new_proxy_string = string.format("PROXY %s:%s; DIRECT", proxy_ip, mixed_port) local new_pac_content = generate_pac_content(proxy_ip, mixed_port, auth_user, auth_pass) local new_pac_lines = count_pac_lines(new_pac_content) - + local pac_dir = "/www/luci-static/resources/openclash/pac/" local pac_filename = nil local pac_file_path = nil @@ -2872,7 +2757,7 @@ function action_generate_pac() if not existing_proxy then existing_proxy = string.match(file_content, 'return%s*"(PROXY%s+[^"]*)"') end - + if existing_proxy and existing_proxy == new_proxy_string then local existing_lines = count_pac_lines(file_content) if existing_lines == new_pac_lines then @@ -2887,7 +2772,7 @@ function action_generate_pac() file:write(new_pac_content) file:close() luci.sys.call("chmod 644 " .. file_path) - + pac_filename = file_path:match("([^/]+)$") pac_file_path = file_path random_suffix = pac_filename:match("^pac_(.+)$") @@ -2899,23 +2784,23 @@ function action_generate_pac() local updated_content = string.gsub(file_content, 'return%s*"PROXY%s+[^"]*"', 'return "' .. new_proxy_string .. '"') - + if updated_content ~= file_content then local updated_lines = count_pac_lines(updated_content) local final_content - + if updated_lines == new_pac_lines then final_content = updated_content else final_content = new_pac_content end - + local file = io.open(file_path, "w") if file then file:write(final_content) file:close() luci.sys.call("chmod 644 " .. file_path) - + pac_filename = file_path:match("([^/]+)$") pac_file_path = file_path random_suffix = pac_filename:match("^pac_(.+)$") @@ -2928,19 +2813,19 @@ function action_generate_pac() end end end - + if need_update then luci.sys.call("rm -f " .. pac_dir .. "pac_* 2>/dev/null") - + random_suffix = generate_random_string() pac_filename = "pac_" .. random_suffix pac_file_path = pac_dir .. pac_filename - + local file = io.open(pac_file_path, "w") if file then file:write(new_pac_content) file:close() - + luci.sys.call("chmod 644 " .. pac_file_path) else result.error = "Failed to write PAC file" @@ -2951,14 +2836,14 @@ function action_generate_pac() else luci.sys.call(string.format("find %s -name 'pac_*' -type f ! -name '%s' -delete 2>/dev/null", pac_dir, pac_filename)) end - + local pac_url = generate_pac_url_with_client_info(pac_filename, random_suffix) result.pac_url = pac_url - + if not auth_exists then result.error = "warning: No authentication configured, please be aware of the risk of information leakage!" end - + luci.http.prepare_content("application/json") luci.http.write_json(result) end @@ -2968,10 +2853,10 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) local client_hostname = luci.http.formvalue("client_hostname") local client_host = luci.http.formvalue("client_host") local client_port = luci.http.formvalue("client_port") - + local request_scheme = "http" local host = "localhost" - + if client_protocol and (client_protocol == "http" or client_protocol == "https") then request_scheme = client_protocol else @@ -2981,7 +2866,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) request_scheme = "https" end end - + if client_host and client_host ~= "" then host = client_host elseif client_hostname and client_hostname ~= "" then @@ -2997,7 +2882,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) local http_host = luci.http.getenv("HTTP_HOST") local server_port = luci.http.getenv("SERVER_PORT") local proxy_ip = daip() - + if http_host and http_host ~= "" then host = http_host elseif server_name and server_name ~= "" then @@ -3018,7 +2903,7 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) end end end - + local random_param = "" if random_suffix and #random_suffix >= 8 then math.randomseed(os.time()) @@ -3029,15 +2914,15 @@ function generate_pac_url_with_client_info(pac_filename, random_suffix) else random_param = random_suffix or tostring(os.time()) end - + local pac_url = request_scheme .. "://" .. host .. "/luci-static/resources/openclash/pac/" .. pac_filename .. "?v=" .. random_param - + return pac_url end function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) local proxy_string = string.format("PROXY %s:%s; DIRECT", proxy_ip, proxy_port) - + local ipv4_networks = {} local ipv4_file = "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" if fs.access(ipv4_file) then @@ -3076,7 +2961,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) end end end - + local ipv6_networks = {} local ipv6_file = "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" if fs.access(ipv6_file) then @@ -3098,7 +2983,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) end end end - + local ipv4_checks = {} for _, net in ipairs(ipv4_networks) do table.insert(ipv4_checks, string.format('isInNet(resolved_ip, "%s", "%s")', net.network, net.mask)) @@ -3107,7 +2992,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) if #ipv4_checks > 0 then ipv4_check_code = "if (" .. table.concat(ipv4_checks, " ||\n ") .. ") {\n return \"DIRECT\";\n }" end - + local ipv6_checks = {} for _, net in ipairs(ipv6_networks) do if net.prefix_len == 128 then @@ -3121,7 +3006,7 @@ function generate_pac_content(proxy_ip, proxy_port, auth_user, auth_pass) if #ipv6_checks > 0 then ipv6_check_code = "if (" .. table.concat(ipv6_checks, " ||\n ") .. ") {\n return \"DIRECT\";\n }" end - + local pac_script = string.format([[ // OpenClash PAC File var _failureCount = 0; @@ -3132,17 +3017,17 @@ var _checkInterval = 300000; // 5分钟 = 300000毫秒 // Access Check function _checkNetworkConnectivity() { var currentTime = Date.now(); - + if (currentTime - _lastCheckTime < _checkInterval) { return !_isProxyDown; } - + _lastCheckTime = currentTime; - + try { var test1 = dnsResolve("www.gstatic.com"); var test2 = dnsResolve("captive.apple.com"); - + if (test1 || test2) { if (_isProxyDown) { _isProxyDown = false; @@ -3172,19 +3057,19 @@ function FindProxyForURL(url, host) { host === "localhost") { return "DIRECT"; } - + // IPv4 var resolved_ip = dnsResolve(host); if (resolved_ip) { %s } - + // IPv6 var resolved_ipv6 = dnsResolveEx(host); if (resolved_ipv6) { %s } - + if (_checkNetworkConnectivity()) { return "%s"; } else { @@ -3196,7 +3081,7 @@ function FindProxyForURLEx(url, host) { return FindProxyForURL(url, host); } ]], ipv4_check_code, ipv6_check_code, proxy_string) - + return pac_script end @@ -3219,26 +3104,36 @@ function action_oc_action() luci.http.status(404, "Config file not found") return end - - uci:set("openclash", "config", "config_path", config_path) + + if uci:get("openclash", "config", "config_path") ~= config_path then + uci:set("openclash", "config", "config_path", config_path) + end end - + if action == "start" then - uci:set("openclash", "config", "enable", "1") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "1" then + uci:set("openclash", "config", "enable", "1") + uci:commit("openclash") + end if not is_running() then + luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash start >/dev/null 2>&1") else luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1") end elseif action == "stop" then - uci:set("openclash", "config", "enable", "0") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "0" then + uci:set("openclash", "config", "enable", "0") + uci:commit("openclash") + end luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash stop >/dev/null 2>&1") elseif action == "restart" then - uci:set("openclash", "config", "enable", "1") - uci:commit("openclash") + if uci:get("openclash", "config", "enable") ~= "1" then + uci:set("openclash", "config", "enable", "1") + uci:commit("openclash") + end + luci.sys.call("ps | grep openclash | grep -v grep | awk '{print $1}' | xargs -r kill -9 >/dev/null 2>&1") luci.sys.call("/etc/init.d/openclash restart >/dev/null 2>&1") else luci.http.status(400, "Invalid action parameter") @@ -3252,12 +3147,12 @@ end function action_config_file_list() local config_files = {} local current_config = "" - + local config_path = fs.uci_get_config("config", "config_path") if config_path then current_config = config_path end - + local config_dir = "/etc/openclash/config/" if fs.access(config_dir) then local files = fs.dir(config_dir) @@ -3277,12 +3172,12 @@ function action_config_file_list() end end end - + table.sort(config_files, function(a, b) return a.mtime > b.mtime end) end - + luci.http.prepare_content("application/json") luci.http.write_json({ config_files = config_files, @@ -3294,9 +3189,9 @@ end function action_upload_config() local upload = luci.http.formvalue("config_file") local filename = luci.http.formvalue("filename") - + luci.http.prepare_content("application/json") - + if not upload or upload == "" then luci.http.write_json({ status = "error", @@ -3304,7 +3199,7 @@ function action_upload_config() }) return end - + if not filename or filename == "" then filename = "upload_" .. os.date("%Y%m%d_%H%M%S") end @@ -3320,10 +3215,10 @@ function action_upload_config() if not string.match(filename, "%.ya?ml$") then filename = filename .. ".yaml" end - + local config_dir = "/etc/openclash/config/" local target_path = config_dir .. filename - + if string.len(upload) == 0 then luci.http.write_json({ status = "error", @@ -3331,7 +3226,7 @@ function action_upload_config() }) return end - + local file_size = string.len(upload) if file_size > 10 * 1024 * 1024 then luci.http.write_json({ @@ -3340,10 +3235,10 @@ function action_upload_config() }) return end - + local yaml_valid = false - local content_start = string.sub(upload, 1, 1000) - + local content_start = string.sub(upload, 1, 5000) + if string.find(content_start, "proxy%-providers:") or string.find(content_start, "proxies:") or string.find(content_start, "rules:") or @@ -3351,7 +3246,7 @@ function action_upload_config() string.find(content_start, "mode:") then yaml_valid = true end - + if not yaml_valid then luci.http.write_json({ status = "error", @@ -3359,17 +3254,17 @@ function action_upload_config() }) return end - + luci.sys.call("mkdir -p " .. config_dir) - + local fp = io.open(target_path, "w") if fp then fp:write(upload) fp:close() - + luci.sys.call(string.format("chmod 644 '%s'", target_path)) luci.sys.call(string.format("chown root:root '%s'", target_path)) - + local written_content = fs.readfile(target_path) if not written_content or string.len(written_content) ~= file_size then fs.unlink(target_path) @@ -3379,7 +3274,7 @@ function action_upload_config() }) return end - + luci.http.write_json({ status = "success", message = "Config file uploaded successfully", @@ -3407,11 +3302,11 @@ function action_config_file_read() local allow = false if config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" then allow = true - elseif config_file:match("^/etc/openclash/overwrite/[^/]+$") then + elseif config_file:match("^/etc/openclash/overwrite/[^/]+$") and not string.find(config_file, "%.%.") then allow = true elseif config_file:match("^/etc/openclash/[^/]+%.ya?ml$") then allow = true - elseif config_file:match("^/etc/openclash/config/[^/]+%.ya?ml$") then + elseif config_file:match("^/etc/openclash/config/[^/]+%.ya?ml$") and not string.find(config_file, "%.%.") then allow = true end @@ -3503,8 +3398,7 @@ function action_config_file_save() local is_overwrite = (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or config_file:match("^/etc/openclash/overwrite/[^/]+$")) if not is_overwrite then - if not string.match(config_file, "^/etc/openclash/config/[^/%.]+%.ya?ml$") then - luci.http.prepare_content("application/json") + if not string.match(config_file, "^/etc/openclash/config/[^/]+%.ya?ml$") or string.find(config_file, "%.%.") then luci.http.write_json({ status = "error", message = "Invalid config file path" @@ -3512,7 +3406,7 @@ function action_config_file_save() return end else - if not (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or config_file:match("^/etc/openclash/overwrite/[^/]+$")) then + if not (config_file == "/etc/openclash/custom/openclash_custom_overwrite.sh" or (config_file:match("^/etc/openclash/overwrite/[^/]+$") and not string.find(config_file, "%.%."))) then luci.http.prepare_content("application/json") luci.http.write_json({ status = "error", @@ -3627,9 +3521,9 @@ function action_add_subscription() local keyword = luci.http.formvalue("keyword") or "" local ex_keyword = luci.http.formvalue("ex_keyword") or "" local de_ex_keyword = luci.http.formvalue("de_ex_keyword") or "" - + luci.http.prepare_content("application/json") - + if not name or not address then luci.http.write_json({ status = "error", @@ -3637,9 +3531,9 @@ function action_add_subscription() }) return end - + local is_valid_url = false - + if sub_convert == "1" then if string.find(address, "^https?://") and not string.find(address, "\n") and not string.find(address, "|") then is_valid_url = true @@ -3654,7 +3548,7 @@ function action_add_subscription() table.insert(links, link:match("^%s*(.-)%s*$")) end end - + for _, link in ipairs(links) do if link and link ~= "" then if string.find(link, "^https?://") or string.find(link, "^[a-zA-Z]+://") then @@ -3674,7 +3568,7 @@ function action_add_subscription() is_valid_url = true end end - + if not is_valid_url then local error_msg if sub_convert == "1" then @@ -3682,14 +3576,14 @@ function action_add_subscription() else error_msg = "Invalid subscription URL format. Only single HTTP/HTTPS subscription URL is supported when subscription conversion is disabled" end - + luci.http.write_json({ status = "error", message = error_msg }) return end - + local exists = false uci:foreach("openclash", "config_subscribe", function(s) if s.name == name then @@ -3697,7 +3591,7 @@ function action_add_subscription() return false end end) - + if exists then luci.http.write_json({ status = "error", @@ -3705,7 +3599,7 @@ function action_add_subscription() }) return end - + local normalized_address = address if sub_convert == "1" and (string.find(address, "\n") or string.find(address, "|")) then local links = {} @@ -3728,7 +3622,7 @@ function action_add_subscription() else normalized_address = address:match("^%s*(.-)%s*$") end - + local section_id = uci:add("openclash", "config_subscribe") if section_id then uci:set("openclash", section_id, "name", name) @@ -3743,7 +3637,7 @@ function action_add_subscription() uci:set("openclash", section_id, "sort", sort) uci:set("openclash", section_id, "node_type", node_type) uci:set("openclash", section_id, "rule_provider", rule_provider) - + if custom_params and custom_params ~= "" then local params = {} for line in custom_params:gmatch("[^\n]+") do @@ -3758,7 +3652,7 @@ function action_add_subscription() end end end - + if keyword and keyword ~= "" then local keywords = {} for line in keyword:gmatch("[^\n]+") do @@ -3773,7 +3667,7 @@ function action_add_subscription() end end end - + if ex_keyword and ex_keyword ~= "" then local ex_keywords = {} for line in ex_keyword:gmatch("[^\n]+") do @@ -3788,7 +3682,7 @@ function action_add_subscription() end end end - + if de_ex_keyword and de_ex_keyword ~= "" then local de_ex_keywords = {} for line in de_ex_keyword:gmatch("[^\n]+") do @@ -3803,9 +3697,9 @@ function action_add_subscription() end end end - + uci:commit("openclash") - + luci.http.write_json({ status = "success", message = "Subscription added successfully", diff --git a/small/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua b/small/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua index 75f05e7cb3..84a254d261 100644 --- a/small/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua +++ b/small/luci-app-openclash/luasrc/model/cbi/openclash/config-overwrite.lua @@ -227,6 +227,7 @@ o.description = translate("Fake-IP is not returned if the matching succeeds when o.default = "blacklist" o:value("blacklist", translate("Blacklist Mode")) o:value("whitelist", translate("Whitelist Mode")) +o:value("rule", translate("Rule Mode")) o:depends("custom_fakeip_filter", "1") custom_fake_black = s:taboption("dns", Value, "custom_fake_filter") @@ -376,13 +377,6 @@ o = s:taboption("smart", Flag, "auto_smart_switch", font_red..bold_on..translate o.description = font_red..bold_on..translate("Auto Switch Url-test and Load-balance Group to Smart Group")..bold_off..font_off o.default = 0 -o = s:taboption("smart", ListValue, "smart_strategy", translate("Node Select Strategy")) -o:value("0", translate("Disable")) -o:value("sticky-sessions", translate("Sticky-sessions")) -o:value("round-robin", translate("Round-robin")) -o.default = "0" -o.description = translate("Before Node Data Collect Completely, The Default is Sticky-sessions") - o = s:taboption("smart", Value, "smart_policy_priority", translate("Policy Priority")) o.default = "" o.placeholder = "Premium:0.9;SG:1.3" diff --git a/small/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua b/small/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua index e5f2b55e3d..5093ef2fbd 100644 --- a/small/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua +++ b/small/luci-app-openclash/luasrc/model/cbi/openclash/custom-dns-edit.lua @@ -138,7 +138,7 @@ function(s) o:value(s.name) end end) - + o:value("DIRECT") o:value("GLOBAL") o:value("Disable", translate("Disable")) diff --git a/small/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua b/small/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua index 73bb627156..e1d0fc6a7f 100644 --- a/small/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua +++ b/small/luci-app-openclash/luasrc/model/cbi/openclash/groups-config.lua @@ -57,7 +57,6 @@ o:value("smart", translate("Smart-Select")) o:value("url-test", translate("URL-Test")) o:value("fallback", translate("Fallback")) o:value("load-balance", translate("Load-Balance")) -o:value("relay", translate("Relay-Traffic")) o = s:option(Value, "name", translate("Group Name")) o.rmempty = false @@ -95,13 +94,6 @@ o:value("consistent-hashing", translate("Consistent-hashing")) o:value("sticky-sessions", translate("Sticky-sessions")) o:depends("type", "load-balance") -o = s:option(ListValue, "strategy_smart", translate("Strategy Type")) -o.rmempty = true -o.description = translate("Choose The Smart's Strategy Type") -o:value("round-robin", translate("Round-robin")) -o:value("sticky-sessions", translate("Sticky-sessions")) -o:depends("type", "smart") - o = s:option(ListValue, "uselightgbm", translate("Uselightgbm")) o.description = translate("Use LightGBM Model For Smart Group Weight Prediction") o:value("false", translate("Disable")) diff --git a/small/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua b/small/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua index 0d64e1bf93..6698bddd65 100644 --- a/small/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua +++ b/small/luci-app-openclash/luasrc/model/cbi/openclash/servers-config.lua @@ -148,6 +148,7 @@ o:value("tuic", translate("Tuic")) o:value("snell", translate("Snell")) o:value("mieru", translate("Mieru")) o:value("anytls", translate("AnyTLS")) +o:value("sudoku", translate("Sudoku")) o:value("socks5", translate("Socks5")) o:value("http", translate("HTTP(S)")) o:value("direct", translate("DIRECT")) @@ -174,6 +175,7 @@ o:depends("type", "wireguard") o:depends("type", "tuic") o:depends("type", "mieru") o:depends("type", "anytls") +o:depends("type", "sudoku") o:depends("type", "snell") o:depends("type", "socks5") o:depends("type", "http") @@ -194,6 +196,7 @@ o:depends("type", "wireguard") o:depends("type", "tuic") o:depends("type", "mieru") o:depends("type", "anytls") +o:depends("type", "sudoku") o:depends("type", "snell") o:depends("type", "socks5") o:depends("type", "http") @@ -223,6 +226,46 @@ o:depends("type", "hysteria2") o:depends("type", "mieru") o:depends("type", "anytls") +-- [[ Sudoku ]]-- +o = s:option(Value, "sudoku_key", translate("Key")) +o.rmempty = true +o.placeholder = translate("") +o:depends("type", "sudoku") + +o = s:option(ListValue, "aead_method", translate("Aead-method")) +o.rmempty = true +o.default = "chacha20-poly1305" +o:value("chacha20-poly1305") +o:value("aes-128-gcm") +o:value("none") +o:depends("type", "sudoku") + +o = s:option(Value, "padding_min", translate("Padding-min")) +o.rmempty = true +o.datatype = "uinteger" +o.placeholder = translate("2") +o:depends("type", "sudoku") + +o = s:option(Value, "padding_max", translate("Padding-max")) +o.rmempty = true +o.datatype = "uinteger" +o.placeholder = translate("7") +o:depends("type", "sudoku") + +o = s:option(ListValue, "table_type", translate("Table-type")) +o.rmempty = true +o.default = "prefer_ascii" +o:value("prefer_ascii") +o:value("prefer_entropy") +o:depends("type", "sudoku") + +o = s:option(ListValue, "http_mask", translate("Http-mask")) +o.rmempty = true +o.default = "true" +o:value("true") +o:value("false") +o:depends("type", "sudoku") + -- [[ Mieru ]]-- o = s:option(Value, "port_range", translate("Port Range")) o.datatype = "portrange" @@ -1118,16 +1161,26 @@ function o.validate(self, value) return value end +o = s:option(Value, "dialer_proxy", translate("Dialer-proxy")) +o.rmempty = true +o.description = font_red..bold_on..translate("The added Dialer Proxy or Group Must Exist")..bold_off..font_off +m.uci:foreach("openclash", "groups", +function(s) + if s.name ~= "" and s.name ~= nil then + o:value(s.name) + end +end) + o = s:option(DynamicList, "groups", translate("Proxy Group (Support Regex)")) o.description = font_red..bold_on..translate("No Need Set when Config Create, The added Proxy Groups Must Exist")..bold_off..font_off o.rmempty = true o:value("all", translate("All Groups")) m.uci:foreach("openclash", "groups", - function(s) - if s.name ~= "" and s.name ~= nil then - o:value(s.name) - end - end) +function(s) + if s.name ~= "" and s.name ~= nil then + o:value(s.name) + end +end) local t = { {Commit, Back} diff --git a/small/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua b/small/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua index 629d66131e..fad304bd9f 100644 --- a/small/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua +++ b/small/luci-app-openclash/luasrc/model/cbi/openclash/settings.lua @@ -252,7 +252,7 @@ ip_ac:value("localnetwork", translate("Local Network")) o = s2:option(Value, "src_port", translate("Internal ports")) o.datatype = "or(port, portrange)" o.placeholder = translate("5000 or 1234-2345") -o.rmempty = false +o.rmempty = true o = s2:option(ListValue, "proto", translate("Proto")) o:value("udp", translate("UDP")) @@ -299,10 +299,10 @@ local function ip_compare(a, b) end return 0 end - + local a_is_ipv4 = datatype.ip4addr(a.dest) local b_is_ipv4 = datatype.ip4addr(b.dest) - + if a_is_ipv4 and not b_is_ipv4 then return true elseif not a_is_ipv4 and b_is_ipv4 then @@ -318,14 +318,20 @@ local all_neighbors = {} luci.ip.neighbors({ family = 4 }, function(n) if n.mac and n.dest then - table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, family = 4}) + if n.hostname then + hostname = " [".. n.hostname .."]" + end + table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, hostname = hostname or "", family = 4}) end end) if string.len(SYS.exec("/usr/share/openclash/openclash_get_network.lua 'gateway6'")) ~= 0 then luci.ip.neighbors({ family = 6 }, function(n) if n.mac and n.dest then - table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, family = 6}) + if n.hostname then + hostname = " [".. n.hostname .."]" + end + table.insert(all_neighbors, {dest = n.dest:string(), mac = n.mac, hostname = hostname or "", family = 6}) end end) end @@ -334,16 +340,20 @@ table.sort(all_neighbors, ip_compare) local mac_ip_map = {} local mac_order = {} +local mac_hostname_map = {} for _, item in ipairs(all_neighbors) do - ip_b:value(item.dest) - ip_w:value(item.dest) - ip_ac:value(item.dest) + ip_b:value(item.dest, "%s%s" %{ item.dest, item.hostname }) + ip_w:value(item.dest, "%s%s" %{ item.dest, item.hostname }) + ip_ac:value(item.dest, "%s%s" %{ item.dest, item.hostname }) if not mac_ip_map[item.mac] then mac_ip_map[item.mac] = {} table.insert(mac_order, item.mac) end table.insert(mac_ip_map[item.mac], item.dest) + if not mac_hostname_map[item.mac] then + mac_hostname_map[item.mac] = item.hostname + end end for _, mac in ipairs(mac_order) do @@ -366,8 +376,8 @@ for _, mac in ipairs(mac_order) do end end) local ip_str = table.concat(ips, "|") - mac_b:value(mac, "%s (%s)" %{ mac, ip_str }) - mac_w:value(mac, "%s (%s)" %{ mac, ip_str }) + mac_b:value(mac, "%s%s (%s)" %{ mac, mac_hostname_map[mac], ip_str }) + mac_w:value(mac, "%s%s (%s)" %{ mac, mac_hostname_map[mac], ip_str }) end ---- Traffic Control diff --git a/small/luci-app-openclash/luasrc/view/openclash/config_edit.htm b/small/luci-app-openclash/luasrc/view/openclash/config_edit.htm index 70fc3625ad..1b7ceeff0a 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/config_edit.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/config_edit.htm @@ -573,7 +573,7 @@
- +
@@ -586,7 +586,7 @@ - + @@ -747,7 +747,7 @@
<%:URI and subscription address is supported when online subscription conversion enabled, multiple links should be one per line or separated by%> |
- +
@@ -958,64 +958,64 @@ var ConfigUploader = { selectedFile: null, isProcessing: false, currentMode: 'file', - + init: function() { this.overlay = document.getElementById('config-upload-overlay'); this.model = document.getElementById('config-upload-model'); - + if (!this.overlay || !this.model) { return; } - + this.bindEvents(); }, - + bindEvents: function() { var self = this; var uploadZone = document.getElementById('upload-zone'); var fileInput = document.getElementById('config-file-input'); - + document.getElementById('upload-mode-file').addEventListener('click', function() { self.switchMode('file'); }); - + document.getElementById('upload-mode-subscribe').addEventListener('click', function() { self.switchMode('subscribe'); }); - + uploadZone.addEventListener('click', function() { if (!self.isProcessing && self.currentMode === 'file') { fileInput.click(); } }); - + fileInput.addEventListener('change', function(e) { if (e.target.files.length > 0) { self.handleFileSelect(e.target.files[0]); } }); - + uploadZone.addEventListener('dragover', function(e) { e.preventDefault(); if (!self.isProcessing && self.currentMode === 'file') { uploadZone.classList.add('dragover'); } }); - + uploadZone.addEventListener('dragleave', function(e) { e.preventDefault(); uploadZone.classList.remove('dragover'); }); - + uploadZone.addEventListener('drop', function(e) { e.preventDefault(); uploadZone.classList.remove('dragover'); - + if (!self.isProcessing && self.currentMode === 'file' && e.dataTransfer.files.length > 0) { self.handleFileSelect(e.dataTransfer.files[0]); } }); - + var subscribeUrlInput = document.getElementById('subscribe-url-input'); var filenameInput = document.getElementById('config-filename-input'); var subscribeUaSelect = document.getElementById('subscribe-ua-input'); @@ -1033,9 +1033,9 @@ var ConfigUploader = { self.updateSubmitButton(); self.autoFillConfigName(); }); - + filenameInput.addEventListener('input', this.updateSubmitButton.bind(this)); - + subscribeUaSelect.addEventListener('change', function() { if (this.value === 'custom') { subscribeUaCustom.style.display = 'block'; @@ -1078,7 +1078,7 @@ var ConfigUploader = { customTemplateGroup.style.display = 'none'; } }); - + document.getElementById('config-upload-submit').addEventListener('click', function() { if (self.currentMode === 'file') { self.uploadFile(); @@ -1086,37 +1086,37 @@ var ConfigUploader = { self.processSubscription(); } }); - + document.getElementById('config-upload-cancel').addEventListener('click', function() { if (!self.isProcessing) { self.hide(); } }); - + document.getElementById('config-upload-close').addEventListener('click', function() { if (!self.isProcessing) { self.hide(); } }); - + this.overlay.addEventListener('click', function(e) { if (e.target === self.overlay && !self.isProcessing) { self.hide(); } }); - + document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && !self.isProcessing && self.overlay.classList.contains('show')) { self.hide(); } }); }, - + show: function() { this.overlay.classList.add('show'); this.reset(); }, - + hide: function() { this.overlay.classList.remove('show'); this.reset(); @@ -1128,15 +1128,15 @@ var ConfigUploader = { document.getElementById('convert-address-input').value = 'https://api.dler.io/sub'; document.getElementById('convert-address-custom').style.display = 'none'; document.getElementById('convert-address-custom').value = ''; - + var templateSelect = document.getElementById('template-select'); if (templateSelect && templateSelect.options.length > 1) { templateSelect.selectedIndex = 0; } - + document.getElementById('custom-template-group').style.display = 'none'; document.getElementById('custom-template-input').value = ''; - + document.getElementById('emoji-enable').checked = false; document.getElementById('udp-enable').checked = false; document.getElementById('skip-cert-verify').checked = false; @@ -1144,7 +1144,7 @@ var ConfigUploader = { document.getElementById('node-type-enable').checked = false; document.getElementById('rule-provider-enable').checked = false; document.getElementById('custom-params-input').value = ''; - + document.getElementById('keyword-input').value = ''; document.getElementById('exclude-keyword-input').value = ''; document.getElementById('exclude-expire').checked = false; @@ -1152,42 +1152,42 @@ var ConfigUploader = { document.getElementById('exclude-tg').checked = false; document.getElementById('exclude-website').checked = false; }, - + reset: function() { this.selectedFile = null; this.isProcessing = false; this.currentMode = 'file'; - + this.switchMode('file'); document.getElementById('config-filename-input').value = ''; document.getElementById('subscribe-url-input').value = ''; document.getElementById('subscribe-ua-input').value = 'clash.meta'; document.getElementById('subscribe-ua-custom').style.display = 'none'; - + document.getElementById('advanced-options-enable').checked = false; document.getElementById('advanced-options-container').style.display = 'none'; this.resetAdvancedOptions(); - + var templateSelect = document.getElementById('template-select'); if (templateSelect && templateSelect.options.length > 1) { templateSelect.selectedIndex = 0; } - + document.getElementById('upload-progress').style.display = 'none'; document.getElementById('config-upload-status-text').textContent = '<%:Ready to add config%>'; this.updateSubmitButton(); }, - + switchMode: function(mode) { this.currentMode = mode; - + var modeFileTab = document.getElementById('upload-mode-file'); var modeSubscribeTab = document.getElementById('upload-mode-subscribe'); var modeFileContent = document.getElementById('mode-file-content'); var modeSubscribeContent = document.getElementById('mode-subscribe-content'); var statusText = document.getElementById('config-upload-status-text'); var uploadZone = document.getElementById('upload-zone'); - + if (mode === 'file') { modeFileTab.classList.add('active'); modeSubscribeTab.classList.remove('active'); @@ -1201,49 +1201,49 @@ var ConfigUploader = { modeSubscribeContent.style.display = 'block'; statusText.textContent = '<%:Ready to add subscription%>'; } - + this.selectedFile = null; uploadZone.classList.remove('has-file'); uploadZone.querySelector('.upload-primary').textContent = '<%:Click to select file or drag and drop%>'; uploadZone.querySelector('.upload-secondary').textContent = '<%:Support YAML file, max size 10MB%>'; - + this.updateSubmitButton(); }, - + handleFileSelect: function(file) { this.selectedFile = file; var uploadZone = document.getElementById('upload-zone'); var filenameInput = document.getElementById('config-filename-input'); var statusText = document.getElementById('config-upload-status-text'); - + if (!file) { uploadZone.classList.remove('has-file'); this.updateSubmitButton(); statusText.textContent = '<%:Ready to upload file%>'; return; } - + if (!file.name.match(/\.(yaml|yml)$/i)) { alert('<%:Please select a YAML file%>'); return; } - + if (file.size > 10 * 1024 * 1024) { alert('<%:File size exceeds 10MB limit%>'); return; } - + uploadZone.classList.add('has-file'); uploadZone.querySelector('.upload-primary').textContent = '<%:File selected:%> ' + file.name; uploadZone.querySelector('.upload-secondary').textContent = '<%:Size:%> ' + this.formatFileSize(file.size); - + var defaultName = file.name.replace(/\.(yaml|yml)$/i, ''); filenameInput.value = defaultName; - + this.updateSubmitButton(); statusText.textContent = '<%:File ready to upload%>'; }, - + formatFileSize: function(bytes) { if (bytes === 0) return '0 B'; var k = 1024; @@ -1251,19 +1251,19 @@ var ConfigUploader = { var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; }, - + updateSubmitButton: function() { var filename = document.getElementById('config-filename-input').value.trim(); var submitBtn = document.getElementById('config-upload-submit'); var isValid = false; - + if (this.currentMode === 'file') { isValid = this.selectedFile && filename; } else if (this.currentMode === 'subscribe') { var url = document.getElementById('subscribe-url-input').value.trim(); var advancedEnabled = document.getElementById('advanced-options-enable').checked; var subConvert = advancedEnabled && document.getElementById('sub-convert-enable').checked; - + if (url && filename) { if (subConvert) { if (url.indexOf('\n') !== -1 || url.indexOf('|') !== -1) { @@ -1283,39 +1283,39 @@ var ConfigUploader = { } } } - + submitBtn.disabled = !isValid || this.isProcessing; }, - + uploadFile: function() { if (!this.selectedFile || this.isProcessing) return; - + var filename = document.getElementById('config-filename-input').value.trim(); if (!filename) { alert('<%:Please enter a filename%>'); return; } - + if (!/^[a-zA-Z0-9_\-\s\u4e00-\u9fa5\.]+$/.test(filename)) { alert('<%:Filename contains invalid characters%>'); return; } - + var self = this; this.isProcessing = true; - + var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var statusText = document.getElementById('config-upload-status-text'); var progressContainer = document.getElementById('upload-progress'); var progressFill = document.getElementById('upload-progress-fill'); var progressText = document.getElementById('upload-progress-text'); - + submitBtn.disabled = true; cancelBtn.disabled = true; statusText.textContent = '<%:Uploading...%>'; progressContainer.style.display = 'block'; - + var progress = 0; var progressInterval = setInterval(function() { if (progress < 90) { @@ -1324,22 +1324,22 @@ var ConfigUploader = { progressText.textContent = '<%:Uploading...%> ' + Math.floor(Math.min(progress, 90)) + '%'; } }, 100); - + var reader = new FileReader(); reader.onload = function(e) { var fileContent = e.target.result; - + var formData = new FormData(); formData.append('config_file', fileContent); formData.append('filename', filename); - + fetch('<%=luci.dispatcher.build_url("admin", "services", "openclash", "upload_config")%>', { method: 'POST', body: formData }) .then(function(response) { clearInterval(progressInterval); - + if (!response.ok) { throw new Error('HTTP error! status: ' + response.status); } @@ -1348,10 +1348,10 @@ var ConfigUploader = { .then(function(data) { progressFill.style.width = '100%'; progressText.textContent = '<%:Upload completed%> 100%'; - + if (data.status === 'success') { statusText.textContent = '<%:Upload successful%>'; - + setTimeout(function() { self.hide(); if (typeof ConfigFileManager !== 'undefined' && ConfigFileManager.refreshConfigList) { @@ -1366,24 +1366,24 @@ var ConfigUploader = { self.handleError('<%:Upload failed:%> ' + error.message); }); }; - + reader.onerror = function() { clearInterval(progressInterval); self.handleError('<%:Failed to read file%>'); }; - + reader.readAsText(this.selectedFile, 'UTF-8'); }, - + processSubscription: function() { var url = document.getElementById('subscribe-url-input').value.trim(); var filename = document.getElementById('config-filename-input').value.trim(); var userAgent = document.getElementById('subscribe-ua-input').value; var subscribeUaCustom = document.getElementById('subscribe-ua-custom'); - + var advancedEnabled = document.getElementById('advanced-options-enable').checked; var subConvert = advancedEnabled && document.getElementById('sub-convert-enable').checked; - + var convertAddress = 'https://api.dler.io/sub'; var template = ''; var emoji = false; @@ -1396,7 +1396,7 @@ var ConfigUploader = { var keywords = ''; var excludeKeywords = ''; var excludeDefaults = []; - + if (advancedEnabled) { convertAddress = document.getElementById('convert-address-input').value; var convertAddressCustom = document.getElementById('convert-address-custom').value; @@ -1411,32 +1411,32 @@ var ConfigUploader = { customParams = document.getElementById('custom-params-input').value; keywords = document.getElementById('keyword-input').value; excludeKeywords = document.getElementById('exclude-keyword-input').value; - + if (document.getElementById('exclude-expire').checked) excludeDefaults.push('过期时间'); if (document.getElementById('exclude-traffic').checked) excludeDefaults.push('剩余流量'); if (document.getElementById('exclude-tg').checked) excludeDefaults.push('TG群'); if (document.getElementById('exclude-website').checked) excludeDefaults.push('官网'); - + if (convertAddress === 'custom') { convertAddress = convertAddressCustom.trim() || 'https://api.dler.io/sub'; } - + if (template === '0') { template = customTemplate.trim(); } } - + if (userAgent === 'custom') { userAgent = subscribeUaCustom.value.trim() || 'clash.meta'; } - + if (!url || !filename) { alert('<%:Please enter subscription URL and config name%>'); return; } - + var isValidFormat = false; - + if (subConvert) { if (url.indexOf('\n') !== -1 || url.indexOf('|') !== -1) { var links = []; @@ -1445,7 +1445,7 @@ var ConfigUploader = { } else { links = url.split('|'); } - + for (var i = 0; i < links.length; i++) { var link = links[i].trim(); if (link && (/^https?:\/\//.test(link) || /^[a-zA-Z]+:\/\//.test(link))) { @@ -1463,7 +1463,7 @@ var ConfigUploader = { isValidFormat = true; } } - + if (!isValidFormat) { var errorMsg = subConvert ? '<%:Invalid subscription URL format. Support HTTP/HTTPS subscription URLs or protocol links, can be separated by newlines or |%>' : @@ -1471,7 +1471,7 @@ var ConfigUploader = { alert(errorMsg); return; } - + var requestData = { name: filename, address: url, @@ -1490,22 +1490,22 @@ var ConfigUploader = { ex_keyword: excludeKeywords, de_ex_keyword: excludeDefaults.join('\n') }; - + var self = this; this.isProcessing = true; - + var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var statusText = document.getElementById('config-upload-status-text'); var progressContainer = document.getElementById('upload-progress'); var progressFill = document.getElementById('upload-progress-fill'); var progressText = document.getElementById('upload-progress-text'); - + submitBtn.disabled = true; cancelBtn.disabled = true; statusText.textContent = '<%:Adding subscription...%>'; progressContainer.style.display = 'block'; - + var progress = 0; var progressInterval = setInterval(function() { if (progress < 90) { @@ -1514,7 +1514,7 @@ var ConfigUploader = { progressText.textContent = '<%:Processing...%> ' + Math.floor(Math.min(progress, 90)) + '%'; } }, 100); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "add_subscription")%>', { name: filename, address: url, @@ -1538,12 +1538,12 @@ var ConfigUploader = { filename: filename }, function(x2, data2) { clearInterval(progressInterval); - + if (x2 && x2.status == 200) { progressFill.style.width = '100%'; progressText.textContent = '<%:Subscription added successfully%> 100%'; statusText.textContent = '<%:Subscription added successfully%>'; - + setTimeout(function() { self.hide(); if (typeof ConfigFileManager !== 'undefined' && ConfigFileManager.refreshConfigList) { @@ -1564,34 +1564,34 @@ var ConfigUploader = { autoFillConfigName: function() { var url = document.getElementById('subscribe-url-input').value.trim(); var filenameInput = document.getElementById('config-filename-input'); - + if (!filenameInput.value.trim() && url) { try { var urlObj = new URL(url); var hostname = urlObj.hostname; - + var configName = hostname .replace(/^(www\.|api\.|sub\.|subscribe\.)/, '') .replace(/\.(com|net|org|cn|io|me|cc|xyz|top)$/, '') .replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_') .replace(/_{2,}/g, '_') .replace(/^_|_$/g, ''); - + if (!configName || configName.length < 2) { configName = 'subscription_' + Date.now().toString().slice(-6); } - + if (configName.length > 30) { configName = configName.substring(0, 30); } - + filenameInput.value = configName; this.updateSubmitButton(); } catch (e) { } } }, - + handleError: function(message) { var statusText = document.getElementById('config-upload-status-text'); var progressText = document.getElementById('upload-progress-text'); @@ -1599,13 +1599,13 @@ var ConfigUploader = { var submitBtn = document.getElementById('config-upload-submit'); var cancelBtn = document.getElementById('config-upload-cancel'); var progressContainer = document.getElementById('upload-progress'); - + statusText.textContent = '<%:Process failed%>'; progressText.textContent = '<%:Process failed%>'; progressFill.style.width = '0%'; - + alert(message); - + this.isProcessing = false; submitBtn.disabled = false; cancelBtn.disabled = false; diff --git a/small/luci-app-openclash/luasrc/view/openclash/developer.htm b/small/luci-app-openclash/luasrc/view/openclash/developer.htm index 80510e3423..f94f05d9eb 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/developer.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/developer.htm @@ -173,18 +173,18 @@ .oc .developer-grid { gap: 10px 35px; } - + .oc .developer-avatar { width: 60px; height: 60px; border-width: 3px; } - + .oc .developer-avatar-container { min-width: 60px; width: 60px; } - + .oc .developer-label { font-size: 11px; padding: 3px 8px; @@ -196,18 +196,18 @@ .oc .developer-grid { gap: 6px 25px; } - + .oc .developer-avatar { width: 45px; height: 45px; border-width: 2px; } - + .oc .developer-avatar-container { min-width: 45px; width: 45px; } - + .oc .developer-label { font-size: 9px; padding: 2px 4px; @@ -219,17 +219,17 @@ .oc .developer-grid { gap: 4px 20px; } - + .oc .developer-avatar { width: 40px; height: 40px; } - + .oc .developer-avatar-container { min-width: 40px; width: 40px; } - + .oc .developer-label { font-size: 8px; padding: 1px 4px; @@ -241,17 +241,17 @@ .oc .developer-grid { gap: 3px 15px; } - + .oc .developer-avatar { width: 35px; height: 35px; } - + .oc .developer-avatar-container { min-width: 35px; width: 35px; } - + .oc .developer-label { font-size: 7px; padding: 1px 3px; @@ -263,17 +263,17 @@ .oc .developer-grid { gap: 2px 10px; } - + .oc .developer-avatar { width: 30px; height: 30px; } - + .oc .developer-avatar-container { min-width: 30px; width: 30px; } - + .oc .developer-label { font-size: 6px; padding: 1px 2px; @@ -364,7 +364,7 @@ window.addEventListener('resize', function() { setAvatars(); }); - + function Dreamacro_rediret() { window.open('https://github.com/Dreamacro'); } @@ -410,7 +410,7 @@ function MetaCubeX_rediret() { window.open('https://github.com/MetaCubeX'); } - + function imgerrorfun(imgobj, imgSrc) { setTimeout(function() { imgobj.src = imgSrc; diff --git a/small/luci-app-openclash/luasrc/view/openclash/dlercloud.htm b/small/luci-app-openclash/luasrc/view/openclash/dlercloud.htm index d8f552b654..5d1ed41f65 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/dlercloud.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/dlercloud.htm @@ -428,28 +428,28 @@ .oc .dler-main-container { width: calc(100% - 32px); } - + .oc .card .additional.collapsed { width: 140px; } - + .oc .card .additional .user-card { width: 140px; } - + .oc .card .additional .more-info h1 { font-size: 1.8rem; } - + .oc .card .additional .coords { font-size: 0.95rem; } - + .oc .card .general { margin-left: 120px; padding-right: 8px; } - + .oc .card .general .more { bottom: 6px; padding-right: 12px; @@ -461,34 +461,34 @@ .oc .dler-main-container { width: 100%; } - + .oc .card .additional.collapsed { width: 125px; } - + .oc .card .additional .user-card { width: 125px; } - + .oc .card .additional .more-info h1 { font-size: 1.5rem; } - + .oc .card .additional .coords { font-size: 0.8rem; } - + .oc .card .general { margin-left: 110px; padding-right: 6px; } - + .oc .card .general h1 { font-size: 24px; line-height: 30px; margin: 0; } - + .oc .card .general .dler-info { grid-template-columns: 1fr; grid-template-rows: auto auto auto; @@ -496,31 +496,31 @@ padding-right: 8px; height: 50%; } - + .oc .card .general .dler-info-right { justify-content: flex-start; padding-top: 8px; gap: 12px; } - + .oc .card .general .btn { width: 80px !important; height: 80px !important; font-size: 14px; padding: 0 !important; } - + .oc .card .general .dler-title { font-size: 14px; width: 50%; } - + .oc .card .general .dler-result, .oc .card .general .dler-result2 { font-size: 14px; width: 50%; } - + .oc .card .general .more { bottom: 4px; padding-right: 10px; @@ -536,23 +536,23 @@ .oc .center { padding: 8px; } - + .oc .card .additional.collapsed { width: 115px; } - + .oc .card .additional .user-card { width: 115px; } - + .oc .card .additional .more-info h1 { font-size: 1.3rem; } - + .oc .card .additional .coords { font-size: 0.7rem; } - + .oc .card .general { margin-left: 120px; padding-right: 4px; @@ -561,7 +561,7 @@ .oc .card .general .dler-info { height: 50%; } - + .oc .card .general h1 { font-size: 18px; line-height: 26px; @@ -578,7 +578,7 @@ font-size: 12px; width: 50%; } - + .oc .card .general .more { bottom: 2px; padding-right: 8px; @@ -637,7 +637,7 @@

- +

@@ -654,7 +654,7 @@

- +
@@ -695,7 +695,7 @@ obj.classList.remove('collapsed'); obj.classList.add('expanded'); }); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_info")%>', null, function(x, status) { if (x && x.status == 200 && status.dler_info != "error") { dler_plan.innerHTML = status.dler_info.plan; @@ -721,7 +721,7 @@ show_less(); } }); - + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_info")%>', null, function(x, status) { if (x && x.status == 200 && status.dler_info != "error") { dler_plan.innerHTML = status.dler_info.plan; @@ -752,7 +752,7 @@ show_less(); } }); - + function dler_checkin_btn(btn) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "dler_checkin")%>', null, function(x, status) { @@ -774,13 +774,13 @@ } }); } - + function web_dler() { url='https://bit.ly/32mrABp'; window.open(url); } - + function show_more() { if (obj.classList.contains('expanded')) { @@ -804,7 +804,7 @@ obj.classList.add('expanded'); obj.classList.remove('collapsed'); } - + var rdmdl = Math.floor(Math.random() * 6) + 1; if (rdmdl == 1) { dler_it.innerHTML = '<%:Simple & trustworthy%>'; diff --git a/small/luci-app-openclash/luasrc/view/openclash/log.htm b/small/luci-app-openclash/luasrc/view/openclash/log.htm index f775da0407..f0286ef982 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/log.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/log.htm @@ -148,7 +148,7 @@ ul{ .radio-button input[type="radio"] { display: none; } - + .radio-button label { display: flex; align-items: center; @@ -358,7 +358,7 @@ function createAndDownloadFile(fileName, content) { function download_log(){ var dt = new Date(); var timestamp = dt.getFullYear()+"-"+(dt.getMonth()+1)+"-"+dt.getDate()+"-"+dt.getHours()+"-"+dt.getMinutes()+"-"+dt.getSeconds(); - + var oc_content = ""; if (typeof oc_editor !== 'undefined' && oc_editor) { oc_content = oc_editor.getValue(); @@ -367,7 +367,7 @@ function download_log(){ } else if (lv && lv.innerHTML) { oc_content = lv.innerHTML; } - + var core_content = ""; if (typeof core_editor !== 'undefined' && core_editor) { core_content = core_editor.getValue(); @@ -376,15 +376,15 @@ function download_log(){ } else if (cl && cl.innerHTML) { core_content = cl.innerHTML; } - + oc_content = oc_content.split('\n').filter(function(line) { return line.indexOf("】订阅的下载链接为【") === -1 && line.indexOf("】Downloading URL【") === -1; }).join('\n'); - + if (!oc_content.trim() && !core_content.trim()) { return; } - + var downloadContent = ""; if (oc_content.trim()) { downloadContent += "<%:OpenClash Log%>:\n" + oc_content + "\n\n"; @@ -392,7 +392,7 @@ function download_log(){ if (core_content.trim()) { downloadContent += "<%:Core Log%>:\n" + core_content; } - + createAndDownloadFile("OpenClash-"+timestamp+".log", downloadContent); return; }; @@ -418,15 +418,15 @@ function line_tolocal(str) { var trans_local = new Array(); var local_count = 0; - + str.trim().split('\n').forEach(function(v, i) { var regex = /(time=)"([^"]*)"/g; var res = regex.exec(v); - + try { if (res) { var dt = new Date(res[2]); - + if (!isNaN(dt.getTime())) { if (v.indexOf("level=") != -1) { var log_info = v.substring(res[2].length + 7); @@ -443,7 +443,7 @@ function line_tolocal(str) { } else { try { var dtt = new Date(v.substring(0, 19)); - + if (!isNaN(dtt.getTime()) && v.substring(0, 19).match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)) { trans_local[local_count] = v; local_count++; @@ -461,7 +461,7 @@ function line_tolocal(str) { local_count++; } }); - + return trans_local; }; @@ -470,16 +470,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv var isAtTop = false; var cursorPos = null; var selectionRange = null; - + var isFirstLoad = !currentContent || currentContent.trim() === ""; - + if (isEditor && target) { scrollPosition = target.getScrollInfo(); isAtTop = (scrollPosition.top < 20); - + if (target.hasFocus()) { cursorPos = target.getCursor(); - + if (cursorPos.line === 0) { cursorPos = null; selectionRange = null; @@ -499,7 +499,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv scrollPosition = target.scrollTop; isAtTop = (target.scrollTop < 20); } - + if ((target === oc_editor && animatingOC) || (target === core_editor && animatingCore) || !isActiveTab) { var content = ""; var lines = newLines.slice().reverse(); @@ -507,33 +507,33 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv content += lines[i] + "\n"; } content = content + (currentContent || ""); - + var allLines = content.split("\n"); if (allLines.length > 2000) { allLines = allLines.slice(0, 1999); allLines.push("..."); content = allLines.join("\n"); } - + if (isEditor) { var addedLines = lines.length; target.setValue(content); - + if (!isAtTop && scrollPosition) { if (cursorPos) { cursorPos.line += addedLines; target.setCursor(cursorPos); - + target.scrollIntoView({line: cursorPos.line, ch: cursorPos.ch}, 300); } else { target.scrollTo(scrollPosition.left, scrollPosition.top); } - + if (selectionRange) { selectionRange.from.line += addedLines; selectionRange.to.line += addedLines; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -545,7 +545,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv target.setCursor({line: 0, ch: 0}); } } - + target.refresh(); } else { var oldScrollTop = scrollPosition; @@ -556,16 +556,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } return; } - + if (target === oc_editor || target === lv) { animatingOC = true; } else { animatingCore = true; } - + var totalLines = newLines.length; var batchSize, interval; - + if (totalLines <= 10) { batchSize = 2; interval = 90; @@ -588,12 +588,12 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv batchSize = 250; interval = 5; } - + var displayedContent = currentContent || ""; var logLines = newLines.slice(); var currentBatchCount = 0; var accumulatedContent = ""; - + function displayNextBatch() { if (currentBatchCount >= logLines.length) { if (target === oc_editor || target === lv) { @@ -601,16 +601,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } else { animatingCore = false; } - + if (isEditor && !isAtTop && cursorPos) { cursorPos.line += logLines.length; target.setCursor(cursorPos); - + if (selectionRange) { selectionRange.from.line += logLines.length; selectionRange.to.line += logLines.length; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -621,31 +621,31 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } return; } - + var nextBatchSize = Math.min(batchSize, logLines.length - currentBatchCount); - + var batchLines = logLines.slice(currentBatchCount, currentBatchCount + nextBatchSize).reverse(); currentBatchCount += nextBatchSize; - + if (accumulatedContent) { accumulatedContent = batchLines.join("\n") + "\n" + accumulatedContent; } else { accumulatedContent = batchLines.join("\n"); } - + var content = accumulatedContent + (displayedContent ? "\n" + displayedContent : ""); - + var contentLines = content.split("\n"); if (contentLines.length > 2000) { contentLines = contentLines.slice(0, 1999); contentLines.push("..."); content = contentLines.join("\n"); } - + if (isEditor) { var currentScrollInfo = isAtTop ? null : target.getScrollInfo(); target.setValue(content); - + if (!isAtTop && currentScrollInfo) { target.scrollTo(currentScrollInfo.left, currentScrollInfo.top); } @@ -657,7 +657,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv target.scrollTop = currentScrollTop; } } - + if (currentBatchCount < logLines.length) { setTimeout(displayNextBatch, interval); } else { @@ -666,16 +666,16 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } else { animatingCore = false; } - + if (isEditor && !isAtTop && cursorPos) { cursorPos.line += logLines.length; target.setCursor(cursorPos); - + if (selectionRange) { selectionRange.from.line += logLines.length; selectionRange.to.line += logLines.length; target.setSelection(selectionRange.from, selectionRange.to); - + target.scrollIntoView({ from: selectionRange.from, to: selectionRange.to @@ -686,7 +686,7 @@ function smoothlyDisplayLogs(newLines, target, isEditor, currentContent, isActiv } } } - + displayNextBatch(); } @@ -702,11 +702,11 @@ function poll_log(){ r = setTimeout("poll_log()", 2000); return; } - + if (status.len) { log_len = status.len; } - + var activeTabId = 0; var titles = document.getElementsByName('tab-header'); for(var i=0; i 0) { if (oc_editor) { var currentContent = oc_editor.getValue(); @@ -729,10 +729,10 @@ function poll_log(){ } } } - + if (status.core_log && status.core_log !== "") { var core_logs = line_tolocal(status.core_log); - + if (core_logs && core_logs.length > 0) { if (core_editor) { var currentCoreContent = core_editor.getValue(); @@ -778,7 +778,7 @@ window.onload = function(){ } }; } - + li.onclick = handleTabSwitch(li); li.ontouchstart = handleTabSwitch(li); } diff --git a/small/luci-app-openclash/luasrc/view/openclash/myip.htm b/small/luci-app-openclash/luasrc/view/openclash/myip.htm index ec4469a347..d5d845c411 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/myip.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/myip.htm @@ -5,7 +5,7 @@ - + @@ -13,7 +13,7 @@ - + @@ -419,48 +419,48 @@ --card-item-padding: 8px 6px; --card-item-min-height: 80px; } - + .oc .myip-content-grid { grid-template-columns: 1fr; } - + .oc .myip-section-title { font-size: 22px; margin-bottom: 12px; } - + .oc .myip-ip-list, .oc .myip-check-list { grid-template-columns: repeat(2, 1fr); } - + .oc .ip-title, .oc .ip-state_title { font-size: 13px; } - + .oc .ip-title::after, .oc .ip-state_title::after { width: 25px; } - + .oc .ip-result { font-size: 12px; } - + .oc .ip-geo { font-size: 12px; } - + .oc .sk-text-success, .oc .sk-text-error { font-size: 12px; } - + .oc .sk-load-success { font-size: 12px; } - + .oc .myip-footer p { font-size: 13px !important; line-height: 18px !important; @@ -472,44 +472,44 @@ --card-item-padding: 6px 4px; --card-item-min-height: 70px; } - + .oc .myip-content-grid { padding: 2px; } - + .oc .myip-section-title { font-size: 20px; margin-bottom: 10px; } - + .oc .ip-title, .oc .ip-state_title { font-size: 12px; margin-bottom: 6px; } - + .oc .ip-title::after, .oc .ip-state_title::after { width: 20px; } - + .oc .ip-result { font-size: 11px; } - + .oc .ip-geo { font-size: 11px; } - + .oc .sk-text-success, .oc .sk-text-error { font-size: 11px; } - + .oc .sk-load-success { font-size: 11px; } - + .oc .myip-footer p { font-size: 11px !important; line-height: 16px !important; @@ -543,7 +543,7 @@

- +
UpaiYun @@ -552,7 +552,7 @@
- +
IPIP.NET
@@ -560,7 +560,7 @@
- +
IP.SB
@@ -568,7 +568,7 @@
- +
IPIFY
@@ -578,7 +578,7 @@
- +

<%:Access Check%> @@ -598,7 +598,7 @@

- +
<%:Baidu Search%> @@ -607,7 +607,7 @@
- +
<%:NetEase Music%>
@@ -615,7 +615,7 @@
- +
GitHub
@@ -623,7 +623,7 @@
- +
YouTube
@@ -633,7 +633,7 @@
- + @@ -657,8 +657,8 @@ } function ip_skk() { - url2='https://ip.skk.moe'; - window.open(url2); + url2='https://ip.skk.moe'; + window.open(url2); } const $$ = document; var ip_ipip_ip; @@ -728,6 +728,18 @@ } }) }, + getPcolIP: () => { + fetch(`https://whois.pconline.com.cn/ipJson.jsp?z=${random}`) + .then(response => response.json()) + .then(data => { + let pcisp = data.addr.split(' '); + if (localStorage.getItem('privacy_my_ip') != 'true') { + $$.getElementById('ip-pcol').innerHTML = data.ip; + }; + $$.getElementById('ip-pcol-geo').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`; + addTitleOnOverflow(); + }) + }, getUpaiIP: () => { IP.get(`https://pubstatic.b0.upaiyun.com/?_upnode&z=${random}`, 'json') .then(resp => { @@ -743,7 +755,7 @@ .then(resp => { const ipMatch = resp.data.match(/当前 IP:([0-9.]+)/); const geoMatch = resp.data.match(/来自于:(.+)/); - + if (ipMatch && geoMatch) { if (localStorage.getItem('privacy_my_ip') != 'true') { $$.getElementById('ip-ipip').innerHTML = ipMatch[1]; @@ -765,9 +777,20 @@ IP.parseIPIpip(ip, 'ip-ipify-geo'); addTitleOnOverflow(); }) + }, + getIpsbIP: () => { + fetch(`https://api.ip.sb/geoip?z=${random}`) + .then(response => response.json()) + .then(data => { + if (localStorage.getItem('privacy_my_ip') != 'true') { + $$.getElementById('ip-ipsb').innerHTML = data.ip; + }; + $$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.isp}`; + addTitleOnOverflow(); + }) } }; - + $$.getElementById('http-baidu').innerHTML = '<%:Testing...%>'; $$.getElementById('http-163').innerHTML = '<%:Testing...%>'; $$.getElementById('http-github').innerHTML = '<%:Testing...%>'; @@ -820,15 +843,15 @@ }, checker_router: (domain, cbElID, cbLoID) => { let start_time = (+new Date()); - + var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/website_check?domain=' + encodeURIComponent(domain), true); xhr.timeout = 10000; - + xhr.onreadystatechange = function() { if (xhr.readyState === 4) { let response_time = (new Date()) - start_time; - + if (xhr.status === 200) { try { var response = JSON.parse(xhr.responseText); @@ -836,7 +859,7 @@ if ($$.getElementById(cbLoID).style.display == 'none') { $$.getElementById(cbLoID).style.display = ''; } - + let load_time = response.response_time || response_time; if (load_time <= 500) { $$.getElementById(cbLoID).innerHTML = '' + load_time + ' ms' @@ -865,17 +888,17 @@ } } }; - + xhr.ontimeout = function() { $$.getElementById(cbLoID).style.display = 'none'; $$.getElementById(cbElID).innerHTML = '<%:Access Timed Out%>' }; - + xhr.onerror = function() { $$.getElementById(cbLoID).style.display = 'none'; $$.getElementById(cbElID).innerHTML = '<%:Access Denied%>' }; - + xhr.send(); }, runcheck: () => { @@ -886,53 +909,13 @@ } }; - //function getPcolIP(data){ - // let pcisp = data.addr.split(' '); - // if (localStorage.getItem('privacy_my_ip') != 'true') { - // $$.getElementById('ip-pcol').innerHTML = data.ip; - // }; - // $$.getElementById('ip-pcol-geo').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`; - // addTitleOnOverflow(); - //}; - - function getIpsbIP(data){ - if (localStorage.getItem('privacy_my_ip') != 'true') { - $$.getElementById('ip-ipsb').innerHTML = data.ip; - }; - $$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.isp}`; - addTitleOnOverflow(); - }; - - function delete_ip_script() - { - var scripts = document.getElementsByTagName('script'); - for (var i = scripts.length; i--; ) { - if (document.getElementsByTagName("script")[i]['src'] && - (document.getElementsByTagName("script")[i]['src'].indexOf('whois.pconline.com.cn') > -1 - || document.getElementsByTagName("script")[i]['src'].indexOf('api-ipv4.ip.sb') > -1)) { - scripts[i].parentNode.removeChild(scripts[i]); - }; - }; - }; - function myip_Load() { - delete_ip_script(); - var mypage = document.getElementsByTagName('HEAD').item(0); - var random = parseInt(Math.random() * 100000000); - //var pcipScript= document.createElement("script"); - //pcipScript.defer = "defer"; - //pcipScript.src=`https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP&z=${random}`; - //mypage.appendChild(pcipScript); - - var sbipScript= document.createElement("script"); - sbipScript.defer = "defer"; - sbipScript.src=`https://api-ipv4.ip.sb/geoip?callback=getIpsbIP&z=${random}`; - mypage.appendChild(sbipScript); - + //IP.getPcolIP(); IP.getUpaiIP(); IP.getIpipIP(); IP.getIpifyIP(); + IP.getIpsbIP(); }; function show_my_ip() { @@ -968,7 +951,7 @@ var eyeOpenCircle = document.getElementById('eye-open-circle'); var eyeClosed = document.getElementById('eye-closed'); var titleElement = eyeIcon.querySelector('title'); - + if (isOpen) { eyeOpen.style.display = ''; eyeOpenCircle.style.display = ''; @@ -984,14 +967,13 @@ function privacy_my_ip(svgElement) { var isCurrentlyOpen = document.getElementById('eye-open').style.display !== 'none'; - + if (isCurrentlyOpen) { - delete_ip_script(); clearInterval(refresh_ip); refresh_ip = null; localStorage.setItem('privacy_my_ip', 'true'); update_eye_icon(false); - + ip_ipip_ip = $$.getElementById('ip-ipip').innerHTML; ip_ipsb_ip = $$.getElementById('ip-ipsb').innerHTML; ip_upaiyun_ip = $$.getElementById('ip-upaiyun').innerHTML; @@ -1032,7 +1014,7 @@ }; var use_router_mode = true; - + function toggle_mode_by_icon(svgElement) { var rect = svgElement.querySelector('rect[fill="#2F88FF"]'); if (rect && rect.getAttribute('fill') === '#2F88FF') { @@ -1049,14 +1031,14 @@ init_router_mode(); } } - + function update_mode_icon() { var modeIcon = document.getElementById('mode-icon'); var rect = modeIcon.querySelector('rect[x="4"]'); var paths = modeIcon.querySelectorAll('path'); var smallRect = modeIcon.querySelector('rect[x="30"]'); var titleElement = modeIcon.querySelector('title'); - + if (use_router_mode) { rect.setAttribute('fill', '#2F88FF'); rect.setAttribute('stroke', '#333'); @@ -1075,30 +1057,29 @@ if (titleElement) titleElement.textContent = '<%:Browser Mode%>'; } } - + function init_router_mode() { if (refresh_ip) { clearInterval(refresh_ip); refresh_ip = null; } - delete_ip_script(); - + if (localStorage.getItem('privacy_my_ip') === 'true') { $$.getElementById('ip-ipip').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipsb').innerHTML = '***.***.***.***'; $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipify').innerHTML = '***.***.***.***'; } - + get_router_ip_info(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("get_router_ip_info()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + function init_browser_mode() { if (localStorage.getItem('privacy_my_ip') === 'true') { $$.getElementById('ip-ipip').innerHTML = '***.***.***.***'; @@ -1112,16 +1093,16 @@ } else { reset_display(); } - + myip_Load(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + function get_router_ip_info() { var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/myip_check', true); @@ -1189,7 +1170,7 @@ $$.getElementById('ip-upaiyun-geo').innerHTML = ''; $$.getElementById('ip-ipify-geo').innerHTML = ''; } - + function update_ip_display(data) { const ipFields = [ { id: 'ip-upaiyun', geo: 'ip-upaiyun-geo', key: 'upaiyun' }, @@ -1233,19 +1214,19 @@ } addTitleOnOverflow(); } - + function reset_display() { $$.getElementById('ip-ipip').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-ipify').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-upaiyun').innerHTML = '<%:Querying...%>'; $$.getElementById('ip-ipsb').innerHTML = '<%:Querying...%>'; - + $$.getElementById('ip-ipip-geo').innerHTML = ''; $$.getElementById('ip-ipify-geo').innerHTML = ''; $$.getElementById('ip-upaiyun-geo').innerHTML = ''; $$.getElementById('ip-ipsb-geo').innerHTML = ''; } - + function clearAllIntervals() { if (refresh_http) { clearInterval(refresh_http); @@ -1256,15 +1237,15 @@ refresh_ip = null; } } - + function refresh_myip(svgElement) { svgElement.style.transform = 'rotate(360deg)'; setTimeout(function() { svgElement.style.transform = ''; }, 500); - + clearAllIntervals(); - + if (use_router_mode) { get_router_ip_info(); HTTP.runcheck(); @@ -1283,19 +1264,19 @@ $$.getElementById('ip-upaiyun').innerHTML = '***.***.***.***'; $$.getElementById('ip-ipify').innerHTML = '***.***.***.***'; } - + myip_Load(); HTTP.runcheck(); - + refresh_http = setInterval("HTTP.runcheck()", Math.floor(Math.random()*(10-5+1)+5)*1000); if (localStorage.getItem('privacy_my_ip') !== 'true') { refresh_ip = setInterval("myip_Load()", Math.floor(Math.random()*(40-15+1)+15)*1000); } } - + return false; } - + function init_page() { var saved_mode = localStorage.getItem('myip_check_mode'); if (saved_mode === 'true' || saved_mode === null) { @@ -1307,18 +1288,18 @@ update_mode_icon(); init_browser_mode(); } - + if (localStorage.getItem('privacy_my_ip') === 'true') { update_eye_icon(false); } else { update_eye_icon(true); } } - + window.addEventListener('load', function() { init_page(); }); - + window.addEventListener('beforeunload', function() { clearAllIntervals(); }); diff --git a/small/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm b/small/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm index 9a39fbf1d8..e5bf26c579 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/select_git_cdn.htm @@ -21,7 +21,7 @@ --radius-lg: 8px; --transition-fast: 0.15s ease; --transition-normal: 0.3s ease; - + --control-height: 36px; --card-padding: 6px 8px; --gap-size: 16px; @@ -369,12 +369,12 @@ grid-template-columns: 1fr; gap: 12px; } - + .config-item { width: 100%; max-width: 100%; } - + .select-class { max-width: 100%; font-size: 13px; @@ -389,38 +389,38 @@ max-height: 90vh; overflow-y: auto; } - + .config-grid { grid-template-columns: 1fr; gap: 12px; } - + .config-item { text-align: center; } - + .select-popup-header { font-size: 16px; margin-bottom: 16px; padding-bottom: 12px; } - + .select-config-section { padding: 12px; margin-bottom: 16px; } - + .select-popup-body { max-height: 200px; } - + .select-option { padding: 10px 12px; font-size: 13px; align-items: flex-start; gap: 4px; } - + .custom-option-input { font-size: 13px; padding: 10px; @@ -433,32 +433,32 @@ width: 80%; padding: 12px; } - + .select-popup-header { font-size: 15px; margin-bottom: 12px; } - + .select-config-section { padding: 10px; } - + .config-label { font-size: 12px; } - + .select-class { font-size: 12px; padding: 6px 28px 6px 10px; } - + .config-item::after { right: 10px; border-left: 3px solid transparent; border-right: 3px solid transparent; border-top: 3px solid var(--text-secondary); } - + .select-option { padding: 8px 10px; font-size: 12px; @@ -578,7 +578,7 @@
- +
<%:Release Branch%>
- +
<%:Smart Core%> @@ -605,7 +605,7 @@
- +
https://raw.githubusercontent.com/ (<%:RAW address%>) @@ -642,9 +642,9 @@ function initDarkMode() { var ocContainer = document.querySelector('.oc'); if (!ocContainer) return; - + var shouldUseDark = isDarkBackground(document.body); - + if (shouldUseDark) { ocContainer.setAttribute('data-darkmode', 'true'); } else { @@ -691,7 +691,7 @@ } }); } - + function isValidURL(str) { var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name @@ -701,7 +701,7 @@ '(\\#[-a-z\\d_]*)?'+'\/$','i'); // fragment locator return !!pattern.test(str); } - + function HTTP_delay(domain, ID) { var xhr = new XMLHttpRequest(); xhr.open('GET', '/cgi-bin/luci/admin/services/openclash/website_check?domain=' + encodeURIComponent(domain), true); @@ -751,13 +751,13 @@ xhr.send(); } - + function updateCDNStatus(element, status, text) { var existingStatus = element.querySelector('.cdn-status'); if (existingStatus) { existingStatus.remove(); } - + var statusSpan = document.createElement('span'); statusSpan.className = 'cdn-status ' + status; statusSpan.textContent = text; @@ -790,7 +790,7 @@ } }, Math.floor(Math.random()*(7-3+1)+3)*1000); } - + function select_window_close(event) { var selectPopup = document.getElementById('selectPopup'); if (!selectPopup.contains(event.target)) { diff --git a/small/luci-app-openclash/luasrc/view/openclash/server_url.htm b/small/luci-app-openclash/luasrc/view/openclash/server_url.htm index e91ec0187e..70ab99c64a 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/server_url.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/server_url.htm @@ -115,13 +115,13 @@ function setFormValue(sid, field, value) { function export_url(btn, urlname, sid) { var s = document.getElementById(urlname + '-status'); if (!s) return false; - + var v_type = document.getElementsByName('cbid.openclash.' + sid + '.type')[0]; if (!v_type) return false; - + var type = v_type.value.toLowerCase(); var url = null; - + try { switch (type) { case "ss": @@ -161,7 +161,7 @@ function export_url(btn, urlname, sid) { s.innerHTML = "<%:Unsupported protocol type%>"; return false; } - + if (url) { var textarea = document.createElement("textarea"); textarea.textContent = url; @@ -183,7 +183,7 @@ function export_url(btn, urlname, sid) { s.innerHTML = "<%:Export error%>"; return false; } - + return false; } @@ -202,17 +202,17 @@ function exportSS(sid) { var host = getFormValue(sid, 'host'); var path = getFormValue(sid, 'path'); var tls = getFormValue(sid, 'tls'); - + if (!server || !port || !password || !cipher) { return null; } - + // SIP002 format var userInfo = b64encsafe(cipher + ':' + password); var url = userInfo + '@' + server + ':' + port + '/?'; - + var params = []; - + if (obfs && obfs !== 'none') { var plugin = ''; if (obfs === 'http' || obfs === 'tls') { @@ -236,13 +236,13 @@ function exportSS(sid) { params.push('plugin=' + encodeURIComponent(plugin)); } } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'ss://' + url; } @@ -256,15 +256,15 @@ function exportSSR(sid) { var obfs_param = getFormValue(sid, 'obfs_param'); var protocol_param = getFormValue(sid, 'protocol_param'); var name = getFormValue(sid, 'name'); - + if (!server || !port || !password || !method) { return null; } - + var ssr_str = server + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" + b64encsafe(password) + "/?obfsparam=" + b64encsafe(obfs_param) + "&protoparam=" + b64encsafe(protocol_param) + "&remarks=" + b64encutf8safe(name); - + return "ssr://" + b64encsafe(ssr_str); } @@ -278,11 +278,11 @@ function exportVmess(sid) { var obfs = getFormValue(sid, 'obfs_vmess'); var tls = getFormValue(sid, 'tls'); var servername = getFormValue(sid, 'servername'); - + if (!server || !port || !uuid) { return null; } - + var info = { "v": "2", "ps": name || "", @@ -297,11 +297,11 @@ function exportVmess(sid) { "path": "", "tls": tls === 'true' ? "tls" : "" }; - + if (tls === 'true' && servername) { info.sni = servername; } - + // Handle network type if (obfs === 'websocket') { info.net = "ws"; @@ -318,7 +318,7 @@ function exportVmess(sid) { info.net = "grpc"; info.path = getFormValue(sid, 'grpc_service_name') || ''; } - + return "vmess://" + b64EncodeUnicode(JSON.stringify(info)); } @@ -331,16 +331,16 @@ function exportVless(sid) { var servername = getFormValue(sid, 'servername'); var obfs = getFormValue(sid, 'obfs_vless'); var flow = getFormValue(sid, 'vless_flow'); - + if (!server || !port || !uuid) { return null; } - + var url = uuid + '@' + server + ':' + port + '?'; var params = []; - + params.push('encryption=none'); - + if (tls === 'true') { if (flow && flow.includes('xtls')) { params.push('security=xtls'); @@ -352,7 +352,7 @@ function exportVless(sid) { params.push('sni=' + encodeURIComponent(servername)); } } - + if (obfs === 'ws') { params.push('type=ws'); var path = getFormValue(sid, 'ws_opts_path'); @@ -373,13 +373,13 @@ function exportVless(sid) { } else { params.push('type=tcp'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'vless://' + url; } @@ -391,32 +391,32 @@ function exportTrojan(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port || !password) { return null; } - + var url = encodeURIComponent(password) + '@' + server + ':' + port + '/?'; var params = []; - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('allowInsecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'trojan://' + url; } @@ -432,52 +432,52 @@ function exportHysteria(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'hysteria_alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = server + ':' + port + '?'; var params = []; - + if (auth) { params.push('auth=' + encodeURIComponent(auth)); } - + if (protocol) { params.push('protocol=' + protocol); } - + if (up) { params.push('up=' + up); } - + if (down) { params.push('down=' + down); } - + if (obfs) { params.push('obfsParam=' + encodeURIComponent(obfs)); } - + if (sni) { params.push('peer=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'hysteria://' + url; } @@ -493,53 +493,53 @@ function exportHysteria2(sid) { var sni = getFormValue(sid, 'sni'); var alpn = getFormValue(sid, 'hysteria_alpn'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = ''; if (password) { url += encodeURIComponent(password) + '@'; } url += server + ':' + port + '?'; - + var params = []; - + if (obfs) { params.push('obfs=' + encodeURIComponent(obfs)); } - + if (obfs_password) { params.push('obfs-password=' + encodeURIComponent(obfs_password)); } - + if (up) { params.push('up=' + up); } - + if (down) { params.push('down=' + down); } - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'hysteria2://' + url; } @@ -555,11 +555,11 @@ function exportTuic(sid) { var sni = getFormValue(sid, 'sni'); var disable_sni = getFormValue(sid, 'disable_sni'); var udp_relay = getFormValue(sid, 'udp_relay_mode'); - + if (!server || !port) { return null; } - + var url = ''; if (password) { // TUIC v5 @@ -568,37 +568,37 @@ function exportTuic(sid) { // TUIC v4 url += encodeURIComponent(token) + '@'; } - + url += server + ':' + port + '?'; - + var params = []; - + if (cc) { params.push('congestion_control=' + encodeURIComponent(cc)); } - + if (alpn) { params.push('alpn=' + encodeURIComponent(alpn)); } - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (disable_sni === 'true') { params.push('disable_sni=1'); } - + if (udp_relay) { params.push('udp_relay_mode=' + encodeURIComponent(udp_relay)); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'tuic://' + url; } @@ -608,21 +608,21 @@ function exportSocks(sid) { var username = getFormValue(sid, 'auth_name'); var password = getFormValue(sid, 'auth_pass'); var name = getFormValue(sid, 'name'); - + if (!server || !port) { return null; } - + var url = ''; if (username && password) { url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@'; } url += server + ':' + port; - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'socks5://' + url; } @@ -633,23 +633,23 @@ function exportHttp(sid) { var password = getFormValue(sid, 'auth_pass'); var name = getFormValue(sid, 'name'); var tls = getFormValue(sid, 'tls'); - + if (!server || !port) { return null; } - + var scheme = tls === 'true' ? 'https' : 'http'; var url = ''; - + if (username && password) { url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@'; } url += server + ':' + port; - + if (name) { url += '#' + encodeURIComponent(name); } - + return scheme + '://' + url; } @@ -662,11 +662,11 @@ function exportAnyTLS(sid) { var sni = getFormValue(sid, 'sni'); var fingerprint = getFormValue(sid, 'fingerprint'); var skip_cert = getFormValue(sid, 'skip_cert_verify'); - + if (!server || !port) { return null; } - + var url = ''; if (username) { url += encodeURIComponent(username); @@ -676,51 +676,51 @@ function exportAnyTLS(sid) { url += '@'; } url += server + ':' + port + '?'; - + var params = []; - + if (sni) { params.push('sni=' + encodeURIComponent(sni)); } - + if (fingerprint) { params.push('hpkp=' + encodeURIComponent(fingerprint)); } - + if (skip_cert === 'true') { params.push('insecure=1'); } - + url += params.join('&'); - + if (name) { url += '#' + encodeURIComponent(name); } - + return 'anytls://' + url; } function import_url(btn, urlname, sid) { var s = document.getElementById(urlname + '-status'); if (!s) return false; - + var ssrurl = prompt("<%:Paste sharing link here%>", ""); if (ssrurl == null || ssrurl == "") { s.innerHTML = "<%:User cancelled%>"; return false; } s.innerHTML = ""; - + var ssu = ssrurl.split('://'); if (ssu.length < 2) { s.innerHTML = "<%:Invalid format%>"; return false; } - + var scheme = ssu[0].toLowerCase(); var event = document.createEvent("HTMLEvents"); event.initEvent("change", true, true); - + try { switch (scheme) { case "ss": @@ -730,7 +730,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "ssr": if (parseSSR(ssu[1], sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -738,7 +738,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "vmess": if (parseVmess(ssu[1], sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -746,7 +746,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "vless": if (parseVless(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -754,7 +754,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "trojan": if (parseTrojan(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -762,7 +762,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "hysteria": if (parseHysteria(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -770,7 +770,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "hysteria2": case "hy2": if (parseHysteria2(ssrurl, sid)) { @@ -779,7 +779,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "tuic": if (parseTuic(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -787,7 +787,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "socks": case "socks5": case "socks5h": @@ -797,7 +797,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "http": case "https": if (parseHttp(ssrurl, sid)) { @@ -806,7 +806,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + case "anytls": if (parseAnyTLS(ssrurl, sid)) { s.innerHTML = "<%:Import configuration information successfully%>"; @@ -814,7 +814,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Invalid format%>"; } break; - + default: s.innerHTML = "<%:Invalid format%>"; return false; @@ -823,7 +823,7 @@ function import_url(btn, urlname, sid) { s.innerHTML = "<%:Parse error%>"; return false; } - + return false; } @@ -831,16 +831,16 @@ function parseSS(body, sid) { var url0, param = ""; var sipIndex = body.indexOf("@"); var ploc = body.indexOf("#"); - + if (ploc > 0) { url0 = body.substr(0, ploc); param = body.substr(ploc + 1); } else { url0 = body; } - + setFormValue(sid, 'type', 'ss'); - + if (sipIndex !== -1) { // SIP002 format var userInfo = b64decsafe(url0.substr(0, sipIndex)); @@ -849,28 +849,28 @@ function parseSS(body, sid) { var server = serverInfo[0]; var port = serverInfo[1]; var method, password; - + if (temp[1]) { var query = parseQuery("?" + temp[1]); - + if (query.plugin) { var decodedPlugin = decodeURIComponent(query.plugin); - + var pluginParts = decodedPlugin.split(';'); var pluginName = pluginParts[0]; - + // obfs-local if (pluginName === 'obfs-local' || pluginName.includes('obfs')) { var obfsMode = 'http'; var obfsHost = ''; - + for (var i = 1; i < pluginParts.length; i++) { var opt = pluginParts[i]; var eqIndex = opt.indexOf('='); if (eqIndex !== -1) { var key = opt.substring(0, eqIndex).trim(); var value = opt.substring(eqIndex + 1).trim(); - + if (key === 'obfs') { obfsMode = value; } else if (key === 'obfs-host') { @@ -878,27 +878,27 @@ function parseSS(body, sid) { } } } - + setFormValue(sid, 'obfs', obfsMode); if (obfsHost) { setFormValue(sid, 'host', obfsHost); } } - + // v2ray-plugin if (pluginName === 'v2ray-plugin') { var v2rayMode = 'websocket'; var v2rayHost = ''; var v2rayPath = '/'; var v2rayTls = false; - + for (var i = 1; i < pluginParts.length; i++) { var opt = pluginParts[i]; var eqIndex = opt.indexOf('='); if (eqIndex !== -1) { var key = opt.substring(0, eqIndex).trim(); var value = opt.substring(eqIndex + 1).trim(); - + if (key === 'mode') { v2rayMode = value; } else if (key === 'host') { @@ -910,7 +910,7 @@ function parseSS(body, sid) { } } } - + setFormValue(sid, 'obfs', 'websocket'); if (v2rayHost) { setFormValue(sid, 'host', v2rayHost); @@ -923,18 +923,18 @@ function parseSS(body, sid) { } } } - + if (query['udp-over-tcp'] === 'true' || query['uot'] === '1') { setFormValue(sid, 'udp_over_tcp', 'true'); } } - + var userInfoSplitIndex = userInfo.indexOf(":"); if (userInfoSplitIndex !== -1) { method = userInfo.substr(0, userInfoSplitIndex); password = userInfo.substr(userInfoSplitIndex + 1); } - + setFormValue(sid, 'server', server); setFormValue(sid, 'port', port); setFormValue(sid, 'password', password || ""); @@ -945,17 +945,17 @@ function parseSS(body, sid) { var team = sstr.split('@'); var part1 = team[0].split(':'); var part2 = team[1].split(':'); - + setFormValue(sid, 'server', part2[0]); setFormValue(sid, 'port', part2[1]); setFormValue(sid, 'password', part1[1]); setFormValue(sid, 'cipher', part1[0]); } - + if (param) { setFormValue(sid, 'name', decodeURIComponent(param)); } - + return true; } @@ -966,7 +966,7 @@ function parseSSR(body, sid) { } catch (e) { return false; } - + setFormValue(sid, 'type', 'ssr'); // ssr://host:port:protocol:method:obfs:urlsafebase64pass/?obfsparam=... @@ -979,26 +979,26 @@ function parseSSR(body, sid) { before = dcBuf; after = ""; } - + var parts = before.split(':'); if (parts.length !== 6) { return false; } - + var host = parts[0]; var port = parts[1]; var protocol = parts[2]; var method = parts[3]; var obfs = parts[4]; var password = b64decsafe(parts[5]); - + setFormValue(sid, 'server', host); setFormValue(sid, 'port', port); setFormValue(sid, 'protocol', protocol); setFormValue(sid, 'cipher_ssr', method); setFormValue(sid, 'obfs_ssr', obfs); setFormValue(sid, 'password', password); - + if (after) { var params = {}; var paramPairs = after.split('&'); @@ -1010,20 +1010,20 @@ function parseSSR(body, sid) { params[key] = value; } } - + if (params.obfsparam) { setFormValue(sid, 'obfs_param', b64decsafe(params.obfsparam)); } - + if (params.protoparam) { setFormValue(sid, 'protocol_param', b64decsafe(params.protoparam)); } - + if (params.remarks) { setFormValue(sid, 'name', b64decutf8safe(params.remarks)); } } - + return true; } @@ -1032,25 +1032,25 @@ function parseVmess(body, sid) { // Try V2rayN format first var sstr = b64DecodeUnicode(body); var ssm = JSON.parse(sstr); - + setFormValue(sid, 'type', 'vmess'); setFormValue(sid, 'name', ssm.ps || ''); setFormValue(sid, 'server', ssm.add); setFormValue(sid, 'port', ssm.port); setFormValue(sid, 'alterId', ssm.aid || 0); setFormValue(sid, 'uuid', ssm.id); - + if (ssm.scy) { setFormValue(sid, 'securitys', ssm.scy); } - + if (ssm.tls === "tls") { setFormValue(sid, 'tls', 'true'); if (ssm.sni) { setFormValue(sid, 'servername', ssm.sni); } } - + var network = (ssm.net || 'tcp').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_vmess', 'websocket'); @@ -1080,27 +1080,27 @@ function parseVmess(body, sid) { setFormValue(sid, 'obfs_vmess', 'grpc'); setFormValue(sid, 'grpc_service_name', ssm.path || ''); } - + return true; } catch (e) { // Try Xray VMessAEAD format try { var parsed = parseUrl('vmess://' + body); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'vmess'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'uuid', parsed.username); setFormValue(sid, 'alterId', 0); setFormValue(sid, 'securitys', query.encryption || 'auto'); - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } catch (e2) { return false; @@ -1111,14 +1111,14 @@ function parseVmess(body, sid) { function parseVless(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'vless'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'uuid', parsed.username); - + if (query.security) { if (query.security === 'tls' || query.security === 'xtls') { setFormValue(sid, 'tls', 'true'); @@ -1141,7 +1141,7 @@ function parseVless(url, sid) { } } } - + var network = (query.type || 'tcp').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_vless', 'ws'); @@ -1155,34 +1155,34 @@ function parseVless(url, sid) { } else { setFormValue(sid, 'obfs_vless', 'tcp'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseTrojan(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'trojan'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'password', parsed.username); - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.alpn) { // Handle ALPN - multiple values support, decode properly setFormValue(sid, 'alpn', decodeURIComponent(query.alpn)); } - + var network = (query.type || '').toLowerCase(); if (network === 'ws') { setFormValue(sid, 'obfs_trojan', 'ws'); @@ -1194,131 +1194,131 @@ function parseTrojan(url, sid) { setFormValue(sid, 'obfs_trojan', 'grpc'); setFormValue(sid, 'grpc_service_name', decodeURIComponent(query.serviceName || '')); } - + if (query.allowInsecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseHysteria(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'hysteria'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + if (query.auth) { setFormValue(sid, 'hysteria_auth_str', decodeURIComponent(query.auth)); } - + if (query.protocol) { setFormValue(sid, 'flag_transport', '1'); setFormValue(sid, 'hysteria_protocol', query.protocol); } - + if (query.up || query.upmbps) { var upSpeed = decodeURIComponent(query.up || query.upmbps); upSpeed = upSpeed.replace(/[^0-9]/g, ''); setFormValue(sid, 'hysteria_up', upSpeed); } - + if (query.down || query.downmbps) { var downSpeed = decodeURIComponent(query.down || query.downmbps); downSpeed = downSpeed.replace(/[^0-9]/g, ''); setFormValue(sid, 'hysteria_down', downSpeed); } - + if (query.obfs || query.obfsParam) { setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs || query.obfsParam)); } - + if (query.peer) { setFormValue(sid, 'sni', decodeURIComponent(query.peer)); } - + if (query.alpn) { setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn)); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseHysteria2(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'hysteria2'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + if (parsed.username) { setFormValue(sid, 'password', parsed.username); } - + if (query.obfs) { setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs)); } - + if (query['obfs-password']) { setFormValue(sid, 'hysteria_obfs_password', decodeURIComponent(query['obfs-password'])); } - + if (query.up) { setFormValue(sid, 'hysteria_up', decodeURIComponent(query.up)); } - + if (query.down) { setFormValue(sid, 'hysteria_down', decodeURIComponent(query.down)); } - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.alpn) { setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn)); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseTuic(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'tuic'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); - + // Check if it's v5 (has password) or v4 (token only) if (parsed.password) { setFormValue(sid, 'uuid', parsed.username); @@ -1326,42 +1326,42 @@ function parseTuic(url, sid) { } else { setFormValue(sid, 'tc_token', parsed.username); } - + if (query.congestion_control) { setFormValue(sid, 'congestion_controller', decodeURIComponent(query.congestion_control)); } - + if (query.alpn) { setFormValue(sid, 'tc_alpn', decodeURIComponent(query.alpn)); } - + if (query.sni) { setFormValue(sid, 'sni', decodeURIComponent(query.sni)); } - + if (query.disable_sni === '1') { setFormValue(sid, 'disable_sni', 'true'); } - + if (query.udp_relay_mode) { setFormValue(sid, 'udp_relay_mode', decodeURIComponent(query.udp_relay_mode)); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } - + return true; } function parseSocks(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + setFormValue(sid, 'type', 'socks5'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '1080'); - + if (parsed.username) { try { var decoded = atob(parsed.username); @@ -1375,28 +1375,28 @@ function parseSocks(url, sid) { } } } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } function parseHttp(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + setFormValue(sid, 'type', 'http'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || (parsed.protocol === 'https:' ? '443' : '80')); - + if (parsed.protocol === 'https:') { setFormValue(sid, 'tls', 'true'); } - + if (parsed.username) { try { var decoded = atob(parsed.username); @@ -1410,46 +1410,46 @@ function parseHttp(url, sid) { } } } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } function parseAnyTLS(url, sid) { var parsed = parseUrl(url); if (!parsed) return false; - + var query = parseQuery(parsed.search); - + setFormValue(sid, 'type', 'anytls'); setFormValue(sid, 'server', parsed.hostname); setFormValue(sid, 'port', parsed.port || '443'); setFormValue(sid, 'auth_name', parsed.username); setFormValue(sid, 'password', parsed.password || parsed.username); - + if (query.sni) { setFormValue(sid, 'sni', query.sni); } - + if (query.hpkp) { setFormValue(sid, 'fingerprint', query.hpkp); } - + if (query.insecure === '1') { setFormValue(sid, 'skip_cert_verify', 'true'); } - + if (parsed.hash) { setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1))); } else { setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port); } - + return true; } diff --git a/small/luci-app-openclash/luasrc/view/openclash/status.htm b/small/luci-app-openclash/luasrc/view/openclash/status.htm index 8f8a520a43..ac6f3fdbb6 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/status.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/status.htm @@ -25,15 +25,15 @@ --radius-lg: 8px; --transition-fast: 0.15s ease; --transition-normal: 0.3s ease; - + --control-height: 32px; --card-padding: 6px 8px; --gap-size: 10px; - + --row-1-height: 160px; --row-2-height: 140px; --row-3-height: 140px; - --row-4-height: 250px; + --row-4-height: 280px; } .oc[data-darkmode="true"] { @@ -542,7 +542,8 @@ width: 100%; height: var(--control-height); padding: 5px 12px; - border: 1px solid var(--border-light); + border: 1px solid var(--border-light) !important; + background-color: var(--bg-white) !important; border-radius: var(--radius-sm); background: var(--bg-white); color: var(--text-primary); @@ -713,7 +714,7 @@ } .oc .dashboard-btn { - font-size: 11px !important; + font-size: 12px !important; font-weight: 500 !important; color: white !important; cursor: pointer !important; @@ -877,6 +878,7 @@ display: flex; flex-direction: column; width: 100%; + height: 180px; box-shadow: var(--shadow-sm); transition: all var(--transition-fast); position: relative; @@ -918,12 +920,13 @@ display: flex; flex-direction: column; gap: 10px; + margin: auto 0; } .oc .subscription-progress-bar { background: var(--bg-gray); border-radius: 4px; - height: 10px; + height: 12px; position: relative; overflow: hidden; } @@ -946,6 +949,17 @@ background: var(--error-color); } +.oc .subscription-info-title { + font-size: 15px; + font-weight: 600; + color: var(--text-secondary); + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; +} + .oc .subscription-info-text { font-size: 13px; color: var(--text-secondary); @@ -956,6 +970,69 @@ display: block; } +/* Multiple Providers Grid Layout */ +.oc .subscription-providers-grid { + display: flex; + gap: 12px; + padding: 8px 0; + max-width: 100%; + width: 100%; + overflow-x: auto; + overflow-y: hidden; + scrollbar-width: none; + -ms-overflow-style: none; + cursor: grab; + user-select: none; +} + +.oc .subscription-providers-grid::-webkit-scrollbar { + display: none; +} + +.oc .subscription-providers-grid.dragging { + cursor: grabbing; +} + +.oc .subscription-providers-grid[data-count="1"] { + overflow-x: hidden; +} + +.oc .subscription-providers-grid[data-count="2"], +.oc .subscription-providers-grid[data-count="3"] { + overflow-x: hidden; +} + +.oc .provider-card { + background: transparent; + padding: 0; + transition: all 0.2s ease; + min-width: calc(33.333% - 8px); + flex: 0 0 calc(33.333% - 8px); + box-sizing: border-box; + display: flex; + flex-direction: column; + gap: 6px; +} + +/* For 1-2 providers, allow them to fill available space */ +.oc .subscription-providers-grid[data-count="1"] .provider-card { + min-width: 100%; + flex: 1 1 100%; +} + +.oc .subscription-providers-grid[data-count="2"] .provider-card { + min-width: calc(50% - 6px); + flex: 1 1 calc(50% - 6px); +} + +/* For 3+ providers, fixed 33.333% width */ +/* data-count="3" uses the base rule: flex: 0 0 calc(33.333% - 8px) */ + +/* Dark mode support for provider cards */ +.oc[data-darkmode="true"] .provider-card { + background: transparent; +} + .oc .subscription-loading, .oc .subscription-error, .oc .subscription-no-info { @@ -1200,6 +1277,10 @@ transform: scaleX(-1); } +.oc .hidden { + display: none !important; +} + @media screen and (max-width: 1200px) { .oc .main-cards-container { grid-template-columns: 1fr; @@ -1207,7 +1288,7 @@ max-width: 95%; width: 95%; } - + .oc .announcement-banner { grid-column: 1; width: 80%; @@ -1219,7 +1300,7 @@ width: 100%; max-width: 100%; } - + .oc .main-card { grid-column: 1; grid-template-rows: auto auto auto auto; @@ -1231,7 +1312,7 @@ grid-column: 1; grid-row: 2; } - + .oc .main-card:last-of-type { grid-column: 1; grid-row: 3; @@ -1249,17 +1330,17 @@ min-width: 200px; flex: 1; } - + .oc .config-select { min-width: 200px; font-size: 14px; } - + .oc .config-select option { font-size: 14px; max-width: 100%; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1315,7 +1396,7 @@ padding: 6px 6px; font-size: 11px; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1338,12 +1419,12 @@ font-size: 13px; padding: 4px 10px; } - + .oc .config-select option { font-size: 13px; padding: 6px 10px; } - + .oc .config-selector::after { right: 10px; border-left: 3px solid transparent; @@ -1354,7 +1435,7 @@ .oc .config-subscription-info { margin-left: 12px; } - + .oc .subscription-info-container { padding: 8px; } @@ -1373,16 +1454,24 @@ align-items: stretch; gap: 8px; } - + .oc .config-file-bottom .card-actions { justify-content: center; gap: 5px; } - + .oc .subscription-info-text { font-size: 10px; } + .oc .subscription-info-title { + font-size: 13px; + } + + .oc .subscription-progress-bar { + height: 10px; + } + .oc .file-info { font-size: 10px; } @@ -1397,7 +1486,7 @@ font-size: 14px !important; padding: 0 24px !important; } - + .oc .config-file-empty-message { font-size: 14px; } @@ -1449,7 +1538,7 @@ } .oc .dashboard-btn { - font-size: 8px !important; + font-size: 9px !important; height: 25px !important; } @@ -1474,7 +1563,7 @@ align-items: stretch; gap: 12px; } - + .oc .config-subscription-info { margin-left: 0; justify-content: center; @@ -1483,7 +1572,7 @@ .oc .subscription-info-header { gap: 6px; } - + .oc .file-info { gap: 4px; font-size: 8px; @@ -1493,7 +1582,7 @@ flex-direction: row; gap: 8px; } - + .oc .card-row:nth-child(1), .oc .card-row:nth-child(2), .oc .card-row:nth-child(3), @@ -1505,18 +1594,18 @@ min-width: 110px; flex: 1; } - + .oc .config-select { min-width: 110px; font-size: 12px; padding: 4px 8px; } - + .oc .config-select option { font-size: 12px; padding: 5px 8px; } - + .oc .config-selector::after { right: 8px; } @@ -1548,6 +1637,10 @@ font-size: 10px; } + .oc .subscription-info-title { + font-size: 13px; + } + .oc .config-file-name { font-size: 15px; } @@ -1603,12 +1696,12 @@ font-size: 13px !important; padding: 0 20px !important; } - + .oc .config-file-empty-state { padding: 30px 15px; gap: 15px; } - + .oc .config-file-empty-message { font-size: 13px; } @@ -1673,8 +1766,9 @@
- @@ -1828,10 +1930,10 @@ - <%:Upload Config File%> + <%:Add Config File%>
- +
@@ -1971,13 +2073,22 @@ init: function() { this.applyDarkMode(); }, - + applyDarkMode: function() { var ocContainers = document.querySelectorAll('.oc'); if (!ocContainers.length) return; - var shouldUseDark = isDarkBackground(document.body); - + var theme = localStorage.getItem('oc-theme') || 'auto'; + var shouldUseDark; + + if (theme === 'light') { + shouldUseDark = false; + } else if (theme === 'dark') { + shouldUseDark = true; + } else { + shouldUseDark = isDarkBackground(document.body); + } + ocContainers.forEach(function(ocContainer) { if (shouldUseDark) { ocContainer.setAttribute('data-darkmode', 'true'); @@ -1988,13 +2099,18 @@ var sunIcon = document.getElementById('sun-icon'); var moonIcon = document.getElementById('moon-icon'); - if (sunIcon && moonIcon) { - if (shouldUseDark) { - sunIcon.style.display = 'none'; + var autoIcon = document.getElementById('auto-icon'); + if (sunIcon && moonIcon && autoIcon) { + sunIcon.style.display = 'none'; + moonIcon.style.display = 'none'; + autoIcon.style.display = 'none'; + + if (theme === 'light') { + sunIcon.style.display = 'inline'; + } else if (theme === 'dark') { moonIcon.style.display = 'inline'; } else { - sunIcon.style.display = 'inline'; - moonIcon.style.display = 'none'; + autoIcon.style.display = 'inline'; } } } @@ -2007,7 +2123,7 @@ request_cache: {}, cache_ttl: 5000, pending_requests: new Map(), - + _cachedXHR: function(url, params, callback, force) { var cacheKey = params ? url + JSON.stringify(params) : url; var now = Date.now(); @@ -2026,7 +2142,7 @@ }, 0); return; } - + if (!force && cacheExists && isCacheStale) { setTimeout(function() { callback({ status: 200, fromCache: true, stale: true }, StateManager.request_cache[cacheKey]); @@ -2061,23 +2177,23 @@ cachedXHRGetWithParams: function(url, params, callback, force) { this._cachedXHR(url, params, callback, force); }, - + clearCache: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; delete this.request_cache[cacheKey]; delete this.last_request_time[cacheKey]; }, - + clearAllCache: function() { this.request_cache = {}; this.last_request_time = {}; }, - + hasCache: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; return !!this.request_cache[cacheKey]; }, - + getCacheAge: function(url, params) { var cacheKey = params ? url + JSON.stringify(params) : url; if (!this.last_request_time[cacheKey]) { @@ -2085,13 +2201,12 @@ } return Date.now() - this.last_request_time[cacheKey]; }, - + setCacheTTL: function(ttl) { this.cache_ttl = ttl; }, - + batchUpdateDOM: function(updates) { - var fragment = document.createDocumentFragment(); for (var i = 0; i < updates.length; i++) { var update = updates[i]; if (update.element && update.content !== undefined) { @@ -2099,12 +2214,12 @@ } } }, - + cachedXHRGetWithRetry: function(url, params, callback, force, maxRetries) { maxRetries = maxRetries || 3; var retryCount = 0; var self = this; - + function attemptRequest() { self.cachedXHRGetWithParams(url, params, function(x, data) { if (x && x.status == 200) { @@ -2117,7 +2232,7 @@ } }, force && retryCount === 0); } - + attemptRequest(); } }; @@ -2379,7 +2494,7 @@ currentConfigIndex: -1, selectElement: null, rawCurrentConfig: '', - + init: function() { this.selectElement = document.getElementById('config_file_select'); if (this.selectElement) { @@ -2387,16 +2502,16 @@ this.setupEventListeners(); } }, - + setupEventListeners: function() { if (this.selectElement) { this.selectElement.addEventListener('change', this.onConfigChange.bind(this)); } }, - + loadConfigFileList: function() { this.updateSelectOptions([{value: '', text: '<%:Collecting data...%>', disabled: true}]); - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "config_file_list")%>', function(x, data) { if (x && x.status == 200) { ConfigFileManager.handleConfigListResponse(data); @@ -2405,34 +2520,35 @@ } }, true); }, - + handleConfigListResponse: function(data) { try { var configFiles = []; var currentConfigFile = ''; var currentFileInfo = null; - + if (data.config_files && Array.isArray(data.config_files)) { configFiles = data.config_files; - } else if (data.files && Array.isArray(data.files)) { - configFiles = data.files; + configFiles.sort(function(a, b) { + var nameA = typeof a === 'string' ? a : (a.name || a.filename || a.path || a); + var nameB = typeof b === 'string' ? b : (b.name || b.filename || b.path || b); + return nameA.localeCompare(nameB); + }); } else { - configFiles = data.config_list || []; + configFiles = []; } - + if (data.current_config) { currentConfigFile = data.current_config; - } else if (data.current) { - currentConfigFile = data.current; } - + this.rawCurrentConfig = currentConfigFile; this.configList = configFiles; this.currentConfig = currentConfigFile; this.currentConfigIndex = -1; this.toggleEmptyState(configFiles.length === 0); - + this.updateConfigSelect(configFiles, currentConfigFile); if (configFiles.length > 0) { @@ -2440,7 +2556,7 @@ for (var i = 0; i < configFiles.length; i++) { var file = configFiles[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === currentConfigFile) { this.currentConfigIndex = i; if (typeof file === 'object' && file.mtime && file.size) { @@ -2453,9 +2569,9 @@ } } } - + this.updateSubscriptionDisplay(currentConfigFile, currentFileInfo); - + if (currentConfigFile && SubscriptionManager.currentConfigFile !== currentConfigFile) { SubscriptionManager.currentConfigFile = currentConfigFile; SubscriptionManager.getSubscriptionInfo(); @@ -2464,24 +2580,24 @@ this.hideSubscriptionDisplay(); SubscriptionManager.currentConfigFile = ''; } - + this.updateNavigationArrows(); if (this._retryGetConfigList) { clearInterval(this._retryGetConfigList); this._retryGetConfigList = null; } - + } catch (e) { this.handleConfigListError(); } }, - + handleConfigListError: function() { this.updateSelectOptions([ {value: '', text: '<%:Failed to load config files%>', disabled: true} ]); - + this.toggleEmptyState(true); this.hideSubscriptionDisplay(); @@ -2497,7 +2613,7 @@ var emptyStateElement = document.getElementById('config-file-empty-state'); var configFileBottom = document.querySelector('.config-file-bottom'); var configFileContent = document.querySelector('.config-file-content'); - + if (isEmpty) { if (emptyStateElement) { emptyStateElement.style.display = 'flex'; @@ -2521,17 +2637,17 @@ } } }, - + hideSubscriptionDisplay: function() { var subscriptionDisplay = document.getElementById('subscription-info-display'); if (subscriptionDisplay) { subscriptionDisplay.style.display = 'none'; } }, - + updateConfigSelect: function(configFiles, currentConfig) { var options = []; - + if (!configFiles || configFiles.length === 0) { options.push({ value: '', @@ -2544,10 +2660,10 @@ text: '<%:Please select a config file%>', disabled: false }); - + configFiles.forEach(function(file) { var fileName, filePath; - + if (typeof file === 'string') { fileName = file; filePath = file; @@ -2555,9 +2671,9 @@ fileName = file.name || file.filename || file.path || file; filePath = file.path || file.filepath || file.name || file; } - + var displayName = fileName; - + options.push({ value: filePath, text: displayName, @@ -2566,22 +2682,22 @@ }); }); } - + this.updateSelectOptions(options); }, - + updateSelectOptions: function(options) { if (!this.selectElement) return; - + this.selectElement.innerHTML = ''; - + options.forEach(function(option) { var optionElement = document.createElement('option'); optionElement.value = option.value; optionElement.textContent = option.text; optionElement.disabled = option.disabled || false; optionElement.selected = option.selected || false; - + this.selectElement.appendChild(optionElement); }, this); }, @@ -2591,25 +2707,25 @@ var configNameElement = document.getElementById('current-config-name'); var fileModifyTimeElement = document.getElementById('file-modify-time'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + if (this.configList.length === 0) { container.style.display = 'none'; return; } - + if (!configFile) { container.style.display = 'none'; return; } - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { container.style.display = 'none'; return; } - + container.style.display = 'flex'; if (configNameElement) { @@ -2628,7 +2744,7 @@ configNameElement.title = ''; } } - + if (fileInfo) { if (fileModifyTimeElement) { var modifyTime = this.formatUnixTime(fileInfo.mtime); @@ -2639,7 +2755,7 @@ fileModifyTimeElement.title = ''; } } - + if (detailsSection) { detailsSection.style.display = 'flex'; } @@ -2647,7 +2763,7 @@ if (fileModifyTimeElement) { fileModifyTimeElement.textContent = '<%:Update Time%> --'; } - + if (detailsSection) { detailsSection.style.display = 'none'; } @@ -2658,7 +2774,7 @@ if (!unixTimestamp || unixTimestamp === 0) { return '--'; } - + try { var date = new Date(unixTimestamp * 1000); var year = date.getFullYear(); @@ -2667,7 +2783,7 @@ var hour = String(date.getHours()).padStart(2, '0'); var minute = String(date.getMinutes()).padStart(2, '0'); var second = String(date.getSeconds()).padStart(2, '0'); - + return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second; } catch (e) { return '--'; @@ -2676,51 +2792,51 @@ formatFileSize: function(bytes) { if (!bytes || bytes === 0) return '--'; - + var sizes = ['B', 'KB', 'MB', 'GB', 'TB']; var i = Math.floor(Math.log(bytes) / Math.log(1024)); - + if (i === 0) { return bytes + ' ' + sizes[i]; } - + return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i]; }, - + formatDisplayName: function(fileName) { if (!fileName) return '<%:Unknown%>'; - + var name = fileName.split('/').pop().split('\\').pop(); - + //name = name.replace(/\.(yaml|yml)$/i, ''); - + if (name.length > 30) { name = name.substring(0, 27) + '...'; } - + return name; }, - + onConfigChange: function(event) { var selectedValue = event.target.value; - + if (selectedValue) { this.currentConfig = selectedValue; - + for (var i = 0; i < this.configList.length; i++) { var file = this.configList[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === selectedValue) { this.currentConfigIndex = i; break; } } - + var selectedFileInfo = this.getConfigFileInfo(selectedValue); this.updateSubscriptionDisplay(selectedValue, selectedFileInfo); this.updateNavigationArrows(); - + if (SubscriptionManager.currentConfigFile !== selectedValue) { SubscriptionManager.currentConfigFile = selectedValue; var detailsSection = document.getElementById('subscription-info-details'); @@ -2743,7 +2859,7 @@ for (var i = 0; i < this.configList.length; i++) { var file = this.configList[i]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (filePath === selectedValue) { if (typeof file === 'object' && file.mtime && file.size) { selectedFileInfo = { @@ -2756,54 +2872,54 @@ } return selectedFileInfo; }, - + updateNavigationArrows: function() { var prevArrow = document.getElementById('subscription-prev-arrow'); var nextArrow = document.getElementById('subscription-next-arrow'); - + if (!prevArrow || !nextArrow) return; - + var hasMultipleConfigs = this.configList.length > 1; var currentIndex = this.currentConfigIndex; - + if (!hasMultipleConfigs || currentIndex === -1) { prevArrow.style.display = 'none'; nextArrow.style.display = 'none'; return; } - + prevArrow.style.display = 'block'; nextArrow.style.display = 'block'; - + prevArrow.classList.remove('disabled'); nextArrow.classList.remove('disabled'); }, - + switchToConfigByIndex: function(index) { if (this.configList.length === 0) { return false; } - + if (index < 0) { index = this.configList.length - 1; } else if (index >= this.configList.length) { index = 0; } - + var file = this.configList[index]; var filePath = typeof file === 'string' ? file : (file.path || file.filepath || file); - + if (this.selectElement) { this.selectElement.value = filePath; } - + this.currentConfig = filePath; this.currentConfigIndex = index; - + var fileInfo = this.getConfigFileInfo(filePath); this.updateSubscriptionDisplay(filePath, fileInfo); this.updateNavigationArrows(); - + if (SubscriptionManager.currentConfigFile !== filePath) { SubscriptionManager.currentConfigFile = filePath; var detailsSection = document.getElementById('subscription-info-details'); @@ -2812,18 +2928,18 @@ } SubscriptionManager.getSubscriptionInfo(); } - + return true; }, - + refreshConfigList: function() { this.loadConfigFileList(); }, - + getCurrentConfig: function() { return this.currentConfig; }, - + getSelectedConfig: function() { return this.selectElement ? this.selectElement.value : ''; } @@ -2835,17 +2951,17 @@ maxRetries: 5, updateTimer: null, isInitialized: false, - + init: function() { if (this.isInitialized) return; this.isInitialized = true; - + setTimeout(function() { SubscriptionManager.loadSubscriptionInfo(); SubscriptionManager.startAutoUpdate(); }, 500); }, - + loadSubscriptionInfo: function() { var currentConfig = ConfigFileManager.getCurrentConfig() || ConfigFileManager.getSelectedConfig(); if (currentConfig && currentConfig !== this.currentConfigFile) { @@ -2853,21 +2969,21 @@ this.getSubscriptionInfo(); } }, - + getSubscriptionInfo: function() { if (ConfigFileManager.configList.length === 0) { return; } - + if (!this.currentConfigFile) return; - + var requestConfigFile = this.currentConfigFile; var filename = this.extractFilename(this.currentConfigFile); if (!filename) return; - + var cachedData = localStorage.getItem('sub_info_' + filename); var shouldFetchNew = true; - + if (cachedData) { try { var parsedData = JSON.parse(cachedData); @@ -2881,13 +2997,13 @@ this.showNoInfo(); } } - + if (parsedData.get_time) { var currentTime = Math.floor(Date.now() / 1000); var cacheTime = parseInt(parsedData.get_time); var timeDiff = currentTime - cacheTime; var halfHourInSeconds = 30 * 60; - + if (timeDiff <= halfHourInSeconds) { shouldFetchNew = false; } @@ -2896,8 +3012,10 @@ shouldFetchNew = true; } } - + if (shouldFetchNew) { + this.showLoading(); + StateManager.cachedXHRGetWithParams('<%=luci.dispatcher.build_url("admin", "services", "openclash", "sub_info_get")%>', {filename: filename}, function(x, status) { if (SubscriptionManager.currentConfigFile !== requestConfigFile) { return; @@ -2916,18 +3034,16 @@ }, true); } }, - + displaySubscriptionInfo: function(data) { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - var progressFill = document.getElementById('subscription-progress-fill'); - var infoText = document.getElementById('subscription-info-text'); - + if (!container) return; var configFileContent = document.querySelector('.config-file-content'); @@ -2936,101 +3052,241 @@ } container.style.display = 'flex'; - + if (data && data.sub_info && data.sub_info !== "No Sub Info Found") { - if (progressSection) { - progressSection.style.display = 'flex'; - } - - if (!progressFill || !infoText) return; - - var percent = data.percent || 0; - var used = data.surplus || data.used || '0 B'; - var total = data.total || '0 B'; - var expire = data.expire || ''; - var daysLeft = data.day_left || 0; - - progressFill.style.width = percent + '%'; - progressFill.className = 'subscription-progress-fill ' + - (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); - - var infoString = used + ' / ' + total + ' (' + percent + '%)'; - if (expire && daysLeft > 0) { - infoString += ' • ' + '<%:Remaining%> ' + daysLeft + ' <%:days%>'; - infoString += ' • ' + '<%:Expire Date%>: ' + expire; - } - - infoText.textContent = infoString; - if (infoText.scrollWidth > infoText.clientWidth) { - infoText.title = infoString; + if (data.providers && Array.isArray(data.providers) && data.providers.length > 0) { + if (data.providers.length > 1 || data.providers[0].provider_name) { + this.displayMultipleProviders(data.providers, progressSection); + } else { + this.displaySingleProvider(data.providers[0], progressSection); + } } else { - infoText.title = ''; - } - - } else { - if (progressSection) { progressSection.style.display = 'none'; } + } else { + progressSection.style.display = 'none'; } - + if (detailsSection) { detailsSection.style.display = 'flex'; } }, - + + displaySingleProvider: function(provider, progressSection) { + if (!progressSection) return; + + progressSection.innerHTML = ''; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; + + var progressBar = document.createElement('div'); + progressBar.className = 'subscription-progress-bar'; + + progressFill = document.createElement('div'); + progressFill.className = 'subscription-progress-fill'; + progressBar.appendChild(progressFill); + + infoText = document.createElement('div'); + infoText.className = 'subscription-info-text'; + + progressSection.appendChild(progressBar); + progressSection.appendChild(infoText); + + var percent = parseFloat(provider.percent) || 0; + var used = String(provider.surplus || provider.used || '0 B'); + var total = String(provider.total || '0 B'); + var expire = String(provider.expire || ''); + var daysLeft = parseInt(provider.day_left, 10); + if (isNaN(daysLeft)) daysLeft = 0; + + progressFill.style.width = percent + '%'; + progressFill.className = 'subscription-progress-fill ' + + (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); + + var infoString = used + ' / ' + total + ' (' + percent + '%)'; + var tooltipString = infoString; + if (expire && expire !== 'null' && daysLeft > 0) { + infoString += ' • ' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + tooltipString += '\n' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + infoText.textContent = infoString; + infoText.title = tooltipString; + }, + + displayMultipleProviders: function(providers, progressSection) { + if (!progressSection) return; + + var displayProviders = providers; + var providerCount = displayProviders.length; + + progressSection.innerHTML = ''; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-providers-grid'; + progressSection.setAttribute('data-count', providerCount); + + displayProviders.forEach(function(provider) { + var card = document.createElement('div'); + card.className = 'provider-card'; + + var cardName = document.createElement('div'); + var providerName = String(provider.provider_name || 'Unknown'); + cardName.className = 'subscription-info-title'; + cardName.textContent = providerName; + cardName.title = providerName; + card.appendChild(cardName); + + var progressBar = document.createElement('div'); + progressBar.className = 'subscription-progress-bar'; + + var progressFill = document.createElement('div'); + var percent = parseFloat(provider.percent) || 0; + progressFill.style.width = percent + '%'; + progressFill.className = 'subscription-progress-fill ' + + (percent >= 50 ? 'high' : (percent >= 20 ? 'medium' : 'low')); + + progressBar.appendChild(progressFill); + card.appendChild(progressBar); + + var infoText = document.createElement('div'); + infoText.className = 'subscription-info-text'; + + var used = String(provider.used || '0 B'); + var total = String(provider.total || 'N/A'); + var expire = String(provider.expire || ''); + var daysLeft = parseInt(provider.day_left, 10); + if (isNaN(daysLeft)) daysLeft = 0; + + var infoString = used + ' / ' + total + ' (' + percent + '%)'; + if (expire && expire !== 'null' && daysLeft > 0) { + infoString += ' • ' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + var tooltipString = used + ' / ' + total + ' (' + percent + '%)'; + if (expire && expire !== 'null' && daysLeft > 0) { + tooltipString += '\n' + expire + ' (<%:Remaining%> ' + daysLeft + ' <%:days%>)'; + } + + infoText.textContent = infoString; + infoText.title = tooltipString; + + card.appendChild(infoText); + progressSection.appendChild(card); + }); + + if (providerCount > 3) { + this.initDragScroll(progressSection); + } + }, + + initDragScroll: function(element) { + var isDragging = false; + var startX; + var scrollLeft; + var hasMoved = false; + + var onMouseDown = function(e) { + if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { + return; + } + + isDragging = true; + hasMoved = false; + startX = e.pageX - element.offsetLeft; + scrollLeft = element.scrollLeft; + element.classList.add('dragging'); + }; + + var onMouseMove = function(e) { + if (!isDragging) return; + + var x = e.pageX - element.offsetLeft; + var walk = (x - startX) * 1.5; + + if (Math.abs(walk) > 5) { + hasMoved = true; + e.preventDefault(); + element.scrollLeft = scrollLeft - walk; + } + }; + + var onMouseUp = function() { + isDragging = false; + element.classList.remove('dragging'); + }; + + var onMouseLeave = function() { + if (isDragging) { + isDragging = false; + element.classList.remove('dragging'); + } + }; + + element.addEventListener('mousedown', onMouseDown); + element.addEventListener('mousemove', onMouseMove); + element.addEventListener('mouseup', onMouseUp); + element.addEventListener('mouseleave', onMouseLeave); + + element.addEventListener('dragstart', function(e) { + e.preventDefault(); + }); + }, + showNoInfo: function() { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { return; } - + container.style.display = 'flex'; - + if (progressSection) { - progressSection.style.display = 'none'; + progressSection.innerHTML = '
<%:No Sub Info Found%>
'; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; } - + if (detailsSection) { var fileModifyTimeElement = document.getElementById('file-modify-time'); - + var hasFileInfo = false; if (fileModifyTimeElement) { var modifyTimeText = fileModifyTimeElement.textContent || ''; hasFileInfo = !modifyTimeText.includes('--'); } - + detailsSection.style.display = hasFileInfo ? 'flex' : 'none'; } }, - + showError: function() { if (ConfigFileManager.configList.length === 0) { return; } - + var container = document.getElementById('subscription-info-display'); var progressSection = document.getElementById('subscription-progress-section'); var detailsSection = document.getElementById('subscription-info-details'); - + if (!container) return; - + var configFileContent = document.querySelector('.config-file-content'); if (configFileContent && configFileContent.classList.contains('empty-state')) { return; } - + container.style.display = 'flex'; - + if (progressSection) { progressSection.style.display = 'none'; } @@ -3038,7 +3294,36 @@ detailsSection.style.display = 'none'; } }, - + + showLoading: function() { + if (ConfigFileManager.configList.length === 0) { + return; + } + + var container = document.getElementById('subscription-info-display'); + var progressSection = document.getElementById('subscription-progress-section'); + var detailsSection = document.getElementById('subscription-info-details'); + + if (!container) return; + + var configFileContent = document.querySelector('.config-file-content'); + if (configFileContent && configFileContent.classList.contains('empty-state')) { + return; + } + + container.style.display = 'flex'; + + if (progressSection) { + progressSection.innerHTML = '
<%:Collecting data...%>
'; + progressSection.style.display = 'flex'; + progressSection.className = 'subscription-progress'; + } + + if (detailsSection) { + detailsSection.style.display = 'none'; + } + }, + handleError: function() { if (this.retryCount >= this.maxRetries) { this.showError(); @@ -3053,32 +3338,32 @@ }, 5000); } }, - + extractFilename: function(path) { if (!path) return ''; var parts = path.split('/'); var filename = parts[parts.length - 1]; - + if (filename.endsWith('.yaml')) { filename = filename.slice(0, -5); } else if (filename.endsWith('.yml')) { filename = filename.slice(0, -4); } - + return filename; }, - + startAutoUpdate: function() { if (this.updateTimer) { clearTimeout(this.updateTimer); } - + this.updateTimer = setTimeout(function() { SubscriptionManager.getSubscriptionInfo(); SubscriptionManager.startAutoUpdate(); }, 60000 * 15); }, - + stopAutoUpdate: function() { if (this.updateTimer) { clearTimeout(this.updateTimer); @@ -3090,7 +3375,7 @@ var LogManager = { isPolling: false, pollTimer: null, - maxPollTime: 15000, + maxPollTime: 60000, pollInterval: 1000, startTime: 0, lastLogContent: '', @@ -3113,12 +3398,12 @@ DOMCache.oclog.style.display = 'inline-flex'; DOMCache.oclog.innerHTML = '' + (initialMessage || '<%:Processing...%>') + ''; } - + this.isPolling = true; this.startTime = Date.now(); this.lastLogContent = ''; this.retryCount = 0; - + var self = this; setTimeout(function() { if (self.isPolling) { @@ -3126,7 +3411,7 @@ } }, 2000); }, - + stopLogDisplay: function() { this.isPolling = false; if (this.pollTimer) { @@ -3143,15 +3428,15 @@ }, 1000); } }, - + pollLog: function() { if (!this.isPolling) return; - + if (Date.now() - this.startTime > this.maxPollTime) { this.stopLogDisplay(); return; } - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "startlog")%>', function(x, status) { if (!self.isPolling) return; @@ -3175,7 +3460,7 @@ }, 3000); return; } - + if (logContent !== '') { self.retryCount = 0; self.scheduleNextPoll(self.pollInterval); @@ -3208,12 +3493,12 @@ self.pollLog(); }, delay); }, - + checkForErrors: function(log) { if (!log) return false; if (log.match(/level=fatal|level=error|FTL \[Config]/)) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "del_start_log")%>', null, function(x) {}); - + var errorMsg; if (log.match(/level=(fatal|error)/)) { var msgParts = log.split('msg='); @@ -3222,32 +3507,32 @@ var ftlParts = log.split('FTL [Config] '); errorMsg = ftlParts.length > 1 ? ftlParts[1] : log; } - + setTimeout(function() { alert('<%:OpenClash Start Failed%>:\n\n' + errorMsg); }, 500); - + return true; } return false; }, - + displayLog: function(logContent) { if (!this.isPolling || !DOMCache.oclog) return; - + var cleanLog = this.cleanLogContent(logContent); this.lastLogContent = cleanLog; var color = this.getLogColor(cleanLog); var displayText = this.formatLogText(cleanLog); - + DOMCache.oclog.innerHTML = '' + displayText + ''; }, - + cleanLogContent: function(content) { return content ? content.replace(/[\r\n]+/g, ' ').replace('##FINISH##', '').trim() : ''; }, - + getLogColor: function(log) { if (log.includes("Tip:") || log.includes("提示:")) { return 'var(--warning-color)'; @@ -3263,22 +3548,22 @@ return 'var(--text-secondary)'; } }, - + formatLogText: function(log) { if (!log) return '<%:Processing...%>'; - + var cleanText = log.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[.\d]*Z?\s*/, '') .replace(/^time="[^"]*"\s*/, '') .replace(/^level=\w+\s*/, '') .replace(/^msg="?([^"]*)"?\s*/, '$1'); - + if (cleanText.length > 60) { cleanText = cleanText.substring(0, 57) + '...'; } - + return this.escapeHtml(cleanText) || '<%:Processing...%>'; }, - + escapeHtml: function(text) { var div = document.createElement('div'); div.textContent = text; @@ -3292,14 +3577,14 @@ retryCount: 0, maxRetries: 3, isEnabled: false, - + start: function() { if (this.isEnabled) return; this.isEnabled = true; this.retryCount = 0; this.poll(); }, - + stop: function() { this.isEnabled = false; if (this.pollTimer) { @@ -3307,10 +3592,10 @@ this.pollTimer = null; } }, - + poll: function() { if (!this.isEnabled) return; - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "toolbar_show_sys")%>', function(x, status) { if (x && x.status == 200 && x.responseText != "") { @@ -3318,14 +3603,14 @@ var cpuColor = status.cpu <= 50 ? "var(--success-color)" : (status.cpu <= 80 ? "var(--warning-color)" : "var(--error-color)"); var cpuValue = status.cpu <= 100 ? status.cpu + " %" : "0 %"; document.getElementById("cpu_t").innerHTML = ""+cpuValue+""; - + var loadValue = parseFloat(status.load_avg) || 0; var loadColor = loadValue <= 50 ? "var(--success-color)" : (loadValue <= 80 ? "var(--warning-color)" : "var(--error-color)"); document.getElementById("load_a").innerHTML = ""+status.load_avg+" %"; } else { self.handleError(); } - + if (self.isEnabled) { self.pollTimer = setTimeout(function() { self.poll(); @@ -3333,17 +3618,17 @@ } }, true); }, - + handleError: function() { this.retryCount++; - + if (this.retryCount >= this.maxRetries) { document.getElementById("cpu_t").innerHTML = "0 %"; document.getElementById("load_a").innerHTML = "0 %"; this.retryCount = 0; } }, - + setPollInterval: function(interval) { this.pollInterval = interval; } @@ -3355,14 +3640,14 @@ retryCount: 0, maxRetries: 3, isEnabled: false, - + start: function() { if (this.isEnabled) return; this.isEnabled = true; this.retryCount = 0; this.poll(); }, - + stop: function() { this.isEnabled = false; if (this.pollTimer) { @@ -3370,10 +3655,10 @@ this.pollTimer = null; } }, - + poll: function() { if (!this.isEnabled) return; - + var self = this; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "toolbar_show")%>', function(x, status) { if (x && x.status == 200 && x.responseText != "") { @@ -3382,7 +3667,7 @@ } else { self.handleError(); } - + if (self.isEnabled) { self.pollTimer = setTimeout(function() { self.poll(); @@ -3390,7 +3675,7 @@ } }, true); }, - + updateNetworkStats: function(status) { var updates = [ {element: document.getElementById("upload_"), content: ""+status.up+""}, @@ -3400,23 +3685,23 @@ {element: document.getElementById("mem_t"), content: ""+status.mem+""}, {element: document.getElementById("connect_t"), content: ""+status.connections+""} ]; - + if (!SystemStatusManager.isEnabled) { var cpuColor = status.cpu <= 50 ? "var(--success-color)" : (status.cpu <= 80 ? "var(--warning-color)" : "var(--error-color)"); var cpuValue = status.cpu <= 100 ? status.cpu + " %" : "0 %"; updates.push({element: document.getElementById("cpu_t"), content: ""+cpuValue+""}); - + var loadValue = parseFloat(status.load_avg) || 0; var loadColor = loadValue <= 50 ? "var(--success-color)" : (loadValue <= 80 ? "var(--warning-color)" : "var(--error-color)"); updates.push({element: document.getElementById("load_a"), content: ""+status.load_avg+" %"}); } - + StateManager.batchUpdateDOM(updates); }, - + handleError: function() { this.retryCount++; - + if (this.retryCount >= this.maxRetries) { var fallbackUpdates = [ {element: document.getElementById("upload_"), content: "0 B/S"}, @@ -3426,17 +3711,17 @@ {element: document.getElementById("mem_t"), content: "0 KB"}, {element: document.getElementById("connect_t"), content: "0"} ]; - + if (!SystemStatusManager.isEnabled) { fallbackUpdates.push({element: document.getElementById("cpu_t"), content: "0 %"}); fallbackUpdates.push({element: document.getElementById("load_a"), content: "0 %"}); } - + StateManager.batchUpdateDOM(fallbackUpdates); this.retryCount = 0; } }, - + setPollInterval: function(interval) { this.pollInterval = interval; } @@ -3445,18 +3730,18 @@ var SettingsManager = { pendingOperations: new Set(), pausedPolls: new Set(), - + pausePoll: function(pollName, duration) { this.pausedPolls.add(pollName); setTimeout(() => { this.pausedPolls.delete(pollName); }, duration || 3000); }, - + isPollPaused: function(pollName) { return this.pausedPolls.has(pollName); }, - + updateUIState: function(setting, value) { setTimeout(() => { function setCheckedAndDisabled(elements, checkedIndex) { @@ -3532,7 +3817,7 @@ } }, 10); }, - + switchSetting: function(setting, value, endpoint, additionalParams) { var operationKey = setting + '_' + value; @@ -3627,7 +3912,7 @@ return false; }, - + getErrorMessage: function(setting) { var messages = { 'meta_sniffer': '<%:Sniffer setting failed%>', @@ -3665,20 +3950,20 @@ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "openclash", "status")%>', null, function(x, status) { if (x && x.status == 200) { var updates = []; - + if (!pluginToggleUserAction) { updates.push({ element: DOMCache.clash, content: status.clash ? '' + status.core_type +' <%:Running%>' : '<%:Not Running%>' }); - + updatePluginToggleState(status.clash); } get_run_mode(); get_rule_mode(); get_oc_settings(); - + var webContent = status.clash ? '' : ''; updates.push({element: DOMCache.web, content: webContent}); @@ -3698,7 +3983,7 @@ var reloadFwContent = status.clash ? '' : ''; updates.push({element: document.getElementById('_reload_firewall_btn'), content: reloadFwContent}); - var flushCacheContent = status.clash ? '' : ''; + var flushCacheContent = status.clash ? '' : ''; updates.push({element: document.getElementById('_flush_dns_cache_btn'), content: flushCacheContent}); var oneKeyUpdateContent = ''; @@ -3706,11 +3991,19 @@ StateManager.batchUpdateDOM(updates); + if (!status.yacd) { + DOMCache.web.classList.add('hidden'); + } + + if (!status.dashboard) { + DOMCache.webo.classList.add('hidden'); + } + StateManager.current_status = status; - + if (status.daip) { var daipContent, dapoContent; - + if (status.daip && window.location.hostname == status.daip) { dapoContent = status.cn_port ? ":"+status.cn_port : ""; daipContent = status.daip ? ""+status.daip+dapoContent+"" : ""+"<%:Not Set%>"+""; @@ -3721,7 +4014,7 @@ dapoContent = status.cn_port ? ":"+status.cn_port : ""; daipContent = status.daip ? ""+status.daip+dapoContent+"" : ""+"<%:Not Set%>"+""; } - + DOMCache.daip.innerHTML = daipContent; StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "proxy_info")%>', function(x, proxy_info) { @@ -3745,7 +4038,7 @@ DOMCache.copy_mix_secret.style.display = "none"; DOMCache.copy_pac_config.style.display = "none"; } - + if (status.clash && status.daip) { if (!WSManager.hasActiveConnections()) { if (!WSManager._ws_error || WSManager._ws_retry < 3) { @@ -3759,7 +4052,7 @@ if (NetworkStatsManager && NetworkStatsManager.isEnabled) { NetworkStatsManager.stop(); } - + if (SystemStatusManager && !SystemStatusManager.isEnabled) { SystemStatusManager.start(); } @@ -3783,10 +4076,10 @@ if (!status || !status.clash || !status.daip) { return false; } - + var protocol = getWebSocketProtocol(status); var token = status.dase; - + var connections = [ { type: 'traffic', @@ -3804,19 +4097,19 @@ handler: ws_mmessage } ]; - + connections.forEach(function(conn) { var url = protocol + conn.endpoint + (token ? '?token=' + token : ''); WSManager.createConnection(conn.type, url, conn.handler); }); - + return true; } function getWebSocketProtocol(status) { var protocol = window.location.protocol === "https:" ? "wss://" : "ws://"; var host, port; - + if (status.daip && window.location.hostname === status.daip) { host = status.daip; port = status.cn_port; @@ -3828,14 +4121,14 @@ host = status.daip; port = status.cn_port; } - + return protocol + host + ":" + port; } function loadAnnouncement() { var userLang = navigator.language || navigator.userLanguage; var isChineseUser = userLang.indexOf('zh') === 0; - + var tips = [ '<%:Tip: You can modify the profile on the profile page (for content that is not taken over)%>', '<%:Tip: do not write configuration files? Try to create one click on the server page%>', @@ -3850,14 +4143,14 @@ '<%:Note: Some software will modify the device HOSTS, which will cause abnormal shunt, please pay attention to check%>', '<%:Note: The default proxy routes local traffic, BT, PT download, etc., please use Redir-Host mode as much as possible and pay attention to traffic avoidance%>' ]; - + function calculateAnimationDuration(bannerWidth, contentWidth) { var screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var refreshRate = window.screen && window.screen.refreshRate ? window.screen.refreshRate : 60; if (refreshRate <= 0) refreshRate = 60; - + if (refreshRate > 480) refreshRate = 480; - + var baseDuration; if (screenWidth <= 575) { baseDuration = 12000; @@ -3868,27 +4161,27 @@ } else { baseDuration = 9000; } - + var refreshRateMultiplier = 1; if (refreshRate > 60) { refreshRateMultiplier = 1 + (refreshRate - 60) / 240; } - + var duration = baseDuration * refreshRateMultiplier; - + return Math.max(4000, Math.min(duration, 18000)); } - + function updateScrollAnimation(banner, content, duration) { var bannerWidth = banner.offsetWidth; var contentWidth = content.offsetWidth; var scrollDistance = -(contentWidth + bannerWidth); - + banner.style.setProperty('--scroll-distance', scrollDistance + 'px'); - + content.style.animationDuration = duration + 'ms'; } - + function getRandomTips(count) { var shuffled = tips.slice(); for (var i = shuffled.length - 1; i > 0; i--) { @@ -3899,11 +4192,11 @@ } return shuffled.slice(0, count); } - + function updateIcon(isRandomTips) { var megaphoneElement = document.getElementById('megaphone'); if (!megaphoneElement) return; - + if (isRandomTips) { megaphoneElement.innerHTML = ''; megaphoneElement.setAttribute('viewBox', '0 0 256 256'); @@ -3913,22 +4206,22 @@ megaphoneElement.setAttribute('viewBox', '0 0 256 256'); } } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "announcement")%>', function(x, status) { var banner = document.getElementById('announcement-banner'); var content = document.getElementById('announcement-content'); var announcements = []; var isRandomTips = false; - + if (!banner || !content) return; - + if (x && x.status == 200 && status.content) { try { var contentData = status.content; if (typeof contentData === 'string') { contentData = JSON.parse(contentData); } - + if (Array.isArray(contentData)) { if (contentData.length > 0 && (contentData[0].zh || contentData[0].en)) { contentData.forEach(function(item) { @@ -3954,20 +4247,20 @@ } } } - + if (announcements.length === 0) { announcements = getRandomTips(3); isRandomTips = true; } - + updateIcon(isRandomTips); banner.style.display = 'block'; - + var currentIndex = 0; var isHovered = false; var pauseTimeout = null; var nextAnimationTimeout = null; - + banner.addEventListener('mouseenter', function() { isHovered = true; content.classList.add('paused'); @@ -3976,7 +4269,7 @@ isHovered = false; content.classList.remove('paused'); }); - + var resizeTimeout; window.addEventListener('resize', function() { clearTimeout(resizeTimeout); @@ -3987,50 +4280,50 @@ } }, 250); }); - + function startScrollAnimation() { if (nextAnimationTimeout) { clearTimeout(nextAnimationTimeout); nextAnimationTimeout = null; } - + content.textContent = announcements[currentIndex]; - + setTimeout(function() { var duration = calculateAnimationDuration(banner.offsetWidth, content.offsetWidth); updateScrollAnimation(banner, content, duration); - + content.classList.remove('scrolling'); content.offsetHeight; content.classList.add('scrolling'); - + var onAnimationEnd = function(e) { if (e.target === content && e.animationName === 'announceScroll') { content.removeEventListener('animationend', onAnimationEnd); - + pauseTimeout = setTimeout(function() { if (!isHovered) { currentIndex = (currentIndex + 1) % announcements.length; - + if (isRandomTips && currentIndex === 0) { announcements = getRandomTips(3); } - + startScrollAnimation(); } }, 2000); } }; - + content.addEventListener('animationend', onAnimationEnd); - + }, 50); } - + setTimeout(function() { startScrollAnimation(); }, 300); - + window.addEventListener('beforeunload', function() { if (pauseTimeout) clearTimeout(pauseTimeout); if (nextAnimationTimeout) clearTimeout(nextAnimationTimeout); @@ -4042,7 +4335,7 @@ if (SettingsManager.isPollPaused('rule_mode')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "rule_mode")%>', function(x, status) { if (x && x.status == 200 && status.mode != "") { if (!SettingsManager.pendingOperations.has('rule_mode_' + status.mode)) { @@ -4064,12 +4357,12 @@ '<%=luci.dispatcher.build_url("admin", "services", "openclash", "switch_rule_mode")%>' ); } - + function get_run_mode() { if (SettingsManager.isPollPaused('run_mode')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "get_run_mode")%>', function(x, status) { if (x && x.status == 200 && status.mode) { if (status.mode == "fake-ip" || status.mode == "fake-ip-tun" || status.mode == "fake-ip-mix") { @@ -4079,10 +4372,10 @@ DOMCache.mode.innerHTML = "<%:Redir-Host%>"; DOMCache.radio_run_normal.innerHTML = "<%:Compat%>"; } - + var expectedValue = status["mode"].split("-")[2] == undefined ? "" : ("-" + status["mode"].split("-")[2]); var operationKey = 'run_mode_' + status.mode; - + if (!SettingsManager.pendingOperations.has(operationKey)) { for (var i = 0; i < DOMCache.radio_ru.length; i++) { if (DOMCache.radio_ru[i].value == expectedValue && !DOMCache.radio_ru[i].checked) { @@ -4109,10 +4402,10 @@ window.location.href = url; } } - + function ws_terror() { WSManager._ws_error = true; - + NetworkStatsManager.start(); } @@ -4133,7 +4426,7 @@ uploadElement.innerHTML = data.up ? ""+bytesToSize(data.up)+"/S" : "0 B/S"; downloadElement.innerHTML = data.down ? ""+bytesToSize(data.down)+"/S" : "0 B/S"; } - + function ws_cmessage(event) { var dataObj = event && event.data !== undefined ? event.data : event; var data; @@ -4203,14 +4496,14 @@ return false; }; } - + var all_one_key_update = debounceButton(function(btn) { btn.value = '<%:Check Update%>'; btn.disabled = false; select_git_cdn(); return false; }); - + var b_flush_dns_cache = debounceButton(function(btn) { btn.disabled = true; btn.value = '<%:Flushing...%> '; @@ -4224,7 +4517,7 @@ btn.disabled = false; return false; }); - + var b_reload_firewall = debounceButton(function(btn) { btn.disabled = true; btn.value = '<%:Reloading...%>'; @@ -4245,7 +4538,7 @@ }); return false; }); - + function net_zashboard(btn) { if (StateManager.current_status) { var status = StateManager.current_status; @@ -4320,7 +4613,7 @@ winOpen(url1); return false; } - + function net_dashboard(btn) { if (StateManager.current_status) { var status = StateManager.current_status; @@ -4345,12 +4638,12 @@ winOpen(url2); return false; } - + function homepage() { url3 = 'https://github.com/vernesong/OpenClash'; winOpen(url3); } - + function gitbookpage() { url8 = 'https://wiki.metacubex.one'; winOpen(url8); @@ -4360,12 +4653,12 @@ url5 = 'https://github.com/vernesong/OpenClash/wiki'; winOpen(url5); } - + function telegrampage() { url6 = 'https://t.me/ctcgfw_openwrt_discuss'; winOpen(url6); } - + function sponsorpage() { url7 = 'https://ko-fi.com/vernesong'; winOpen(url7); @@ -4381,11 +4674,11 @@ if (!v1 || !v2) return 0; var ver1 = v1.replace(/^v/, '').split('.'); var ver2 = v2.replace(/^v/, '').split('.'); - + var maxLen = Math.max(ver1.length, ver2.length); while (ver1.length < maxLen) ver1.push('0'); while (ver2.length < maxLen) ver2.push('0'); - + for (var i = 0; i < maxLen; i++) { var num1 = parseInt(ver1[i], 10) || 0; var num2 = parseInt(ver2[i], 10) || 0; @@ -4404,7 +4697,7 @@ if (status.corelv && status.corelv !== "" && status.corelv !== "loading..." && status.corelv !== status.coremetacv) { hasUpdate = true; } - + DOMCache.core_version_text.textContent = coreVersionText; if (DOMCache.core_version_text.scrollWidth > DOMCache.core_version_text.clientWidth) { DOMCache.core_version_text.title = coreVersionText; @@ -4412,12 +4705,12 @@ DOMCache.core_version_text.title = ''; } DOMCache.core_version_display.style.display = 'flex'; - + var existingDot = DOMCache.core_version_display.querySelector('.update-dot'); if (existingDot) { existingDot.remove(); } - + if (hasUpdate) { var updateDot = document.createElement('span'); updateDot.className = 'update-dot'; @@ -4431,17 +4724,17 @@ DOMCache.core_version_display.style.display = 'none'; DOMCache.core_version_display.title = ''; } - + if (status.opcv && status.opcv !== "0") { var pluginVersionText = status.opcv; var hasUpdate = false; - + if (status.oplv && status.oplv !== "" && status.oplv !== "loading...") { if (compareVersions(status.oplv, status.opcv) > 0) { hasUpdate = true; } } - + DOMCache.plugin_version_text.textContent = pluginVersionText; if (DOMCache.plugin_version_text.scrollWidth > DOMCache.plugin_version_text.clientWidth) { DOMCache.plugin_version_text.title = pluginVersionText; @@ -4449,12 +4742,12 @@ DOMCache.plugin_version_text.title = ''; } DOMCache.plugin_version_display.style.display = 'flex'; - + var existingDot = DOMCache.plugin_version_display.querySelector('.update-dot'); if (existingDot) { existingDot.remove(); } - + if (hasUpdate) { var updateDot = document.createElement('span'); updateDot.className = 'update-dot'; @@ -4475,7 +4768,7 @@ function logo_error(imgobj, imgSrc) { imgobj.src = imgSrc; } - + function imgerrorfuns(imgobj, imgSrc) { setTimeout(function() { imgobj.src = imgSrc; @@ -4511,7 +4804,7 @@ function copyAddress() { var status = StateManager.current_status; var address; - + if (status.daip && window.location.hostname == status.daip) { address = 'http://' + status.daip + ':' + (status.cn_port || '9090') + '/ui/zashboard/#/setup?hostname=' + status.daip + '&port=' + (status.cn_port || '9090') + (status.dase ? '&secret=' + status.dase : ''); } else if (status.daip && window.location.hostname != status.daip && status.db_foward_domain && status.db_foward_port) { @@ -4520,7 +4813,7 @@ } else { address = 'http://' + (status.daip || 'unknown') + ':' + (status.cn_port || '9090') + '/ui/zashboard/#/'; } - + copyToClipboard(address, '<%:Control panel address copied:%> '); return false; } @@ -4565,19 +4858,19 @@ if (SettingsManager.isPollPaused('oc_settings')) { return; } - + StateManager.cachedXHRGet('<%=luci.dispatcher.build_url("admin", "services", "openclash", "oc_settings")%>', function(x, info) { if (x && x.status == 200) { if (!SettingsManager.pendingOperations.has('meta_sniffer_' + info.meta_sniffer)) { DOMCache.meta_sniffer_on.checked = info.meta_sniffer == "1"; DOMCache.meta_sniffer_off.checked = info.meta_sniffer != "1"; } - + if (!SettingsManager.pendingOperations.has('respect_rules_' + info.respect_rules)) { DOMCache.respect_rules_on.checked = info.respect_rules == "1"; DOMCache.respect_rules_off.checked = info.respect_rules != "1"; } - + if (!SettingsManager.pendingOperations.has('oversea_' + info.oversea)) { if (info.oversea == "0") { DOMCache.oc_setting_oversea_0.checked = true; @@ -4638,7 +4931,7 @@ port: window.location.port, href: window.location.href }; - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "generate_pac")%>', { client_protocol: currentUrl.protocol.replace(':', ''), client_hostname: currentUrl.hostname, @@ -4681,15 +4974,15 @@ textArea.style.left = "0"; textArea.style.position = "fixed"; textArea.style.opacity = "0"; - + document.body.appendChild(textArea); textArea.focus(); textArea.select(); - + try { var successful = document.execCommand('copy'); document.body.removeChild(textArea); - + if (successful) { prompt(successMessage, text); } else { @@ -4703,7 +4996,7 @@ function togglePlugin(toggleElement) { var isEnabled = toggleElement.checked; - + if (isEnabled) { var currentConfig = ConfigFileManager.getCurrentConfig() || ConfigFileManager.getSelectedConfig(); if (!currentConfig) { @@ -4717,29 +5010,29 @@ pluginToggleUserAction = true; var action = isEnabled ? 'start' : 'stop'; var initialMessage = isEnabled ? '<%:Starting...%>' : '<%:Stopping...%>'; - + LogManager.startLogDisplay(initialMessage); - + var requestParams = { action: action }; - + if (isEnabled) { var currentConfig = ConfigFileManager.getCurrentConfig(); var selectedConfig = ConfigFileManager.getSelectedConfig(); - + if (!currentConfig && selectedConfig) { requestParams.config_file = configFileName; } } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "action")%>', requestParams, function(x, status) { if (x && x.status == 200) { setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 3000); + }, 2000); } else { toggleElement.checked = !isEnabled; - + var errorMessage = isEnabled ? '<%:Failed to start OpenClash%>' : '<%:Failed to stop OpenClash%>'; @@ -4748,7 +5041,7 @@ if (DOMCache.clash) { DOMCache.clash.innerHTML = '<%:Operation Failed%>'; } - + pluginToggleUserAction = false; } toggleElement.disabled = false; @@ -4759,22 +5052,22 @@ if (pluginToggleUserAction) { return; } - + var toggleElement = document.getElementById('plugin_toggle'); if (toggleElement) { toggleElement.checked = isRunning; toggleElement.disabled = false; - + if (DOMCache.clash && StateManager.current_status) { DOMCache.clash.innerHTML = isRunning ? '' + StateManager.current_status.core_type +' <%:Running%>' : '<%:Not Running%>'; } - + if (!isRunning && StateManager.current_status && !StateManager.current_status.clash) { setTimeout(function() { updatePluginToggleState(StateManager.current_status.clash || false); - }, 3000); + }, 2000); } } } @@ -4785,11 +5078,11 @@ alert('<%:Please select a config file first%>'); return false; } - + pluginToggleUserAction = true; - + LogManager.startLogDisplay('<%:Switching Config...%>'); - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "switch_config")%>', { config_file: currentConfig }, function(x, status) { @@ -4798,28 +5091,28 @@ setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 4000); + }, 2000); } else { alert('<%:Failed to switch config file:%> ' + (status.message || '<%:Unknown error%>')); - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Switch Failed%>'; } - + pluginToggleUserAction = false; } }); return false; } - + function updateConfig() { var currentConfig = ConfigFileManager.getSelectedConfig(); if (!currentConfig) { alert('<%:Please select a config file first%>'); return false; } - + var filename = SubscriptionManager.extractFilename(currentConfig); if (!filename) { alert('<%:Invalid config file selected%>'); @@ -4827,7 +5120,7 @@ } pluginToggleUserAction = true; - + LogManager.startLogDisplay('<%:Updating Config...%>'); XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "update_config")%>', { @@ -4836,30 +5129,30 @@ if (x && x.status == 200) { if (status.status === 'success') { setTimeout(function() { - + refreshSubscriptionInfo(); - + ConfigFileManager.refreshConfigList(); - + pluginToggleUserAction = false; - + }, 2000); } else { pluginToggleUserAction = false; - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Update Failed%>'; } - + alert('<%:Failed to update config file:%> ' + (status.message || status.error || '<%:Unknown error%>')); } } else { pluginToggleUserAction = false; - + if (DOMCache.oclog) { DOMCache.oclog.innerHTML = '<%:Update Failed%>'; } - + alert('<%:Failed to update config file, please try again later%>'); } }); @@ -4875,36 +5168,36 @@ } pluginToggleUserAction = true; - + var toggleElement = document.getElementById('plugin_toggle'); if (toggleElement) { toggleElement.disabled = true; } - + LogManager.startLogDisplay('<%:Restarting...%>'); - + var requestParams = { action: 'restart' }; - + var currentConfigValue = ConfigFileManager.getCurrentConfig(); var selectedConfig = ConfigFileManager.getSelectedConfig(); - + if (!currentConfigValue && selectedConfig) { requestParams.config_file = configFileName; } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "action")%>', requestParams, function(x, status) { if (x && x.status == 200) { setTimeout(function() { pluginToggleUserAction = false; updatePluginToggleState(StateManager.current_status.clash || false); - }, 5000); + }, 2000); ConfigFileManager.refreshConfigList(); } else { if (toggleElement) { toggleElement.disabled = false; } alert('<%:Failed to restart core%>'); - + pluginToggleUserAction = false; } }); @@ -4917,34 +5210,34 @@ alert('<%:Please select a config file first%>'); return false; } - + SubscriptionManager.currentConfigFile = currentConfig; SubscriptionManager.retryCount = 0; - + var filename = SubscriptionManager.extractFilename(currentConfig); localStorage.removeItem('sub_info_' + filename); SubscriptionManager.getSubscriptionInfo(); return false; } - + function setSubscriptionUrl() { var currentConfig = ConfigFileManager.getSelectedConfig(); if (!currentConfig) { alert('<%:Please select a config file first%>'); return false; } - + var filename = SubscriptionManager.extractFilename(currentConfig); if (!filename) { alert('<%:Invalid config file selected%>'); return false; } - + var newUrl = prompt('<%:Paste the new url of subscribe infos sources here:%>', ''); if (newUrl === null) { return false; } - + XHR.get('<%=luci.dispatcher.build_url("admin", "services", "openclash", "set_subinfo_url")%>', { filename: filename, url: newUrl @@ -4957,7 +5250,7 @@ alert('<%:Specify subscribe infos sources url failed:%>\n' + (status.info || '<%:Unknown error%>')); } }); - + return false; } @@ -4973,7 +5266,7 @@ } }, 500); } - + return false; } @@ -4983,7 +5276,7 @@ alert('<%:Please select a config file first%>'); return false; } - + if (typeof ConfigEditor !== 'undefined' && ConfigEditor.show) { ConfigEditor.show(currentConfig); } else { @@ -4995,7 +5288,7 @@ } }, 500); } - + return false; } @@ -5011,7 +5304,7 @@ } }, 500); } - + return false; } @@ -5048,7 +5341,7 @@ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { return true; } - + var style = window.getComputedStyle(element); var bgColor = style.backgroundColor; let r, g, b; @@ -5074,9 +5367,13 @@ return luminance < 128; }; - function toggleTheme() { - var currentTheme = localStorage.getItem('oc-theme') || (isDarkBackground(document.body) ? 'dark' : 'light'); - var newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + function toggleThemeMode() { + var themes = ['light', 'dark', 'auto']; + var currentTheme = localStorage.getItem('oc-theme') || 'auto'; + var currentIndex = themes.indexOf(currentTheme); + if (currentIndex === -1) currentIndex = 2; + var newIndex = (currentIndex + 1) % themes.length; + var newTheme = themes[newIndex]; localStorage.setItem('oc-theme', newTheme); DarkModeDetector.init(); } diff --git a/small/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm b/small/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm index db72bbca15..d359a94fa8 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/sub_info_show.htm @@ -17,7 +17,7 @@ min-width: 0; } -.sub_tab{ +.sub_tab { display: block; white-space: nowrap; font-size: 12px; @@ -29,7 +29,7 @@ box-sizing: border-box; } -.sub_tab_show{ +.sub_tab_show { display: block; white-space: nowrap; font-size: 12px; @@ -46,7 +46,7 @@ box-sizing: border-box; } -.sub_setting{ +.sub_setting { display: inline-block; white-space: nowrap; margin: 0; @@ -67,7 +67,7 @@ opacity: 0.7; } -.text_show{ +.text_show { color: #333333; line-height: 1.2; } @@ -131,11 +131,11 @@ .sub_tab, .sub_tab_show { font-size: 11px; } - + .progress_bar_bg { min-width: 220px; } - + .sub_div { gap: 6px; width: calc(100% - 20px); @@ -147,15 +147,15 @@ .sub_tab, .sub_tab_show { font-size: 10px; } - + .progress_bar_bg { min-width: 200px; } - + .sub_setting img { height: 18px !important; } - + .sub_div { gap: 4px; width: calc(100% - 16px); @@ -167,15 +167,15 @@ .sub_tab, .sub_tab_show { font-size: 9px; } - + .progress_bar_bg { min-width: 180px !important; } - + .sub_setting img { height: 16px !important; } - + .sub_div { gap: 2px; width: calc(100% - 12px); @@ -187,15 +187,15 @@ .sub_tab, .sub_tab_show { font-size: 8px; } - + .progress_bar_bg { min-width: 160px !important; } - + .sub_setting img { height: 14px !important; } - + .sub_div { width: calc(100% - 8px); margin: 0 4px; @@ -209,6 +209,169 @@ .sub_div > span:first-child { flex-shrink: 1; } + +/* Multiple providers container */ +.sub_providers_container { + display: flex; + gap: 4px; + flex: 1; + min-width: 0; + overflow-x: auto; + scrollbar-width: thin; + cursor: grab; + user-select: none; +} + +.sub_providers_container.no-scroll { + overflow-x: hidden; + cursor: default; +} + +.sub_providers_container::-webkit-scrollbar { + height: 4px; +} + +.sub_providers_container::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 2px; +} + +.sub_providers_container::-webkit-scrollbar-thumb { + background: #888; + border-radius: 2px; +} + +.sub_providers_container::-webkit-scrollbar-thumb:hover { + background: #555; +} + +.sub_providers_container.dragging { + cursor: grabbing; +} + +.sub_provider_item { + flex: 0 0 auto; + width: 100px; + position: relative; + min-height: 36px; + background-color: #f5f5f5; + border: 1px solid #999999; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; +} + +.sub_provider_fill { + position: absolute; + left: 0; + top: 0; + bottom: 0; + transition: width 0.3s ease; + border-radius: 5px; +} + +.sub_provider_fill.progress_bar_high { + background-color: #9edd9e; +} + +.sub_provider_fill.progress_bar_medium { + background-color: #ffc99f; +} + +.sub_provider_fill.progress_bar_low { + background-color: #ffb9b9; +} + +.sub_provider_name { + position: relative; + z-index: 1; + font-size: 12px; + color: #333; + font-weight: 500; + text-align: center; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + padding: 0 4px; +} + +/* Dark mode support */ +:root[data-darkmode="true"] .sub_provider_item { + background-color: #333333; + border-color: #666666; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_high { + background-color: #5da05d; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_medium { + background-color: #cc8550; +} + +:root[data-darkmode="true"] .sub_provider_fill.progress_bar_low { + background-color: #cc6262; +} + +:root[data-darkmode="true"] .sub_provider_name { + color: #e0e0e0; +} + +/* Responsive adjustments for multiple providers */ +@media (max-width: 1024px) { + .sub_providers_container { + gap: 3px; + } + + .sub_provider_item { + width: 90px; + } + + .sub_provider_name { + font-size: 11px; + } +} + +@media (max-width: 768px) { + .sub_providers_container { + gap: 2px; + } + + .sub_provider_item { + width: 80px; + min-height: 32px; + } + + .sub_provider_name { + font-size: 10px; + } +} + +@media (max-width: 480px) { + .sub_provider_item { + width: 70px; + min-height: 30px; + padding: 0 2px; + } + + .sub_provider_name { + font-size: 9px; + } +} + +@media (max-width: 320px) { + .sub_provider_item { + width: 60px; + min-height: 28px; + } + + .sub_provider_name { + font-size: 8px; + } +} <% @@ -245,7 +408,7 @@ function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) { var fontSize = '12px'; var minWidth = '220px'; var topPosition = tr == "null" ? '6px' : '2px'; - + if (screenWidth <= 320) { fontSize = '8px'; minWidth = '160px'; @@ -263,23 +426,135 @@ function progressbar_<%=idname%>(v, m, pc, np, f, t, tr) { minWidth = '220px'; topPosition = tr == "null" ? '6px' : '2px'; } - + + // Build title for native tooltip (format: "v / m (pc%)\nt (Remaining tr days)") + var titleText = v + ' / ' + m + ' (' + pc + '%%)'; + if (t && t !== 'null' && tr && tr !== 'null' && parseInt(tr) > 0) { + titleText += '\n' + t + ' (<%:Remaining%> ' + tr + ' <%:days%>)'; + } + return String.format( - '
' + - (pc >= 50 ? '
' : - (pc < 50 && pc >= 20 ? '
' : + '
' + + (pc >= 50 ? '
' : + (pc < 50 && pc >= 20 ? '
' : '
')) + '
' + - '%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + - (tr == "null" ? '
' : '
') + + '%s '+ (f ? f : '/') +' %s ' + (np ? "" : '(%s%%)') + + (tr == "null" ? '
' : '
') + '%s (<%:Remaining%> %s <%:days%>)' + '
' + '
' + - '
', + '
', minWidth, pc, fontSize, v, m, pc, t, tr ); }; +function progressbar_multi_<%=idname%>(providers) { + if (!providers || !Array.isArray(providers) || providers.length === 0) { + return 'No Providers'; + } + + var providerCount = providers.length; + var itemWidth; + var containerClass = 'sub_providers_container'; + + if (providerCount === 2) { + itemWidth = 'calc(50% - 2px)'; + containerClass += ' no-scroll'; + } else if (providerCount === 3) { + itemWidth = 'calc(33.33% - 2.67px)'; + containerClass += ' no-scroll'; + } else { + itemWidth = '100px'; + } + + var container = '
'; + + providers.forEach(function(provider) { + var percent = parseFloat(provider.percent) || 0; + var providerName = provider.provider_name || 'Unknown'; + var used = provider.used || '0 B'; + var total = provider.total || 'N/A'; + var surplus = provider.surplus || used; + var expire = provider.expire || 'null'; + var dayLeft = parseInt(provider.day_left) || 0; + + // Determine background color based on percentage + var bgColorClass = percent >= 50 ? 'progress_bar_high' : + (percent >= 20 ? 'progress_bar_medium' : 'progress_bar_low'); + + // Build title for native tooltip (format: "surplus / total (percent%)\nexpire (Remaining dayLeft days)") + var titleText = surplus + ' / ' + total + ' (' + percent + '%)'; + if (expire !== 'null' && dayLeft > 0) { + titleText += '\n' + expire + ' (<%:Remaining%> ' + dayLeft + ' <%:days%>)'; + } + + container += '
' + + '
' + + '' + providerName + '' + + '
'; + }); + + container += '
'; + + if (providerCount > 3) { + setTimeout(function() { + initDragScroll_<%=idname%>(); + }, 100); + } + + return container; +} + +function initDragScroll_<%=idname%>() { + var container = document.getElementById('sub_providers_<%=idname%>'); + if (!container) return; + + var isDragging = false; + var startX; + var scrollLeft; + var hasMoved = false; + + container.addEventListener('mousedown', function(e) { + if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { + return; + } + + isDragging = true; + hasMoved = false; + startX = e.pageX - container.offsetLeft; + scrollLeft = container.scrollLeft; + container.classList.add('dragging'); + }); + + container.addEventListener('mousemove', function(e) { + if (!isDragging) return; + + var x = e.pageX - container.offsetLeft; + var walk = (x - startX) * 2; + + if (Math.abs(walk) > 5) { + hasMoved = true; + e.preventDefault(); + container.scrollLeft = scrollLeft - walk; + } + }); + + container.addEventListener('mouseup', function() { + isDragging = false; + container.classList.remove('dragging'); + }); + + container.addEventListener('mouseleave', function() { + isDragging = false; + container.classList.remove('dragging'); + }); + + container.addEventListener('dragstart', function(e) { + e.preventDefault(); + }); +} + function sub_info_refresh_<%=idname%>() { if (s_<%=idname%>) { clearTimeout(s_<%=idname%>);}; @@ -288,7 +563,31 @@ function sub_info_refresh_<%=idname%>() retry_<%=idname%> = 0; localStorage.setItem("sub_info_<%=filename%>",JSON.stringify(status)); document.getElementById('<%=idname%>').className = "sub_tab_show"; - document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>((status.surplus ? status.surplus : status.used), (status.total), (status.percent), false, false, (status.expire), (status.day_left)); + + if (status.providers && Array.isArray(status.providers) && status.providers.length > 0) { + if (status.providers.length === 1) { + var provider = status.providers[0]; + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (provider.surplus ? provider.surplus : provider.used), + (provider.total), + (provider.percent), + false, false, + (provider.expire), + (provider.day_left) + ); + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(status.providers); + } + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (status.surplus ? status.surplus : status.used), + (status.total), + (status.percent), + false, false, + (status.expire), + (status.day_left) + ); + } } else if ( x && x.status == 200 && status.sub_info == "No Sub Info Found" ) { retry_<%=idname%> = 0; @@ -310,7 +609,7 @@ function sub_info_refresh_<%=idname%>() s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*120); return } - + }; s_<%=idname%> = setTimeout("sub_info_refresh_<%=idname%>()",1000*1800); }); @@ -325,7 +624,30 @@ function sub_info_get_<%=idname%>() document.getElementById('<%=idname%>').innerHTML = "<%:No Sub Info Found%>"; } else { - document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>((save_info.surplus ? save_info.surplus : save_info.used), (save_info.total), (save_info.percent ? save_info.percent : 0), false, false, (save_info.expire), (save_info.day_left ? save_info.day_left : 0)); + if (save_info.providers && Array.isArray(save_info.providers) && save_info.providers.length > 0) { + if (save_info.providers.length === 1) { + var provider = save_info.providers[0]; + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (provider.surplus ? provider.surplus : provider.used), + (provider.total), + (provider.percent ? provider.percent : 0), + false, false, + (provider.expire), + (provider.day_left ? provider.day_left : 0) + ); + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_multi_<%=idname%>(save_info.providers); + } + } else { + document.getElementById('<%=idname%>').innerHTML = progressbar_<%=idname%>( + (save_info.surplus ? save_info.surplus : save_info.used), + (save_info.total), + (save_info.percent ? save_info.percent : 0), + false, false, + (save_info.expire), + (save_info.day_left ? save_info.day_left : 0) + ); + } } } else { diff --git a/small/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm b/small/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm index e838c25e80..60968ad4c9 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/switch_dashboard.htm @@ -32,7 +32,7 @@ } } }); - + function switch_dashboard(btn, name, type) { btn.disabled = true; @@ -82,5 +82,5 @@ } //]]> - + <%+cbi/valuefooter%> \ No newline at end of file diff --git a/small/luci-app-openclash/luasrc/view/openclash/switch_mode.htm b/small/luci-app-openclash/luasrc/view/openclash/switch_mode.htm index d79dd258e1..7265eab8f7 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/switch_mode.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/switch_mode.htm @@ -21,7 +21,7 @@ } } }); - + function switch_modes(btn) { btn.disabled = true; @@ -42,4 +42,4 @@ } //]]> - + diff --git a/small/luci-app-openclash/luasrc/view/openclash/tblsection.htm b/small/luci-app-openclash/luasrc/view/openclash/tblsection.htm index 480c1bbfef..59c8ed55b4 100644 --- a/small/luci-app-openclash/luasrc/view/openclash/tblsection.htm +++ b/small/luci-app-openclash/luasrc/view/openclash/tblsection.htm @@ -55,7 +55,7 @@ local sectiontype = "_"..self.config.."_"..string.match(self.sectiontype, "[%w_] + <%+cbi/valuefooter%> diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index e2b6c4c3e6..2ffd759e94 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=6878dbacfb1fcb1ee022f63ed6934bcefc95a3c4ba10c88f1131fb88dbf7c337 endef -GEOSITE_VER:=20251230092642 +GEOSITE_VER:=20251231122054 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=27f02a97c8a6b5504d239f6d9246262010243573cf4deb28ddc4ea0b094a4d18 + HASH:=7ab59e775822ec207a0e12ca633f97de81c67cf5e7a38901caf97a775735bc03 endef GEOSITE_IRAN_VER:=202512290048 diff --git a/v2rayng/.github/workflows/build.yml b/v2rayng/.github/workflows/build.yml index e644dd9af0..965328c6de 100644 --- a/v2rayng/.github/workflows/build.yml +++ b/v2rayng/.github/workflows/build.yml @@ -38,26 +38,26 @@ jobs: \ ndkVersion = "28.2.13676358"' ${{ github.workspace }}/V2rayNG/app/build.gradle.kts - - name: Restore cached libtun2socks - id: cache-libtun2socks-restore + - name: Restore cached libhevtun + id: cache-libhevtun-restore uses: actions/cache/restore@v4 with: path: ${{ github.workspace }}/libs - key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }} + key: libhevtun-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('compile-hevtun.sh') }} - - name: Build libtun2socks - if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true' + - name: Build libhevtun + if: steps.cache-libhevtun-restore.outputs.cache-hit != 'true' run: | - bash compile-tun2socks.sh && bash compile-hevtun.sh + bash compile-hevtun.sh - - name: Save libtun2socks - if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true' + - name: Save libhevtun + if: steps.cache-libhevtun-restore.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: ${{ github.workspace }}/libs - key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }} + key: libhevtun-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('compile-hevtun.sh') }} - - name: Copy libtun2socks + - name: Copy libhevtun run: | cp -r ${{ github.workspace }}/libs ${{ github.workspace }}/V2rayNG/app diff --git a/v2rayng/.gitmodules b/v2rayng/.gitmodules index 873f22c76e..0e9eca3ee0 100644 --- a/v2rayng/.gitmodules +++ b/v2rayng/.gitmodules @@ -4,12 +4,6 @@ [submodule "AndroidLibXrayLite"] path = AndroidLibXrayLite url = https://github.com/2dust/AndroidLibXrayLite -[submodule "badvpn"] - path = badvpn - url = https://github.com/XTLS/badvpn -[submodule "libancillary"] - path = libancillary - url = https://github.com/shadowsocks/libancillary [submodule "hev-socks5-tunnel"] path = hev-socks5-tunnel url = https://github.com/heiher/hev-socks5-tunnel diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt index e035f6877b..4dd19c8f95 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt @@ -40,6 +40,8 @@ data class ProfileItem( var alpn: String? = null, var fingerPrint: String? = null, var insecure: Boolean? = null, + var echConfigList: String? = null, + var echForceQuery: String? = null, var publicKey: String? = null, var shortId: String? = null, diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt index 2b3ddbfcb2..1a598d31ce 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt @@ -267,6 +267,8 @@ data class V2rayConfig( val certificates: List? = null, val disableSystemRoot: Boolean? = null, val enableSessionResumption: Boolean? = null, + var echConfigList: String? = null, + var echForceQuery: String? = null, // REALITY settings val show: Boolean = false, var publicKey: String? = null, diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt index bbd2989cb4..2ba5d9de36 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt @@ -82,6 +82,7 @@ open class FmtBase { config.sni = queryParam["sni"] config.fingerPrint = queryParam["fp"] config.alpn = queryParam["alpn"] + config.echConfigList = queryParam["ech"] config.publicKey = queryParam["pbk"] config.shortId = queryParam["sid"] config.spiderX = queryParam["spx"] @@ -100,6 +101,7 @@ open class FmtBase { dicQuery["security"] = config.security?.ifEmpty { "none" }.orEmpty() config.sni.let { if (it.isNotNullEmpty()) dicQuery["sni"] = it.orEmpty() } config.alpn.let { if (it.isNotNullEmpty()) dicQuery["alpn"] = it.orEmpty() } + config.echConfigList.let { if (it.isNotNullEmpty()) dicQuery["ech"] = it.orEmpty() } config.fingerPrint.let { if (it.isNotNullEmpty()) dicQuery["fp"] = it.orEmpty() } config.publicKey.let { if (it.isNotNullEmpty()) dicQuery["pbk"] = it.orEmpty() } config.shortId.let { if (it.isNotNullEmpty()) dicQuery["sid"] = it.orEmpty() } diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index 5b09dabe65..f70e427fc0 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -1223,6 +1223,8 @@ object V2rayConfigManager { } val fingerprint = profileItem.fingerPrint val alpns = profileItem.alpn + val echConfigList = profileItem.echConfigList + val echForceQuery = profileItem.echForceQuery val publicKey = profileItem.publicKey val shortId = profileItem.shortId val spiderX = profileItem.spiderX @@ -1235,6 +1237,8 @@ object V2rayConfigManager { serverName = if (sni.isNullOrEmpty()) null else sni, fingerprint = if (fingerprint.isNullOrEmpty()) null else fingerprint, alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() }, + echConfigList = if (echConfigList.isNullOrEmpty()) null else echConfigList, + echForceQuery = if (echForceQuery.isNullOrEmpty()) null else echForceQuery, publicKey = if (publicKey.isNullOrEmpty()) null else publicKey, shortId = if (shortId.isNullOrEmpty()) null else shortId, spiderX = if (spiderX.isNullOrEmpty()) null else spiderX, diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt index 4e2ebf9370..b29c77a113 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt @@ -82,6 +82,9 @@ class ServerActivity : BaseActivity() { private val xhttpMode: Array by lazy { resources.getStringArray(R.array.xhttp_mode) } + private val echForceQuerys: Array by lazy { + resources.getStringArray(R.array.ech_force_query_value) + } // Kotlin synthetics was used, but since it is removed in 1.8. We switch to old manual approach. @@ -130,6 +133,10 @@ class ServerActivity : BaseActivity() { private val et_bandwidth_up: EditText? by lazy { findViewById(R.id.et_bandwidth_up) } private val et_extra: EditText? by lazy { findViewById(R.id.et_extra) } private val layout_extra: LinearLayout? by lazy { findViewById(R.id.layout_extra) } + private val et_ech_config_list: EditText? by lazy { findViewById(R.id.et_ech_config_list) } + private val container_ech_config_list: LinearLayout? by lazy { findViewById(R.id.lay_ech_config_list) } + private val sp_ech_force_query: Spinner? by lazy { findViewById(R.id.sp_ech_force_query) } + private val container_ech_force_query: LinearLayout? by lazy { findViewById(R.id.lay_ech_force_query) } override fun onCreate(savedInstanceState: Bundle?) { @@ -263,7 +270,9 @@ class ServerActivity : BaseActivity() { container_public_key, container_short_id, container_spider_x, - container_mldsa65_verify + container_mldsa65_verify, + container_ech_config_list, + container_ech_force_query ).forEach { it?.visibility = View.GONE } } @@ -272,9 +281,11 @@ class ServerActivity : BaseActivity() { listOf( container_sni, container_fingerprint, - container_alpn + container_alpn, + container_allow_insecure, + container_ech_config_list, + container_ech_force_query ).forEach { it?.visibility = View.VISIBLE } - container_allow_insecure?.visibility = View.VISIBLE listOf( container_public_key, container_short_id, @@ -285,11 +296,16 @@ class ServerActivity : BaseActivity() { // Case 3: Other reality values else -> { - listOf(container_sni, container_fingerprint).forEach { - it?.visibility = View.VISIBLE - } - container_alpn?.visibility = View.GONE - container_allow_insecure?.visibility = View.GONE + listOf( + container_sni, + container_fingerprint + ).forEach { it?.visibility = View.VISIBLE } + listOf( + container_alpn, + container_allow_insecure, + container_ech_config_list, + container_ech_force_query + ).forEach { it?.visibility = View.GONE } listOf( container_public_key, container_short_id, @@ -357,10 +373,6 @@ class ServerActivity : BaseActivity() { val streamSecurity = Utils.arrayFind(streamSecuritys, config.security.orEmpty()) if (streamSecurity >= 0) { sp_stream_security?.setSelection(streamSecurity) - container_sni?.visibility = View.VISIBLE - container_fingerprint?.visibility = View.VISIBLE - container_alpn?.visibility = View.VISIBLE - et_sni?.text = Utils.getEditable(config.sni) config.fingerPrint?.let { it -> val utlsIndex = Utils.arrayFind(uTlsItems, it) @@ -371,42 +383,23 @@ class ServerActivity : BaseActivity() { alpnIndex.let { sp_stream_alpn?.setSelection(if (it >= 0) it else 0) } } if (config.security == TLS) { - container_allow_insecure?.visibility = View.VISIBLE val allowinsecure = Utils.arrayFind(allowinsecures, config.insecure.toString()) if (allowinsecure >= 0) { sp_allow_insecure?.setSelection(allowinsecure) } - listOf( - container_public_key, - container_short_id, - container_spider_x, - container_mldsa65_verify - ).forEach { it?.visibility = View.GONE } + et_ech_config_list?.text = Utils.getEditable(config.echConfigList) + config.echForceQuery?.let { it -> + val index = Utils.arrayFind(echForceQuerys, it) + index.let { sp_ech_force_query?.setSelection(if (it >= 0) it else 0) } + } } else if (config.security == REALITY) { - container_public_key?.visibility = View.VISIBLE et_public_key?.text = Utils.getEditable(config.publicKey.orEmpty()) - container_short_id?.visibility = View.VISIBLE et_short_id?.text = Utils.getEditable(config.shortId.orEmpty()) - container_spider_x?.visibility = View.VISIBLE et_spider_x?.text = Utils.getEditable(config.spiderX.orEmpty()) - container_mldsa65_verify?.visibility = View.VISIBLE et_mldsa65_verify?.text = Utils.getEditable(config.mldsa65Verify.orEmpty()) - container_allow_insecure?.visibility = View.GONE } } - if (config.security.isNullOrEmpty()) { - listOf( - container_sni, - container_fingerprint, - container_alpn, - container_allow_insecure, - container_public_key, - container_short_id, - container_spider_x, - container_mldsa65_verify - ).forEach { it?.visibility = View.GONE } - } val network = Utils.arrayFind(networks, config.network.orEmpty()) if (network >= 0) { sp_network?.setSelection(network) @@ -569,6 +562,8 @@ class ServerActivity : BaseActivity() { val shortId = et_short_id?.text?.toString() val spiderX = et_spider_x?.text?.toString() val mldsa65Verify = et_mldsa65_verify?.text?.toString() + val echConfigList = et_ech_config_list?.text?.toString() + val echForceQueryIndex = sp_ech_force_query?.selectedItemPosition ?: 0 val allowInsecure = if (allowInsecureField == null || allowinsecures[allowInsecureField].isBlank()) { @@ -586,6 +581,8 @@ class ServerActivity : BaseActivity() { config.shortId = shortId config.spiderX = spiderX config.mldsa65Verify = mldsa65Verify + config.echConfigList = echConfigList + config.echForceQuery = echForceQuerys[echForceQueryIndex] } private fun transportTypes(network: String?): Array { diff --git a/v2rayng/V2rayNG/app/src/main/res/layout/layout_tls.xml b/v2rayng/V2rayNG/app/src/main/res/layout/layout_tls.xml index 1866660f1e..c75a79f03a 100644 --- a/v2rayng/V2rayNG/app/src/main/res/layout/layout_tls.xml +++ b/v2rayng/V2rayNG/app/src/main/res/layout/layout_tls.xml @@ -113,7 +113,49 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_spacing_dp8" android:layout_marginBottom="@dimen/padding_spacing_dp8" - android:entries="@array/allowinsecures" /> + android:entries="@array/allowinsecures" + android:nextFocusDown="@+id/et_ech_config_list"/> + + + + + + + + + + + + + + + + android:nextFocusDown="@+id/et_short_id" /> @@ -154,7 +196,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:nextFocusDown="@+id/et_spider_x" /> @@ -175,7 +217,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:nextFocusDown="@+id/et_mldsa65_verify" /> @@ -195,8 +237,7 @@ android:id="@+id/et_mldsa65_verify" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:inputType="text" /> \ No newline at end of file diff --git a/v2rayng/V2rayNG/app/src/main/res/values-ar/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-ar/strings.xml index 6bd3bc8ea4..a263f6d2c2 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -114,6 +114,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery فشل نسخ الملف، يرجى استخدام مدير الملفات diff --git a/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml index bd8bcf5cce..2ab6c414f9 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -113,6 +113,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery ফাইল কপি ব্যর্থ, অনুগ্রহ করে ফাইল ম্যানেজার ব্যবহার করুন diff --git a/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 97c3bee6fc..36a939fbef 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -113,6 +113,8 @@ وا روء رئڌن پئنا باند (واهڌ) هالت XHTTP XHTTP Extra خام JSON، قالوو: { XHTTPObject } + EchConfigList + EchForceQuery لف گیری فایل ٱنجوم نوابی، ز ی برنومه دؽوۉداری فایل هیاری بگرین diff --git a/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml index ff3cd1f8a2..2d21fe0c28 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -113,6 +113,8 @@ افزایش پهنای باند (واحد) حالت XHTTP خام JSON XHTTP Extra، قالب: { XHTTPObject } + EchConfigList + EchForceQuery کپی فایل انجام نشد، لطفا از برنامه مدیریت فایل استفاده کنید diff --git a/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml index de6ecb9d84..915f6f0496 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -113,6 +113,8 @@ Исходящая пропускная способность (допускаются: k/m/g/t) Режим XHTTP Необработанный JSON XHTTP Extra, формат: { XHTTPObject } + EchConfigList + EchForceQuery Невозможно скопировать файл, используйте файловый менеджер diff --git a/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml index db6d1493cd..68c8a203d2 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -113,6 +113,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery Không thể sao chép tệp tin, hãy dùng trình quản lý tệp! diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 102d508dc4..370e33477c 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -113,6 +113,8 @@ 带宽上行 (支持的单位 k/m/g/t) XHTTP 模式 XHTTP Extra 原始 JSON,格式: { XHTTPObject } + EchConfigList + EchForceQuery 失败, 请使用文件管理器 diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index b603b59d1e..a206a35007 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -113,6 +113,8 @@ 頻寬上行 (支持的單位 k/m/g/t) XHTTP 模式 XHTTP Extra 原始 JSON,格式: { XHTTPObject } + EchConfigList + EchForceQuery 失敗,請使用檔案總管 diff --git a/v2rayng/V2rayNG/app/src/main/res/values/arrays.xml b/v2rayng/V2rayNG/app/src/main/res/values/arrays.xml index 1cdaede417..e4ceda6387 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values/arrays.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values/arrays.xml @@ -215,4 +215,11 @@ 2 + + + none + half + full + + \ No newline at end of file diff --git a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml index 29da7c206f..3022b2150d 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml @@ -114,6 +114,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery File copy failed, please use File Manager diff --git a/v2rayng/badvpn/BUILD-WINDOWS-VisualStudio.md b/v2rayng/badvpn/BUILD-WINDOWS-VisualStudio.md deleted file mode 100644 index 4bbe974a34..0000000000 --- a/v2rayng/badvpn/BUILD-WINDOWS-VisualStudio.md +++ /dev/null @@ -1,103 +0,0 @@ -# Windows build using Visual Studio - -This document describes how to build on Windows using Visual Studio. Note that only -32-bit build has been tested and is described here. - -## Prerequisites - -### Visual Studio - -You need Visual Studio 2017. - -### CMake - -You need CMake, it is best to get the latest version. - -### OpenSSL - -You don't need this if you only need tun2socks or udpgw (but only for the VPN software). - -Install ActivePerl if not already. - -Download and extract the OpenSSL source code. - -Open a Visual Studio x86 native tools command prompt (found under Programs -> Visual -Studio 2017) and enter the OpenSSL source code directory. In this terminal, run the -following commands: - -``` -perl Configure VC-WIN32 no-asm --prefix=%cd%\install-dir -ms\do_ms -nmake -f ms\ntdll.mak install -``` - -### NSS - -You don't need this if you only need tun2socks or udpgw (but only for the VPN software). - -Install MozillaBuild (https://wiki.mozilla.org/MozillaBuild). - -Download and extract the NSS source code that includes NSPR -(`nss-VERSION-with-nspr-VERSION.tar.gz`). - -Copy the file `C:\mozilla-build\start-shell.bat` to -`C:\mozilla-build\start-shell-fixed.bat`, and in the latter file REMOVE the following -lines near the beginning: - -``` -SET INCLUDE= -SET LIB= -IF NOT DEFINED MOZ_NO_RESET_PATH ( - SET PATH=%SystemRoot%\System32;%SystemRoot%;%SystemRoot%\System32\Wbem -) -``` - -Open a Visual Studio x86 native tools command prompt. In this terminal, first run the -following command to enter the mozilla-build bash shell: - -``` -C:\mozilla-build\start-shell-fixed.bat -``` - -Enter the NSS source code directory and run the following commands: - -``` -make -C nss nss_build_all OS_TARGET=WINNT BUILD_OPT=1 -cp -r dist/private/. dist/public/. dist/WINNT*.OBJ/include/ -``` - -## Building BadVPN - -Open a Visual Studio x86 native tools command prompt (found under Programs -> Visual -Studio 2017) and enter the BadVPN source code directory. - -If you needed to build OpenSSL and NSS, then specify the paths to the builds of these -libraries by setting the `CMAKE_PREFIX_PATH` environment variable as shown below; -replace `` and `` with the correct paths. For NSS, -check if the `.OBJ` directory name is correct, if not then adjust that as well. - -``` -set CMAKE_PREFIX_PATH=\install-dir;\dist\WINNT6.2_OPT.OBJ -``` - -Run the commands shown below. If you only need tun2socks and udpgw then also add -the following parameters to first `cmake` command: -`-DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1 -DBUILD_UDPGW=1`. - -``` -mkdir build -cd build -cmake .. -G "Visual Studio 15 2017" -DCMAKE_INSTALL_PREFIX=%cd%\..\install-dir -cmake --build . --config Release --target install -``` - -If you did need OpenSSL and NSS, then copy the needed DLL so that the programs will -be able to find them. You can use the following commands to do this (while still in -the `build` directory): - -``` -copy \install-dir\bin\libeay32.dll ..\install-dir\bin\ -copy \dist\WINNT6.2_OPT.OBJ\lib\*.dll ..\install-dir\bin\ -``` - -The build is now complete and is located in `\install-dir`. diff --git a/v2rayng/badvpn/CMakeLists.txt b/v2rayng/badvpn/CMakeLists.txt deleted file mode 100644 index 6751e13854..0000000000 --- a/v2rayng/badvpn/CMakeLists.txt +++ /dev/null @@ -1,411 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(BADVPN C) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules") - -include(GNUInstallDirs) -include(TestBigEndian) -include(CheckIncludeFiles) -include(CheckSymbolExists) -include(CheckTypeSize) - -option(WITH_PLUGIN_LIBS "Build PIC versions of all libraries for use from plugins" OFF) - -set(BUILD_COMPONENTS) - -macro (build_switch name text default) - if (BUILD_NOTHING_BY_DEFAULT) - option(BUILD_${name} "${text}" OFF) - else () - option(BUILD_${name} "${text}" "${default}") - endif () - list(APPEND BUILD_COMPONENTS "${name}") -endmacro () - -# detect Emscripten -if (CMAKE_C_COMPILER MATCHES "/emcc$") - set(EMSCRIPTEN ON) -else () - set(EMSCRIPTEN OFF) -endif () - -if (EMSCRIPTEN) - set(ON_IF_NOT_EMSCRIPTEN OFF) -else () - set(ON_IF_NOT_EMSCRIPTEN ON) -endif() - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT EMSCRIPTEN) - set(ON_IF_LINUX ON) -else () - set(ON_IF_LINUX OFF) -endif() - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR EMSCRIPTEN) - set(ON_IF_LINUX_OR_EMSCRIPTEN ON) -else () - set(ON_IF_LINUX_OR_EMSCRIPTEN OFF) -endif () - -# define build defaults -build_switch(EXAMPLES "build example programs" ON) -build_switch(TESTS "build some other example programs" ON) -build_switch(SERVER "build badvpn-server" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(CLIENT "build badvpn-client" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(FLOODER "build badvpn-flooder" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(TUN2SOCKS "build badvpn-tun2socks" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(UDPGW "build badvpn-udpgw" ${ON_IF_NOT_EMSCRIPTEN}) -build_switch(NCD "build badvpn-ncd" ${ON_IF_LINUX_OR_EMSCRIPTEN}) -build_switch(DOSTEST "build dostest-server and dostest-attacker" OFF) - -if (BUILD_NCD AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")) - message(FATAL_ERROR "NCD is only available on Linux") -endif () - -if (BUILD_CLIENT OR BUILD_SERVER) - find_package(OpenSSL REQUIRED) - set(LIBCRYPTO_INCLUDE_DIRS "${OpenSSL_INCLUDE_DIRS}") - set(LIBCRYPTO_LIBRARY_DIRS "${OpenSSL_LIBRARY_DIRS}") - set(LIBCRYPTO_LIBRARIES "${OpenSSL_LIBRARIES}") -endif () - -if (BUILD_SERVER OR BUILD_CLIENT OR BUILD_FLOODER) - find_package(NSPR REQUIRED) - find_package(NSS REQUIRED) -endif () - -# choose reactor -if (DEFINED BREACTOR_BACKEND) - if (NOT (BREACTOR_BACKEND STREQUAL "badvpn" OR BREACTOR_BACKEND STREQUAL "glib")) - message(FATAL_ERROR "unknown reactor backend specified") - endif () -else () - if (EMSCRIPTEN) - set(BREACTOR_BACKEND "emscripten") - else () - set(BREACTOR_BACKEND "badvpn") - endif () -endif () - -if (BREACTOR_BACKEND STREQUAL "badvpn") - add_definitions(-DBADVPN_BREACTOR_BADVPN) -elseif (BREACTOR_BACKEND STREQUAL "glib") - if (NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")) - message(FATAL_ERROR "GLib reactor backend is only available on Linux") - endif () - find_package(GLIB2 REQUIRED) - add_definitions(-DBADVPN_BREACTOR_GLIB) -elseif (BREACTOR_BACKEND STREQUAL "emscripten") - add_definitions(-DBADVPN_BREACTOR_EMSCRIPTEN) -endif () - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${LIBCRYPTO_INCLUDE_DIRS} - ${NSPR_INCLUDE_DIRS} - ${NSS_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIR} - lwip/custom - lwip/src/include - lwip/src/include/ipv4 - lwip/src/include/ipv6 -) - -link_directories( - ${LIBCRYPTO_LIBRARY_DIRS} - ${NSPR_LIBRARY_DIRS} - ${NSS_LIBRARY_DIRS} -) - -test_big_endian(BIG_ENDIAN) - -check_type_size(int INT_SIZE) -if (NOT (INT_SIZE GREATER "3")) - message(FATAL_ERROR "int must be at least 32 bits") -endif () - -check_type_size(size_t SIZE_SIZE) -if (NOT (SIZE_SIZE GREATER INT_SIZE OR SIZE_SIZE EQUAL INT_SIZE)) - message(FATAL_ERROR "size_t must be greater or equal than int") -endif () - -if (MSVC) - add_definitions(-D_CRT_SECURE_NO_WARNINGS /wd4065 /wd4018 /wd4533 /wd4244 /wd4102 /wd4098 /wd4267 /wd4116) - add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS) -else () - add_definitions(-std=gnu99 -Wall -Wno-unused-value -Wno-parentheses -Wno-switch -Wredundant-decls -Wshadow) - - if (NOT CMAKE_C_COMPILER_ID STREQUAL "PathScale") - add_definitions(-Werror=implicit-function-declaration -Wno-switch-enum -Wno-unused-function - -Wstrict-aliasing) - endif () - - if (CMAKE_C_COMPILER_ID MATCHES "^Clang") - add_definitions(-Wno-initializer-overrides -Wno-tautological-constant-out-of-range-compare) - endif () -endif () - -# platform-specific stuff -if (WIN32) - add_definitions(-DBADVPN_USE_WINAPI -D_WIN32_WINNT=0x600 -DWIN32_LEAN_AND_MEAN) - add_definitions(-DBADVPN_THREAD_SAFE=0) - - set(CMAKE_REQUIRED_DEFINITIONS "-D_WIN32_WINNT=0x600") - check_symbol_exists(WSAID_WSASENDMSG "winsock2.h;mswsock.h" HAVE_MSW_1) - check_symbol_exists(WSAID_WSARECVMSG "winsock2.h;mswsock.h" HAVE_MSW_2) - check_symbol_exists(WSAID_ACCEPTEX "winsock2.h;mswsock.h" HAVE_MSW_3) - check_symbol_exists(WSAID_GETACCEPTEXSOCKADDRS "winsock2.h;mswsock.h" HAVE_MSW_4) - check_symbol_exists(WSAID_CONNECTEX "winsock2.h;mswsock.h" HAVE_MSW_5) - set(CMAKE_REQUIRED_DEFINITIONS "") - if (NOT (HAVE_MSW_1 AND HAVE_MSW_2 AND HAVE_MSW_3 AND HAVE_MSW_4 AND HAVE_MSW_5)) - add_definitions(-DBADVPN_USE_SHIPPED_MSWSOCK) - check_type_size(WSAMSG HAVE_WSAMSG) - if (NOT HAVE_WSAMSG) - add_definitions(-DBADVPN_SHIPPED_MSWSOCK_DECLARE_WSAMSG) - endif () - endif () -else () - set(BADVPN_THREADWORK_USE_PTHREAD 1) - add_definitions(-DBADVPN_THREADWORK_USE_PTHREAD) - add_definitions(-DBADVPN_THREAD_SAFE=1) - - link_libraries(rt pthread) - - if (EMSCRIPTEN) - add_definitions(-DBADVPN_EMSCRIPTEN) - add_definitions(-DBADVPN_NO_PROCESS -DBADVPN_NO_UDEV -DBADVPN_NO_RANDOM) - elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_definitions(-DBADVPN_LINUX) - - check_include_files(sys/signalfd.h HAVE_SYS_SIGNALFD_H) - if (HAVE_SYS_SIGNALFD_H) - add_definitions(-DBADVPN_USE_SIGNALFD) - else () - add_definitions(-DBADVPN_USE_SELFPIPE) - endif () - - check_include_files(sys/epoll.h HAVE_SYS_EPOLL_H) - if (HAVE_SYS_EPOLL_H) - add_definitions(-DBADVPN_USE_EPOLL) - else () - add_definitions(-DBADVPN_USE_POLL) - endif () - - check_include_files(linux/rfkill.h HAVE_LINUX_RFKILL_H) - if (HAVE_LINUX_RFKILL_H) - add_definitions(-DBADVPN_USE_LINUX_RFKILL) - set(BADVPN_USE_LINUX_RFKILL 1) - endif () - - check_include_files(linux/input.h HAVE_LINUX_INPUT_H) - if (HAVE_LINUX_INPUT_H) - add_definitions(-DBADVPN_USE_LINUX_INPUT) - set(BADVPN_USE_LINUX_INPUT 1) - endif () - - check_include_files(sys/inotify.h HAVE_SYS_INOTIFY_H) - if (HAVE_SYS_INOTIFY_H) - add_definitions(-DBADVPN_USE_INOTIFY) - set(BADVPN_USE_INOTIFY 1) - endif () - elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - add_definitions(-DBADVPN_FREEBSD) - - check_symbol_exists(kqueue "sys/types.h;sys/event.h;sys/time.h" HAVE_KQUEUE) - if (NOT HAVE_KQUEUE) - message(FATAL_ERROR "kqueue is required") - endif () - add_definitions(-DBADVPN_USE_KEVENT) - endif () - - if (NOT DEFINED BADVPN_WITHOUT_CRYPTODEV) - check_include_files(crypto/cryptodev.h HAVE_CRYPTO_CRYPTODEV_H) - if (HAVE_CRYPTO_CRYPTODEV_H) - add_definitions(-DBADVPN_USE_CRYPTODEV) - elseif (DEFINED BADVPN_WITH_CRYPTODEV) - message(FATAL_ERROR "crypto/cryptodev.h not found") - endif () - endif () -endif () - -# check for syslog -check_include_files(syslog.h HAVE_SYSLOG_H) -if (HAVE_SYSLOG_H) - add_definitions(-DBADVPN_USE_SYSLOG) -endif () - -# add preprocessor definitions -if (BIG_ENDIAN) - add_definitions(-DBADVPN_BIG_ENDIAN) -else () - add_definitions(-DBADVPN_LITTLE_ENDIAN) -endif () - -# install man pages -install( - FILES badvpn.7 - DESTINATION ${CMAKE_INSTALL_MANDIR}/man7 -) - -# reset variables indicating whether we're building various libraries, -# and set them in the respective CMakeLists files. This is used to disable -# building examples and tests which require libraries that are not available. -set(BUILDING_SECURITY 0) -set(BUILDING_DHCPCLIENT 0) -set(BUILDING_ARPPROBE 0) -set(BUILDING_BKIO 0) -set(BUILDING_PREDICATE 0) -set(BUILDING_UDEVMONITOR 0) -set(BUILDING_THREADWORK 0) -set(BUILDING_RANDOM 0) - -# Used to register an internal library. -# This will also add a library with the -plugin suffix, which is useful -# for use by dynamic libraries (e.g. NCD modules): -# - If BUILD_SHARED_LIBS is off (default), the libraries ${LIB_NAME} and ${LIB_NAME}-plugin -# are built separately. Both are static libraries but the -plugin variant is build as position -# independent code, so it can be (statically) linked into dynamic libraries. -# - If BUILD_SHARED_LIBS is on, only ${LIB_NAME} is built, as a shared library. -# The ${LIB_NAME}-plugin target is set up as an alias to ${LIB_NAME}. -function(badvpn_add_library LIB_NAME LINK_BADVPN_LIBS LINK_SYS_LIBS LIB_SOURCES) - set(BADVPN_LIBS_EXEC) - set(BADVPN_LIBS_PLUGIN) - foreach(LIB ${LINK_BADVPN_LIBS}) - list(APPEND BADVPN_LIBS_EXEC "${LIB}") - list(APPEND BADVPN_LIBS_PLUGIN "${LIB}-plugin") - endforeach() - - add_library("${LIB_NAME}" ${LIB_SOURCES}) - target_link_libraries("${LIB_NAME}" ${BADVPN_LIBS_EXEC} ${LINK_SYS_LIBS}) - set_target_properties("${LIB_NAME}" PROPERTIES OUTPUT_NAME "badvpn-${LIB_NAME}") - - if(WITH_PLUGIN_LIBS) - if(BUILD_SHARED_LIBS) - add_library("${LIB_NAME}-plugin" ALIAS "${LIB_NAME}") - else() - add_library("${LIB_NAME}-plugin" STATIC ${LIB_SOURCES}) - target_link_libraries("${LIB_NAME}-plugin" ${BADVPN_LIBS_PLUGIN} ${LINK_SYS_LIBS}) - set_target_properties("${LIB_NAME}-plugin" PROPERTIES OUTPUT_NAME "badvpn-${LIB_NAME}-plugin") - set_target_properties("${LIB_NAME}-plugin" PROPERTIES POSITION_INDEPENDENT_CODE YES) - set_target_properties("${LIB_NAME}-plugin" PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -DBADVPN_PLUGIN") - endif() - endif() -endfunction() - -# internal libraries -add_subdirectory(base) -add_subdirectory(system) -add_subdirectory(flow) -add_subdirectory(flowextra) -if (OpenSSL_FOUND) - set(BUILDING_SECURITY 1) - add_subdirectory(security) -endif () -if (NSS_FOUND) - add_subdirectory(nspr_support) -endif () -if (BUILD_CLIENT OR BUILDING_SECURITY) - set(BUILDING_THREADWORK 1) - add_subdirectory(threadwork) -endif () -if (BUILD_CLIENT OR BUILD_TUN2SOCKS) - add_subdirectory(tuntap) -endif () -if (BUILD_SERVER) - set(BUILDING_PREDICATE 1) - add_subdirectory(predicate) -endif () -if (BUILD_CLIENT OR BUILD_FLOODER) - add_subdirectory(server_connection) -endif () -if (BUILD_NCD AND NOT EMSCRIPTEN) - set(BUILDING_DHCPCLIENT 1) - set(BUILDING_ARPPROBE 1) - set(BUILDING_UDEVMONITOR 1) - set(BUILDING_RANDOM 1) - add_subdirectory(stringmap) - add_subdirectory(udevmonitor) - add_subdirectory(dhcpclient) - add_subdirectory(arpprobe) - add_subdirectory(random) -endif () -if (BUILD_TUN2SOCKS) - add_subdirectory(socksclient) - add_subdirectory(udpgw_client) - add_subdirectory(socks_udp_client) - add_subdirectory(lwip) -endif () - -# example programs -if (BUILD_EXAMPLES) - add_subdirectory(examples) -endif () - -# tests -if (BUILD_TESTS) - add_subdirectory(tests) -endif () - -# server -if (BUILD_SERVER) - add_subdirectory(server) -endif () - -# client -if (BUILD_CLIENT) - add_subdirectory(client) -endif () - -# flooder -if (BUILD_FLOODER) - add_subdirectory(flooder) -endif () - -# tun2socks -if (BUILD_TUN2SOCKS) - add_subdirectory(tun2socks) -endif () - -# udpgw -if (BUILD_UDPGW) - add_subdirectory(udpgw) -endif () - -# ncd -if (BUILD_NCD) - add_subdirectory(ncd) - if (NOT EMSCRIPTEN) - add_subdirectory(ncd-request) - endif () -endif () - -# dostest -if (BUILD_DOSTEST) - add_subdirectory(dostest) -endif () - -message(STATUS "Building components:") - -# print what we're building and what not -foreach (name ${BUILD_COMPONENTS}) - # to lower name - string(TOLOWER "${name}" name_withspaces) - - # append spaces to name - #while (TRUE) - # string(LENGTH "${name_withspaces}" length) - # if (NOT (length LESS 12)) - # break() - # endif () - # set(name_withspaces "${name_withspaces} ") - #endwhile () - - # determine if we're building - if (BUILD_${name}) - set(building "yes") - else () - set(building "no") - endif () - - message(STATUS " ${name_withspaces} ${building}") -endforeach () diff --git a/v2rayng/badvpn/COPYING b/v2rayng/badvpn/COPYING deleted file mode 100644 index f973347242..0000000000 --- a/v2rayng/badvpn/COPYING +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2009, Ambroz Bizjak -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v2rayng/badvpn/ChangeLog b/v2rayng/badvpn/ChangeLog deleted file mode 100644 index f730a62cf1..0000000000 --- a/v2rayng/badvpn/ChangeLog +++ /dev/null @@ -1,292 +0,0 @@ -Version 1.999.130: - -- Fix TUN/TAP operation with Linux kernel 3.19. See: https://bugzilla.kernel.org/show_bug.cgi?id=96381 - -- ncd: modules/daemon: Implement custom retry time. - -- ncd: modules/daemon: Fix the "daemon crashed" log message to include module context. - -- ncd: modules: arithmetic: Don't fail immediately on arithmetic errors, expose their occurrence. - -- ncd: Add clock_get_ms function. - -- ncd: Implement a simple checksum function as used in the Sphereo blue tooth protocol. - -- ncd: socket: Implement support for opening serial ports. - -- ncd: Implement struct_decode. - -- ncd: Implement struct_encode function. - -- ncd: sys.evdev: Provide event code strings for EV_SYN if available. - -- ncd: modules: blocker: Implement initial_state argument. - -- ncd: modules: blocker: Expose the up-state as a variable. - -- ncd: Implement Do-Interrupt. - -- ncd: Implement Do. - -- ncd: Implement lazy evaluation in If clause. - -- ncd: Implement ifel function to support future lazy If. - -- ncd: Optimize value::append(). - -- ncd: Implement backtrack_point::rgo. - -- ncd: modules: explode: Pass through external strings (avoid copy). - -- ncd: modules: explode: Implement compiling search strings. - -- ncd: modules: parse: Implement parse_hex_number. - -- ncd: Implement caret syntax sugar. ^a.b.c = {"a", "b", "c"} - -- ncd: Fix bugs with bad expectations of null-terminated strings. - -- ncd: Implement object reference infrastructure and objref module. - -- ncd: Remove ComposedString type along with the buffer module. - -- ncd: Implement Block syntax as syntax-sugar around inline_code(). - -- ncd: modules: call: Implement inline_code calls. - -- ncd: modules: call: Fix bug in call_with_caller_target deinit. - -- ncd: modules: socket: close: Fix completion order vs closing. - -- ncd: Fix a bug that caused a bad assertion failure in file_write(). - -- ncd: modules: socket: add read() eof variable - -- ncd: modules: socket: Implement _caller in client process. - -- ncd: Add --signal-exit-code option. - -- ncd: Implement syntax sugar @something = "something". - -- ncd: Fix crash with num_multiply(..., "0"). - -- ncd: Infrastructure for built-in functions and implementation of many such functions. - -- ncd: Fix bad assertion regarding map values. - -Version 1.999.129: - -- ncd: modules: file_open: Fix typo in assertion. - -- server: Fix bug forgetting to call BSSLConnection_ReleaseBuffers(). Unless threads are enabled, this is an assert failure if NDEBUG is not defined an a non-issue otherwise. - -- ncd: Look for various programs in PATH instead of hardcoded paths. - -- Add compile-udpgw.sh. - -- ncd: modules: net_dns: Implement net.dns.resolvconf() forspecification of arbitrary resolv.conf lines - -Version 1.999.128: - -- tun2socks: add option --append-source-to-username to give the SOCKS server the source IP of the connection - -- tun2socks: IPv6 support, and updated to newer version of lwIP - -- tun2socks: fix some bugs/crashes - -- tun2socks, udpgw: transparent DNS forwarding, though no Windows support on udpgw side (contributed by Kerem Hadimli) - -- NCD: preliminary support for dynamically loading commands - -Version 1.999.127: - -- client, server: implement experimental support for performing SSL operations in worker threads. Currently it's rather inefficient. - -- NCD: modules: value: implement value::append() for appending to a list - -- NCD: modules: net_iptables: add single-argument form of append and insert commands, allowing for generic use - -- NCD: modules: net_iptables: implement net.iptables.insert() and net.ebtables.insert() - -- NCD: modules: sys_start_process: implement options, including username, term_on_deinit and deinit_kill_time - -- NCD: modules: sys_request_server: implement _caller in request handler - -- NCD: modules: add getenv() - -- NCD: modules: daemon: implement options, including username option - -- NCD: modules: runonce: add new options format with a map, implement username option - -- NCD: modules: add buffer(), which exposes a buffer with efficient appending and removing from the beginning. - -- NCD: add a new internal string representation called ComposedString. This allows modules to expose the concatenation of multiple memroy buffers as a single string value, efficiently. - -- fix many, hopefully all, strict aliasing violations. In particular, this fixes a bug where the DHCP client integrated into NCD won't work correctly, subject to optimization flags. - -- NCD: modules: sleep: interpret empty string as no sleeping, add sleep(ms_start) with one argument - -- NCD: modules: add log(), log_r() and log_fr() commands for logging via the BLog system - -Version 1.999.126: - -- NCD: modules: sleep: interpret empty string time as no sleeping, add sleep(ms_start) with one argument - -- NCD: modules: add log module for message logging using the BLog system - -- NCD: implement the "include" and "include_guard" directives, which allow separating reusable code into files - -- NCD: modules: call2: implement call_with_caller_target(), which makes it easier to write reusable code that calls back user-provided code - -- NCD: modules: call2: remove call2_if(), call2_ifelse(), embcall2(), embcall2_if(), embcall2_ifelse() - -- NCD: modules: add sys.start_process(), which implements starting and controlling external processes and reading/writing their stdout/stdin - -- tun2socks: implement SOCKS password authentication - -- NCD: track the depth of values and limit the maximum depth. This avoids stack overflow with very deeply nested values. - -- NCD: modules: add substr() - -- NCD: process_manager: add 2-argument start() method which doesn't take a process identifier - -- NCD: process_manager: allow process identifiers to be any value not just strings - -- NCD: multidepend, depend_scope: fix immediate effect order when a depend finishes backtracking - -- NCD: add depend_scope module to do exactly what the multidepend module does, but with separate non-global dependency name scopes - -- NCD: multidepend: allow dependency names to be any value not just strings - -- NCD: implement value::insert(what) for appending to a list - -- NCD: change the format of addresses in sys.request_server() and sys.request_client() to be the same as in the socket module - -- NCD: add socket module (sys.connect() and sys.listen()) - -- NCD: fix bug where duplicate template/process names would not be detected and weird behaviour would result - -- NCD: add backtrack_point() for simple backtracking - -- NCD: add file_open() for more complete file I/O - -- NCD: implement parse_ipv6_addr() and parse_ipv6_cidr_addr() - -- NCD: port to Emscripten/Javascript, for the in-browser demo - -- NCD: many performance and memory usage improvements - -- NCD: add assert_false() - -- NCD: don't link to OpenSSL to for random number generator. Use /dev/urandom instead to generate XIDs for DHCP. - -- NCD: deprecate ip_in_network() and instead add net.ipv{4,6}.addr_in_network(), net.ipv{4,6}.ifnot_addr_in_network() - -- NCD: implement some IPv6 modules: net.ipv6.addr(), net.ipv6.route() - -- NCD: support CIDR style addr/prefix addresses in various modules - -- NCD: recognize Elif and Else with capital first letter to be consistent with other reserved keywords - -Version 1.999.123: - -- NCD: performance improvements related to finding modules for statements - -- NCD: performance improvements related to resolving object names - -- NCD: performance improvements related to instantiating statement arguments - -- NCD: add value::replace_this() and value::replace_this_undo() - -- NCD: add value::reset() - -- NCD: add value::replace() and value::replace_undo() - -- Port to compile with MSVC for Windows. - -- NCD: add Foreach clause - -- NCD: implement _caller in spawn(), add spawn::join() - -- NCD: add explode() - -- NCD: add hard_reboot() and hard_poweroff() - -- NCD: add file_stat() and file_lstat() - -- NCD: fix regex_replace() semantics. It was very broken because it did a complete replacement pass for every regex on the list, so it would match parts that have already been replaced, producing unexpected results. - -- NCD: small performance improvement - -Version 1.999.121: - -- NCD: improve error handling semantics; see http://code.google.com/p/badvpn/source/detail?r=1376 - -- NCD: fix assertion failure in sys.evdev() if a device error occurs (e.g. device unplugged) while an event is being processed. Similar fix in some other modules, but these may not be reproducable. - -- NCD: some more performance improvements - -- NCD: some performance improvements (~30% faster interpretation of cpu-bound code) - -- NCD: implemented If..elif..else clause. - -- NCD: net.backend.wpa_supplicant: fix to work with wpa_supplicant>=1.0 - -Version 1.999.115: - -- NCD: Many improvements; new statements, including call(), alias(), foreach(), choose(). - -Version 1.999.113: - -- NCD: when starting child processes, make sure that file descriptors for standard - streams are always open in the child, by opening /dev/null if they are not. - -- Improve build system to allow selective building of components. - By default, everything is built, unless -DBUILD_NOTHING_BY_DEFAULT=1 is given. - Individual components can then be enabled or disabled using -DBUILD_COMPONENT=1 - and -DBUILD_COMPONENT=0. - -- When starting any BadVPN program, make sure that file descriptors for standard - streams are always open in the child, by opening /dev/null if they are not. - -- NCD: net.backend.wpa_supplicant(): add 'bssid' and 'ssid' variables to allow - determining what wireless network wpa_supplicant connected to. - -- NCD: net.backend.wpa_supplicant(): do not require the user to start wpa_supplicant via - stdbuf, but do it automatically. - -Version 1.999.111: - -- Improved protocol such that peers can use SSL when comminicating via the server. This - improves security, as compromising the server will not allow the attacker to see secret - data shared by peers (in particular, encryption keys and OTP seeds when in UDP mode). - - Compatibility is preserved if an only if the following conditions are met: - - The server is using the latest version. - - If the network is using SSL, all clients using the new version are using the - "--allow-peer-talk-without-ssl" command line option. - - Be aware, however, that using the "--allow-peer-talk-without-ssl" option negates the - security benefits of the new SSL support - not only between pairs of peers where one - peer is using the old version, but also between pairs where both peers are capable - of SSL. This is because the server can re-initialize the pair, telling them not to use - SSL. - -Version 1.999.107: - -- Added Windows IOCP support, removing the limitation on ~64 connections. This is important - for tun2socks, which may have to handle several hundred connections. - -Version 1.999.105.2: - -- Fixed an assertion failure in tun2socks related to sending data to SOCKS. - -Version 1.999.101.3: - -- Fixed UDP transport on Windows 7 which didn't work (was only tested on XP). - -Version 1.999.101: - -- Fixed a protocol issue present in versions <=1.999.100.3. Compatibility is preserved in - case of a new server and old clients, but it is not possible to connect to an old server - with a new client. diff --git a/v2rayng/badvpn/README.md b/v2rayng/badvpn/README.md deleted file mode 100644 index d499667bb8..0000000000 --- a/v2rayng/badvpn/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# BadVPN - -## Introduction - -In this project I host some of my open-source networking software. -All of the software is written in C and utilizes a custom-developed framework for event-driven programming. -The extensive code sharing is the reason all the software is packaged together. -However, it is possible to compile only the required components to avoid extra dependencies. - -### NCD programming language - -NCD (Network Configuration Daemon) is a daemon and programming/scripting language for configuration of network interfaces and other aspects of the operating system. -It implements various functionalities as built-in modules, which may be used from an NCD program wherever and for whatever purpose the user needs them. -This modularity makes NCD extremely flexible and extensible. It does a very good job with hotplugging in various forms, like USB network interfaces and link detection for wired devices. -New features can be added by implementing statements as C-language modules using a straightforward interface. - -### Tun2socks network-layer proxifier - -The tun2socks program "socksifes" TCP connections at the network layer. -It implements a TUN device which accepts all incoming TCP connections (regardless of destination IP), and forwards the connections through a SOCKS server. -This allows you to forward all connections through SOCKS, without any need for application support. -It can be used, for example, to forward connections through a remote SSH server. - -### Peer-to-peer VPN - -The VPN part of this project implements a Layer 2 (Ethernet) network between the peers (VPN nodes). -The peers connect to a central server which acts as a communication proxy allowing the peers to establish direct connections between each other (data connections). -These connections are used for transferring network data (Ethernet frames), and can be secured with a multitude of mechanisms. Notable features are: - -- UDP and TCP transport -- Converges very quickly after a new peer joins -- IGMP snooping to deliver multicasts efficiently (e.g. for IPTV) -- Double SSL: if SSL is enabled, not only do peers connect to the server with SSL, but they use an additional layer of SSL when exchanging messages through the server -- Features related to the NAT problem: - - Can work with multiple layers of NAT (needs configuration) - - Local peers inside a NAT can communicate directly - - Relaying as a fallback (needs configuration) - -## Requirements - -NCD only works on Linux. Tun2socks works on Linux and Windows. The P2P VPN works on Linux, Windows and FreeBSD (not tested often). - -## Installation - -The build system is based on CMake. On Linux, the following commands can be used to -build: - -``` -cd -mkdir build -cd build -cmake .. -DCMAKE_INSTALL_PREFIX= -make install -``` - -If you only need tun2socks or udpgw, then add the following arguments to the `cmake` -command: `-DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1 -DBUILD_UDPGW=1`. -Otherwise (if you want the VPN software), you will first need to install the OpenSSL -and NSS libraries and make sure that CMake can find them. - -Windows builds are not provided. You can build from source code using Visual Studio by -following the instructions in the file `BUILD-WINDOWS-VisualStudio.md`. - -## License - -The BSD 3-clause license as shown below applies to most of the code. - -``` -Copyright (c) 2009, Ambroz Bizjak -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of the author nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -``` - -List of third-party code included in the source: -- lwIP - A Lightweight TCP/IP stack. License: `lwip/COPYING` diff --git a/v2rayng/badvpn/arpprobe/BArpProbe.c b/v2rayng/badvpn/arpprobe/BArpProbe.c deleted file mode 100644 index 2e6feb4fd6..0000000000 --- a/v2rayng/badvpn/arpprobe/BArpProbe.c +++ /dev/null @@ -1,359 +0,0 @@ -/** - * @file BArpProbe.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "BArpProbe.h" - -#include - -#define STATE_INITIAL 1 -#define STATE_NOEXIST 2 -#define STATE_EXIST 3 -#define STATE_EXIST_PANIC 4 - -static void dgram_handler (BArpProbe *o, int event) -{ - DebugObject_Access(&o->d_obj); - - BLog(BLOG_ERROR, "packet socket error"); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BARPPROBE_EVENT_ERROR)); - return; -} - -static void send_request (BArpProbe *o) -{ - if (o->send_sending) { - BLog(BLOG_ERROR, "cannot send packet while another packet is being sent!"); - return; - } - - // build packet - struct arp_packet *arp = &o->send_packet; - arp->hardware_type = hton16(ARP_HARDWARE_TYPE_ETHERNET); - arp->protocol_type = hton16(ETHERTYPE_IPV4); - arp->hardware_size = hton8(6); - arp->protocol_size = hton8(4); - arp->opcode = hton16(ARP_OPCODE_REQUEST); - memcpy(arp->sender_mac, o->if_mac, 6); - arp->sender_ip = hton32(0); - memset(arp->target_mac, 0, sizeof(arp->target_mac)); - arp->target_ip = o->addr; - - // send packet - PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)&o->send_packet, sizeof(o->send_packet)); - - // set sending - o->send_sending = 1; -} - -static void send_if_handler_done (BArpProbe *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->send_sending) - - // set not sending - o->send_sending = 0; -} - -static void recv_if_handler_done (BArpProbe *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= 0) - ASSERT(data_len <= sizeof(struct arp_packet)) - - // receive next packet - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)&o->recv_packet); - - if (data_len != sizeof(struct arp_packet)) { - BLog(BLOG_WARNING, "receive: wrong size"); - return; - } - - struct arp_packet *arp = &o->recv_packet; - - if (ntoh16(arp->hardware_type) != ARP_HARDWARE_TYPE_ETHERNET) { - BLog(BLOG_WARNING, "receive: wrong hardware type"); - return; - } - - if (ntoh16(arp->protocol_type) != ETHERTYPE_IPV4) { - BLog(BLOG_WARNING, "receive: wrong protocol type"); - return; - } - - if (ntoh8(arp->hardware_size) != 6) { - BLog(BLOG_WARNING, "receive: wrong hardware size"); - return; - } - - if (ntoh8(arp->protocol_size) != 4) { - BLog(BLOG_WARNING, "receive: wrong protocol size"); - return; - } - - if (ntoh16(arp->opcode) != ARP_OPCODE_REPLY) { - return; - } - - if (arp->sender_ip != o->addr) { - return; - } - - int old_state = o->state; - - // set minus one missed - o->num_missed = -1; - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITSEND); - - // set state exist - o->state = STATE_EXIST; - - // report exist if needed - if (old_state == STATE_INITIAL || old_state == STATE_NOEXIST) { - o->handler(o->user, BARPPROBE_EVENT_EXIST); - return; - } -} - -static void timer_handler (BArpProbe *o) -{ - DebugObject_Access(&o->d_obj); - - // send request - send_request(o); - - switch (o->state) { - case STATE_INITIAL: { - ASSERT(o->num_missed >= 0) - ASSERT(o->num_missed < BARPPROBE_INITIAL_NUM_ATTEMPTS) - - // increment missed - o->num_missed++; - - // all attempts failed? - if (o->num_missed == BARPPROBE_INITIAL_NUM_ATTEMPTS) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - - // set state noexist - o->state = STATE_NOEXIST; - - // report noexist - o->handler(o->user, BARPPROBE_EVENT_NOEXIST); - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_INITIAL_WAITRECV); - } break; - - case STATE_NOEXIST: { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - } break; - - case STATE_EXIST: { - ASSERT(o->num_missed >= -1) - ASSERT(o->num_missed < BARPPROBE_EXIST_NUM_NOREPLY) - - // increment missed - o->num_missed++; - - // all missed? - if (o->num_missed == BARPPROBE_EXIST_NUM_NOREPLY) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV); - - // set zero missed - o->num_missed = 0; - - // set state panic - o->state = STATE_EXIST_PANIC; - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_WAITRECV); - } break; - - case STATE_EXIST_PANIC: { - ASSERT(o->num_missed >= 0) - ASSERT(o->num_missed < BARPPROBE_EXIST_PANIC_NUM_NOREPLY) - - // increment missed - o->num_missed++; - - // all missed? - if (o->num_missed == BARPPROBE_EXIST_PANIC_NUM_NOREPLY) { - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_NOEXIST_WAITRECV); - - // set state panic - o->state = STATE_NOEXIST; - - // report noexist - o->handler(o->user, BARPPROBE_EVENT_NOEXIST); - return; - } - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_EXIST_PANIC_WAITRECV); - } break; - } -} - -int BArpProbe_Init (BArpProbe *o, const char *ifname, uint32_t addr, BReactor *reactor, void *user, BArpProbe_handler handler) -{ - ASSERT(ifname) - ASSERT(handler) - - // init arguments - o->addr = addr; - o->reactor = reactor; - o->user = user; - o->handler = handler; - - // get interface information - int if_mtu; - int if_index; - if (!badvpn_get_iface_info(ifname, o->if_mac, &if_mtu, &if_index)) { - BLog(BLOG_ERROR, "failed to get interface information"); - goto fail0; - } - - uint8_t *if_mac = o->if_mac; - BLog(BLOG_INFO, "if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d", - if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index); - - // check MTU - if (if_mtu < sizeof(struct arp_packet)) { - BLog(BLOG_ERROR, "MTU is too small for ARP !?!"); - goto fail0; - } - - // init dgram - if (!BDatagram_Init(&o->dgram, BADDR_TYPE_PACKET, o->reactor, o, (BDatagram_handler)dgram_handler)) { - BLog(BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // bind dgram - BAddr bind_addr; - BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_ARP), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac); - if (!BDatagram_Bind(&o->dgram, bind_addr)) { - BLog(BLOG_ERROR, "BDatagram_Bind failed"); - goto fail1; - } - - // set dgram send addresses - BAddr dest_addr; - uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BAddr_InitPacket(&dest_addr, hton16(ETHERTYPE_ARP), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_BROADCAST, broadcast_mac); - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, dest_addr, local_addr); - - // init send interface - BDatagram_SendAsync_Init(&o->dgram, sizeof(struct arp_packet)); - o->send_if = BDatagram_SendAsync_GetIf(&o->dgram); - PacketPassInterface_Sender_Init(o->send_if, (PacketPassInterface_handler_done)send_if_handler_done, o); - - // set not sending - o->send_sending = 0; - - // init recv interface - BDatagram_RecvAsync_Init(&o->dgram, sizeof(struct arp_packet)); - o->recv_if = BDatagram_RecvAsync_GetIf(&o->dgram); - PacketRecvInterface_Receiver_Init(o->recv_if, (PacketRecvInterface_handler_done)recv_if_handler_done, o); - - // init timer - BTimer_Init(&o->timer, 0, (BTimer_handler)timer_handler, o); - - // receive first packet - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)&o->recv_packet); - - // send request - send_request(o); - - // set timer - BReactor_SetTimerAfter(o->reactor, &o->timer, BARPPROBE_INITIAL_WAITRECV); - - // set zero missed - o->num_missed = 0; - - // set state initial - o->state = STATE_INITIAL; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void BArpProbe_Free (BArpProbe *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free timer - BReactor_RemoveTimer(o->reactor, &o->timer); - - // free recv interface - BDatagram_RecvAsync_Free(&o->dgram); - - // free send interface - BDatagram_SendAsync_Free(&o->dgram); - - // free dgram - BDatagram_Free(&o->dgram); -} diff --git a/v2rayng/badvpn/arpprobe/BArpProbe.h b/v2rayng/badvpn/arpprobe/BArpProbe.h deleted file mode 100644 index 2ec3ffae92..0000000000 --- a/v2rayng/badvpn/arpprobe/BArpProbe.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file BArpProbe.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BARPPROBE_H -#define BADVPN_BARPPROBE_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define BARPPROBE_INITIAL_WAITRECV 1000 -#define BARPPROBE_INITIAL_NUM_ATTEMPTS 6 -#define BARPPROBE_NOEXIST_WAITRECV 15000 -#define BARPPROBE_EXIST_WAITSEND 15000 -#define BARPPROBE_EXIST_WAITRECV 10000 -#define BARPPROBE_EXIST_NUM_NOREPLY 2 -#define BARPPROBE_EXIST_PANIC_WAITRECV 1000 -#define BARPPROBE_EXIST_PANIC_NUM_NOREPLY 6 - -#define BARPPROBE_EVENT_EXIST 1 -#define BARPPROBE_EVENT_NOEXIST 2 -#define BARPPROBE_EVENT_ERROR 3 - -typedef void (*BArpProbe_handler) (void *user, int event); - -typedef struct { - uint32_t addr; - BReactor *reactor; - void *user; - BArpProbe_handler handler; - BDatagram dgram; - uint8_t if_mac[6]; - PacketPassInterface *send_if; - int send_sending; - struct arp_packet send_packet; - PacketRecvInterface *recv_if; - struct arp_packet recv_packet; - BTimer timer; - int state; - int num_missed; - DebugError d_err; - DebugObject d_obj; -} BArpProbe; - -int BArpProbe_Init (BArpProbe *o, const char *ifname, uint32_t addr, BReactor *reactor, void *user, BArpProbe_handler handler) WARN_UNUSED; -void BArpProbe_Free (BArpProbe *o); - -#endif diff --git a/v2rayng/badvpn/arpprobe/CMakeLists.txt b/v2rayng/badvpn/arpprobe/CMakeLists.txt deleted file mode 100644 index a090f1078c..0000000000 --- a/v2rayng/badvpn/arpprobe/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -badvpn_add_library(arpprobe "base;system;flow" "" BArpProbe.c) diff --git a/v2rayng/badvpn/badvpn-win32.nix b/v2rayng/badvpn/badvpn-win32.nix deleted file mode 100644 index f5e3e4f63f..0000000000 --- a/v2rayng/badvpn/badvpn-win32.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ stdenv, cmake, pkgconfig, openssl, nspr, nss, zlib, sqlite, zip, debug ? false }: - -rec { - badvpn = ( - let - compileFlags = "-O3 ${stdenv.lib.optionalString (!debug) "-DNDEBUG"}"; - in - stdenv.mkDerivation { - name = "badvpn"; - - src = stdenv.lib.cleanSource ./.; - - nativeBuildInputs = [ cmake pkgconfig ]; - buildInputs = [ openssl nspr nss ]; - - NIX_CFLAGS_COMPILE = "-I${nspr.crossDrv.dev}/include/nspr -I${nss.crossDrv.dev}/include/nss -ggdb"; - NIX_CFLAGS_LINK = ["-ggdb"]; - - preConfigure = '' - cmakeFlagsArray=( "-DCMAKE_BUILD_TYPE=" "-DCMAKE_C_FLAGS=${compileFlags}" "-DCMAKE_SYSTEM_NAME=Windows" ); - ''; - - postInstall = '' - for lib in eay32; do - cp ${openssl.crossDrv.bin}/bin/lib$lib.dll $out/bin/ - done - for lib in nspr4 plc4 plds4; do - cp ${nspr.crossDrv.out}/lib/lib$lib.dll $out/bin/ - done - for lib in nss3 nssutil3 smime3 ssl3 softokn3 freebl3; do - cp ${nss.crossDrv.out}/lib/$lib.dll $out/bin/ - done - cp ${zlib.crossDrv.out}/bin/zlib1.dll $out/bin/ - cp ${sqlite.crossDrv.out}/bin/libsqlite3-0.dll $out/bin/ - _linkDLLs() { true; } - ''; - - dontCrossStrip = true; - }).crossDrv; - - badvpnZip = stdenv.mkDerivation { - name = "badvpn.zip"; - unpackPhase = "true"; - nativeBuildInputs = [ zip ]; - installPhase = '' - mkdir badvpn-win32 - ln -s ${badvpn}/bin badvpn-win32/bin - zip -q -r $out badvpn-win32 - ''; - }; -} diff --git a/v2rayng/badvpn/badvpn.7 b/v2rayng/badvpn/badvpn.7 deleted file mode 100644 index c421a35b1a..0000000000 --- a/v2rayng/badvpn/badvpn.7 +++ /dev/null @@ -1,324 +0,0 @@ -.TH badvpn 7 "6 October 2010" -.SH NAME -BadVPN - peer-to-peer VPN system -.SH DESCRIPTION -.P -BadVPN is a peer-to-peer VPN system. It provides a Layer 2 (Ethernet) network between -the peers (VPN network nodes). The peers connect to a central server which acts as a chat -server for them to establish direct connections between each other (data connections). -These connections are used for transferring network data (Ethernet frames). -.SS "Features" -.P -.B "Data connections" -.P -Peers can transfer network data either over UDP or TCP. For both there are ways of -securing the data (see below). -.P -.B "IPv6 support" -.P -IPv6 can be used for both server connections and data connections, alongside with IPv4. -Additionally, both can be combined to allow gradual migration to IPv6. -.P -.B "Address selection" -.P -Because NATs and firewalls are widespread, it is harder for peer-to-peer services to operate. -In general, for two computers to be able to communicate, one computer must -.I bind -to one of its addresses, and the other computer must -.I connect -to the computer that binded (both for TCP and UDP). In a network with point-to-point -connectivity, the connecting computer can connect to the same address as the binding computer -bound to, so it is sufficient for the binding computer to send its address to the connecting -computer. However, NATs and firewalls break point-to-point connectivity. When a network is -behind a NAT, it is, by default, impossible for computers outside of that network to connect -to computers inside the network. This is because computers inside the network have no externally -visible IP address, and only communicate with the outside world through the external IP address -of the NAT router. It is however possible to manually configure the NAT router to -.I forward -a specific port number on its external IP address to a specific computer inside the network. -This makes it possible for a computer outside of the network to connect to a computer inside -a network, however, it must connect to the external address of the NAT router (rather than -the address the computer inside bound to, which is its internal address). So there needs -to be some way for the connecting peer to know what address to connect to. -.P -BadVPN solves this problem with so-called -.IR "address scopes" "." -The peer that binds must have a list of external addresses for each address it can bind to, -possibly ordered from best to worst. Each external address has its scope name. A scope name -represents part of a network from which an external address can be reached. On the other hand, -the peer that connects must have a list of scopes which it can reach. When a peer binds to an -address, it sends the other peer a list of external addresses along with scope names. That peer -than chooses the first external address whose scope it recognizes and attempts to connect to it -(if there is one). -.P -BadVPN also allows a peer to have multiple addresses for binding to. It is possible to specify -both an IPv4 and an IPv6 address to work in a multi-protocol environment. -.P -.B "Relaying" -.P -BadVPN can be configured to allow pairs of peers that cannot communicate directly (i.e. because of -NATs or firewalls) to relay network data through a third peer. Relaying is only attempted if -none of the two peers recognize any of the other peer's external addresses (or there are none). -For relaying to work, for each of the two peers (P1, other one P2) there must be at least one -third peer (R) that P1 it is allowed to relay through and can communicate directly with, and all -such peers R must be able to communicate directly with P2. -.P -.B "IGMP snooping" -.P -BadVPN nodes perform IGMP snooping in order to efficiently deliver multicast frames. For example, -this makes it possible to use BadVPN as a tunnel into an IPTV network of an Internet Service Provider -for you to watch TV from wherever you want (given sufficient link quality). -.P -.B "Code quality" -.P -BadVPN has great focus on code quality and reliability. BadVPN is written in the C programming -language. It is a single-threaded event-driven program. This allows for low resource usage and -fast response times. Even though C is a relatively low-level language, the programs are made of -small, highly cohesive and loosely coupled modules that are combined into a complete program on -a high level. Modules are accesed and communicate through small, simple and to-the-point interfaces. -It utilizes a flow-based design which greatly simplifies processing of data and input and output -of the programs. -.SS "Security features" -.P -BadVPN contains many security features, all of which are optional. The included security -features are described here. -.P -.B TLS for client-server connections -.P -It is possible for the peers to communicate with the chat server securely with TLS. It is -highly recommended that this feature is used if any security whatsoever is needed. Not -using it renders all other security features useless, since clients exchange keys -unencrypted via the server. When enabled, the chat server requires each client to identify -itself with a certificate. -.P -BadVPN uses Mozilla's NSS library for TLS support. This means that the required certificates -and keys must be available in a NSS database. The database and certificates can be -generated with the -.B certutil -command. See the examples section on how to generate and distribute the certificates. -.P -.B TLS for peer messaging -.P -If TLS is being used for client-server connections, it will also be used between each pair of -peers communicating via the server, on top of the TLS connections to the server. This secures -the messages from the server itself. It is important because the messages may include -encryption keys and other private data. -.P -.B TLS for TCP data connections -.P -If TCP is used for data connections between the peers, the data connections can be secured -with TLS. This requires using TLS for client-server connections. The clients need to trust -each others' certificates to be able to connect. Additionally, each client must identify to -its peers with the same certificates it used for connecting to the server. -.P -.B Encryption for UDP data connections -.P -If UDP is used for data connections, it is possible for each pair of peers to encrypt their -UDP packets with a symmetric block cipher. Note that the encryption keys are transmitted -through the server unencrypted, so for this to be useful, server connections must be secured -with TLS. The encryption aims to prevent third parties from seeing the real contents of -the network data being transfered. -.P -.B Hashes for UDP data connections -.P -If UDP is used for data connections, it is possible to include hashes in packets. Note that -hashes are only useful together with encryption. If enabled, the hash is calculated on the -packet with the hash field zeroed and then written to the hash field. Hashes are calculated -and included before encryption (if enabled). Combined with encryption, hashes aim to prevent -third parties from tampering with the packets and injecting them into the network. -.P -.B One-time passwords for UDP data connections -.P -If UDP is used for data connections, it is possible to include one-time passwords in packets. -Note that for this to be useful, server connections must be secured with TLS. -One-time passwords are generated from a seed value by encrypting zero data with a block cipher. -The seed contains the encryption key for the block cipher and the initialization vector. -Only a fixed number of passwords are used from a single seed. The peers exchange seeds through -the server. One-time passwords aim to prevent replay attacks. -.P -.B Control over peer communication -.P -It is possible to instruct the chat server to only allow certain peers to communicate. This -will break end-to-end connectivity in the virtual network. It is useful in certain cases -to improve security, for example when the VPN is used only to allow clients to securely connect -to a central service. -.SH "EXAMPLES" -.SS "Setting up certificates" -.P -If you want to use TLS for server connections (recommended), the server and all the peers will -need certificates. This section explains how to generate and distribute the certificates using -NSS command line tools. -.P -.B Setting up the Certificate Authority (CA) -.P -On the system that will host the CA, create a NSS database for the CA and generate a CA certificate -valid for 24 months: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -N -.br -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "vpnca" -s "CN=vpnca" -t "TC,," -x -2 -v 24 -.br -> Is this a CA certificate [y/N]? y -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -1 -.br -> Is this a critical extension [y/N]? n -.P -Export the public CA certificate (this file is public): -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -L -n vpnca -a > ca.pem -.P -.B Setting up the server certificate -.P -On the CA system, generate a certificate for the server valid for 24 months, with TLS server usage context: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "" -s "CN=" -c "vpnca" -t ",," -2 -6 -v 24 -.br -> 0 -.br -> -1 -.br -> Is this a critical extension [y/N]? n -.br -> Is this a CA certificate [y/N]? n -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -.br -> Is this a critical extension [y/N]? n -.P -Export the server certificate to a PKCS#12 file (this file must be kept secret): -.P -vpnca $ pk12util -d sql:/home/vpnca/nssdb -o server.p12 -n "" -.P -On the system that will run the server, create a NSS database and import the CA certificate -and the server cerificate: -.P -vpnserver $ certutil -d sql:/home/vpnserver/nssdb -N -.br -vpnserver $ certutil -d sql:/home/vpnserver/nssdb -A -t "CT,," -n "vpnca" -i /path/to/ca.pem -.br -vpnserver $ pk12util -d sql:/home/vpnserver/nssdb -i /path/to/server.p12 -.P -.B Setting up peer certificates -.P -On the CA system, generate a certificate for the peer valid for 24 months, with TLS client and -TLS server usage contexts: -.P -vpnca $ certutil -d sql:/home/vpnca/nssdb -S -n "peer-" -s "CN=peer-" -c "vpnca" -t ",," -2 -6 -v 24 -.br -> 0 -.br -> 1 -.br -> -1 -.br -> Is this a critical extension [y/N]? n -.br -> Is this a CA certificate [y/N]? n -.br -> Enter the path length constraint, enter to skip [<0 for unlimited path]: > -.br -> Is this a critical extension [y/N]? n -.P -Export the peer certificate to a PKCS#12 file (this file must be kept secret): -.P -vpnca $ pk12util -d sql:/home/vpnca/nssdb -o peer-.p12 -n "peer-" -.P -On the system that will run the VPN client, create a NSS database and import the CA certificate -and the peer cerificate: -.P -vpnclient $ certutil -d sql:/home/vpnclient/nssdb -N -.br -vpnclient $ certutil -d sql:/home/vpnclient/nssdb -A -t "CT,," -n "vpnca" -i /path/to/ca.pem -.br -vpnclient $ pk12util -d sql:/home/vpnclient/nssdb -i /path/to/peer-.p12 -.SS "Setting up TAP devices" -.P -You need to create and configure TAP devices on all computers that will participate in the virtual network -(i.e. run the client program). See -.BR badvpn-client (8), -section `TAP DEVICE CONFIGURATION` for details. -.SS "Example: Local IPv4 network, UDP transport, zero security" -.P -.B Starting the server: -.P -badvpn-server --listen-addr 0.0.0.0:7000 -.P -.B Starting the peers: -.P -badvpn-client -.RS ---server-addr :7000 -.br ---transport-mode udp --encryption-mode none --hash-mode none -.br ---scope local1 -.br ---bind-addr 0.0.0.0:8000 --num-ports 30 --ext-addr {server_reported}:8000 local1 -.br ---tapdev tap0 -.RE -.SS "Example: Adding TLS and UDP security" -.P -.B Starting the server (other options as above): -.P -badvpn-server ... -.RS ---ssl --nssdb sql:/home/vpnserver/nssdb --server-cert-name "" -.RE -.P -.B Starting the peers (other options as above): -.P -badvpn-client ... -.RS ---ssl --nssdb sql:/home/vpnclient/nssdb --client-cert-name "peer-" -.br ---encryption-mode blowfish --hash-mode md5 --otp blowfish 3000 2000 -.RE -.SS "Example: Multiple local networks behind NATs, all connected to the Internet" -.P -For each peer in the existing local network, configure the NAT router to forward its -range of ports to it (assuming their port ranges do not overlap). The clients also need -to know the external IP address of the NAT router. If you don't have a static one, -you'll need to discover it before starting the clients. Also forward the server port to -the server. -.P -.B Starting the peers in the local network (other options as above): -.P -badvpn-client -.RS -.RB "..." -.br ---scope internet -.br -.RB "..." -.br ---ext-addr : internet -.br -.RB "..." -.RE -.P -The --ext-addr option applies to the previously specified --bind-addr option, and must come after -the first --ext-addr option which specifies a local address. -.P -Now perform a similar setup in some other local network behind a NAT. However: -.br -- Don't set up a new server, instead make the peers connect to the existing server in the first -local network. -.br -- You can't use {server_reported} for the local address --ext-addr options, because the server -would report the NAT router's external address rather than the peer's internal address. Instead -each peer has to know its internal IP address. -.br -- Use a different scope name for it, e.g. "local2" instead of "local1". -.P -If setup correctly, all peers will be able to communicate: those in the same local network will -communicate directly through local addresses, and those in different local networks will -communicate through the Internet. -.SH "PROTOCOL" -The protocols used in BadVPN are described in the source code in the protocol/ directory. -.SH "SEE ALSO" -.BR badvpn-server (8), -.BR badvpn-client (8) -.SH AUTHORS -Ambroz Bizjak diff --git a/v2rayng/badvpn/badvpn.nix b/v2rayng/badvpn/badvpn.nix deleted file mode 100644 index a13baf025e..0000000000 --- a/v2rayng/badvpn/badvpn.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ stdenv, cmake, pkgconfig, openssl, nspr, nss, debug ? false }: -let - compileFlags = "-O3 ${stdenv.lib.optionalString (!debug) "-DNDEBUG"}"; -in -stdenv.mkDerivation { - name = "badvpn"; - nativeBuildInputs = [ cmake pkgconfig ]; - buildInputs = [ openssl nspr nss ]; - src = stdenv.lib.cleanSource ./.; - preConfigure = '' - cmakeFlagsArray=( "-DCMAKE_BUILD_TYPE=" "-DCMAKE_C_FLAGS=${compileFlags}" ); - ''; -} diff --git a/v2rayng/badvpn/base/BLog.c b/v2rayng/badvpn/base/BLog.c deleted file mode 100644 index bd4b345d88..0000000000 --- a/v2rayng/badvpn/base/BLog.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file BLog.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "BLog.h" - -#ifdef __ANDROID__ -#include -#endif - -#ifndef BADVPN_PLUGIN - -struct _BLog_channel blog_channel_list[] = { -#include -}; - -struct _BLog_global blog_global = {0}; - -#endif - -// keep in sync with level numbers in BLog.h! -static char *level_names[] = { NULL, "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG" }; - -#ifdef __ANDROID__ -static int android_log_level_map[] = {ANDROID_LOG_FATAL, ANDROID_LOG_ERROR, ANDROID_LOG_WARN, - ANDROID_LOG_INFO, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG -}; -#endif - -static void stdout_log (int channel, int level, const char *msg) -{ -#ifndef __ANDROID__ - fprintf(stdout, "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -#else - __android_log_print(android_log_level_map[level], "tun2socks", - "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -#endif -} - -static void stderr_log (int channel, int level, const char *msg) -{ -#ifndef __ANDROID__ - fprintf(stderr, "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -#else - __android_log_print(android_log_level_map[level], "tun2socks", - "%s(%s): %s\n", level_names[level], blog_global.channels[channel].name, msg); -#endif -} - -static void stdout_stderr_free (void) -{ -} - -void BLog_InitStdout (void) -{ - BLog_Init(stdout_log, stdout_stderr_free); -} - -void BLog_InitStderr (void) -{ - BLog_Init(stderr_log, stdout_stderr_free); -} diff --git a/v2rayng/badvpn/base/BLog.h b/v2rayng/badvpn/base/BLog.h deleted file mode 100644 index 0216c686fc..0000000000 --- a/v2rayng/badvpn/base/BLog.h +++ /dev/null @@ -1,400 +0,0 @@ -/** - * @file BLog.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A global object for logging. - */ - -#ifndef BADVPN_BLOG_H -#define BADVPN_BLOG_H - -#include -#include - -#include -#include -#include - -// auto-generated channel numbers and number of channels -#include - -// keep in sync with level names in BLog.c! -#define BLOG_ERROR 1 -#define BLOG_WARNING 2 -#define BLOG_NOTICE 3 -#define BLOG_INFO 4 -#define BLOG_DEBUG 5 - -#define BLog(...) BLog_LogToChannel(BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define BContextLog(context, ...) BLog_ContextLog((context), BLOG_CURRENT_CHANNEL, __VA_ARGS__) -#define BLOG_CCCC(context) BLog_MakeChannelContext((context), BLOG_CURRENT_CHANNEL) - -typedef void (*_BLog_log_func) (int channel, int level, const char *msg); -typedef void (*_BLog_free_func) (void); - -struct _BLog_channel { - const char *name; - int loglevel; -}; - -struct _BLog_global { - #ifndef NDEBUG - int initialized; // initialized statically - #endif - struct _BLog_channel channels[BLOG_NUM_CHANNELS]; - _BLog_log_func log_func; - _BLog_free_func free_func; - BMutex mutex; -#ifndef NDEBUG - int logging; -#endif - char logbuf[2048]; - int logbuf_pos; -}; - -extern struct _BLog_channel blog_channel_list[]; -extern struct _BLog_global blog_global; - -typedef void (*BLog_logfunc) (void *); - -typedef struct { - BLog_logfunc logfunc; - void *logfunc_user; -} BLogContext; - -typedef struct { - BLogContext context; - int channel; -} BLogChannelContext; - -static int BLogGlobal_GetChannelByName (const char *channel_name); - -static void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func); -static void BLog_Free (void); -static void BLog_SetChannelLoglevel (int channel, int loglevel); -static int BLog_WouldLog (int channel, int level); -static void BLog_Begin (void); -static void BLog_AppendVarArg (const char *fmt, va_list vl); -static void BLog_Append (const char *fmt, ...); -static void BLog_AppendBytes (MemRef data); -static void BLog_Finish (int channel, int level); -static void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl); -static void BLog_LogToChannel (int channel, int level, const char *fmt, ...); -static void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl); -static void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...); -static BLogContext BLog_RootContext (void); -static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user); -static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl); -static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...); -static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel); -static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl); -static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...); - -void BLog_InitStdout (void); -void BLog_InitStderr (void); - -int BLogGlobal_GetChannelByName (const char *channel_name) -{ - int i; - for (i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (!strcmp(blog_channel_list[i].name, channel_name)) { - return i; - } - } - - return -1; -} - -void BLog_Init (_BLog_log_func log_func, _BLog_free_func free_func) -{ - ASSERT(!blog_global.initialized) - - #ifndef NDEBUG - blog_global.initialized = 1; - #endif - - // initialize channels - memcpy(blog_global.channels, blog_channel_list, BLOG_NUM_CHANNELS * sizeof(struct _BLog_channel)); - - blog_global.log_func = log_func; - blog_global.free_func = free_func; -#ifndef NDEBUG - blog_global.logging = 0; -#endif - blog_global.logbuf_pos = 0; - blog_global.logbuf[0] = '\0'; - - ASSERT_FORCE(BMutex_Init(&blog_global.mutex)) -} - -void BLog_Free (void) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(!blog_global.logging) -#endif - - BMutex_Free(&blog_global.mutex); - - #ifndef NDEBUG - blog_global.initialized = 0; - #endif - - blog_global.free_func(); -} - -void BLog_SetChannelLoglevel (int channel, int loglevel) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(loglevel >= 0 && loglevel <= BLOG_DEBUG) - - blog_global.channels[channel].loglevel = loglevel; -} - -int BLog_WouldLog (int channel, int level) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - return (level <= blog_global.channels[channel].loglevel); -} - -void BLog_Begin (void) -{ - ASSERT(blog_global.initialized) - - BMutex_Lock(&blog_global.mutex); - -#ifndef NDEBUG - ASSERT(!blog_global.logging) - blog_global.logging = 1; -#endif -} - -void BLog_AppendVarArg (const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - - int w = vsnprintf(blog_global.logbuf + blog_global.logbuf_pos, sizeof(blog_global.logbuf) - blog_global.logbuf_pos, fmt, vl); - - if (w >= sizeof(blog_global.logbuf) - blog_global.logbuf_pos) { - blog_global.logbuf_pos = sizeof(blog_global.logbuf) - 1; - } else { - blog_global.logbuf_pos += w; - } -} - -void BLog_Append (const char *fmt, ...) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - - va_list vl; - va_start(vl, fmt); - BLog_AppendVarArg(fmt, vl); - va_end(vl); -} - -void BLog_AppendBytes (MemRef data) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - - size_t avail = (sizeof(blog_global.logbuf) - 1) - blog_global.logbuf_pos; - data.len = (data.len > avail ? avail : data.len); - - memcpy(blog_global.logbuf + blog_global.logbuf_pos, data.ptr, data.len); - blog_global.logbuf_pos += data.len; - blog_global.logbuf[blog_global.logbuf_pos] = '\0'; -} - -void BLog_Finish (int channel, int level) -{ - ASSERT(blog_global.initialized) -#ifndef NDEBUG - ASSERT(blog_global.logging) -#endif - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - ASSERT(BLog_WouldLog(channel, level)) - - ASSERT(blog_global.logbuf_pos >= 0) - ASSERT(blog_global.logbuf_pos < sizeof(blog_global.logbuf)) - ASSERT(blog_global.logbuf[blog_global.logbuf_pos] == '\0') - - blog_global.log_func(channel, level, blog_global.logbuf); - -#ifndef NDEBUG - blog_global.logging = 0; -#endif - blog_global.logbuf_pos = 0; - blog_global.logbuf[0] = '\0'; - - BMutex_Unlock(&blog_global.mutex); -} - -void BLog_LogToChannelVarArg (int channel, int level, const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - BLog_Begin(); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); -} - -void BLog_LogToChannel (int channel, int level, const char *fmt, ...) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - va_list vl; - va_start(vl, fmt); - - BLog_Begin(); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); - - va_end(vl); -} - -void BLog_LogViaFuncVarArg (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, va_list vl) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - BLog_Begin(); - func(arg); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); -} - -void BLog_LogViaFunc (BLog_logfunc func, void *arg, int channel, int level, const char *fmt, ...) -{ - ASSERT(blog_global.initialized) - ASSERT(channel >= 0 && channel < BLOG_NUM_CHANNELS) - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - if (!BLog_WouldLog(channel, level)) { - return; - } - - va_list vl; - va_start(vl, fmt); - - BLog_Begin(); - func(arg); - BLog_AppendVarArg(fmt, vl); - BLog_Finish(channel, level); - - va_end(vl); -} - -static void BLog__root_logfunc (void *unused) -{ -} - -static BLogContext BLog_RootContext (void) -{ - return BLog_MakeContext(BLog__root_logfunc, NULL); -} - -static BLogContext BLog_MakeContext (BLog_logfunc logfunc, void *logfunc_user) -{ - ASSERT(logfunc) - - BLogContext context; - context.logfunc = logfunc; - context.logfunc_user = logfunc_user; - return context; -} - -static void BLog_ContextLogVarArg (BLogContext context, int channel, int level, const char *fmt, va_list vl) -{ - BLog_LogViaFuncVarArg(context.logfunc, context.logfunc_user, channel, level, fmt, vl); -} - -static void BLog_ContextLog (BLogContext context, int channel, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_ContextLogVarArg(context, channel, level, fmt, vl); - va_end(vl); -} - -static BLogChannelContext BLog_MakeChannelContext (BLogContext context, int channel) -{ - BLogChannelContext ccontext; - ccontext.context = context; - ccontext.channel = channel; - return ccontext; -} - -static void BLog_ChannelContextLogVarArg (BLogChannelContext ccontext, int level, const char *fmt, va_list vl) -{ - BLog_ContextLogVarArg(ccontext.context, ccontext.channel, level, fmt, vl); -} - -static void BLog_ChannelContextLog (BLogChannelContext ccontext, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_ChannelContextLogVarArg(ccontext, level, fmt, vl); - va_end(vl); -} - -#endif diff --git a/v2rayng/badvpn/base/BLog_syslog.c b/v2rayng/badvpn/base/BLog_syslog.c deleted file mode 100644 index d7a954b684..0000000000 --- a/v2rayng/badvpn/base/BLog_syslog.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file BLog_syslog.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include - -#include "BLog_syslog.h" - -static int resolve_facility (char *str, int *out) -{ - if (!strcmp(str, "authpriv")) { - *out = LOG_AUTHPRIV; - } - else if (!strcmp(str, "cron")) { - *out = LOG_CRON; - } - else if (!strcmp(str, "daemon")) { - *out = LOG_DAEMON; - } - else if (!strcmp(str, "ftp")) { - *out = LOG_FTP; - } - else if (!strcmp(str, "local0")) { - *out = LOG_LOCAL0; - } - else if (!strcmp(str, "local1")) { - *out = LOG_LOCAL1; - } - else if (!strcmp(str, "local2")) { - *out = LOG_LOCAL2; - } - else if (!strcmp(str, "local3")) { - *out = LOG_LOCAL3; - } - else if (!strcmp(str, "local4")) { - *out = LOG_LOCAL4; - } - else if (!strcmp(str, "local5")) { - *out = LOG_LOCAL5; - } - else if (!strcmp(str, "local6")) { - *out = LOG_LOCAL6; - } - else if (!strcmp(str, "local7")) { - *out = LOG_LOCAL7; - } - else if (!strcmp(str, "lpr")) { - *out = LOG_LPR; - } - else if (!strcmp(str, "mail")) { - *out = LOG_MAIL; - } - else if (!strcmp(str, "news")) { - *out = LOG_NEWS; - } - else if (!strcmp(str, "syslog")) { - *out = LOG_SYSLOG; - } - else if (!strcmp(str, "user")) { - *out = LOG_USER; - } - else if (!strcmp(str, "uucp")) { - *out = LOG_UUCP; - } - else { - return 0; - } - - return 1; -} - -static int convert_level (int level) -{ - ASSERT(level >= BLOG_ERROR && level <= BLOG_DEBUG) - - switch (level) { - case BLOG_ERROR: - return LOG_ERR; - case BLOG_WARNING: - return LOG_WARNING; - case BLOG_NOTICE: - return LOG_NOTICE; - case BLOG_INFO: - return LOG_INFO; - case BLOG_DEBUG: - return LOG_DEBUG; - default: - ASSERT(0) - return 0; - } -} - -static struct { - char ident[200]; -} syslog_global; - -static void syslog_log (int channel, int level, const char *msg) -{ - syslog(convert_level(level), "%s: %s", blog_global.channels[channel].name, msg); -} - -static void syslog_free (void) -{ - closelog(); -} - -int BLog_InitSyslog (char *ident, char *facility_str) -{ - int facility; - if (!resolve_facility(facility_str, &facility)) { - return 0; - } - - snprintf(syslog_global.ident, sizeof(syslog_global.ident), "%s", ident); - - openlog(syslog_global.ident, 0, facility); - - BLog_Init(syslog_log, syslog_free); - - return 1; -} diff --git a/v2rayng/badvpn/base/BLog_syslog.h b/v2rayng/badvpn/base/BLog_syslog.h deleted file mode 100644 index 1adf04effc..0000000000 --- a/v2rayng/badvpn/base/BLog_syslog.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file BLog_syslog.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * BLog syslog backend. - */ - -#ifndef BADVPN_BLOG_SYSLOG_H -#define BADVPN_BLOG_SYSLOG_H - -#include -#include - -int BLog_InitSyslog (char *ident, char *facility) WARN_UNUSED; - -#endif diff --git a/v2rayng/badvpn/base/BMutex.h b/v2rayng/badvpn/base/BMutex.h deleted file mode 100644 index fbcbd054ec..0000000000 --- a/v2rayng/badvpn/base/BMutex.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file BMutex.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_BMUTEX_H -#define BADVPN_BMUTEX_H - -#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1) -#error BADVPN_THREAD_SAFE is not defined or incorrect -#endif - -#if BADVPN_THREAD_SAFE -#include -#endif - -#include -#include - -typedef struct { -#if BADVPN_THREAD_SAFE - pthread_mutex_t pthread_mutex; -#endif - DebugObject d_obj; -} BMutex; - -static int BMutex_Init (BMutex *o) WARN_UNUSED; -static void BMutex_Free (BMutex *o); -static void BMutex_Lock (BMutex *o); -static void BMutex_Unlock (BMutex *o); - -static int BMutex_Init (BMutex *o) -{ -#if BADVPN_THREAD_SAFE - if (pthread_mutex_init(&o->pthread_mutex, NULL) != 0) { - return 0; - } -#endif - - DebugObject_Init(&o->d_obj); - return 1; -} - -static void BMutex_Free (BMutex *o) -{ - DebugObject_Free(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_destroy(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -static void BMutex_Lock (BMutex *o) -{ - DebugObject_Access(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_lock(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -static void BMutex_Unlock (BMutex *o) -{ - DebugObject_Access(&o->d_obj); - -#if BADVPN_THREAD_SAFE - int res = pthread_mutex_unlock(&o->pthread_mutex); - B_USE(res) - ASSERT(res == 0) -#endif -} - -#endif diff --git a/v2rayng/badvpn/base/BPending.c b/v2rayng/badvpn/base/BPending.c deleted file mode 100644 index 6711604a73..0000000000 --- a/v2rayng/badvpn/base/BPending.c +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @file BPending.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "BPending.h" - -#include "BPending_list.h" -#include - -void BPendingGroup_Init (BPendingGroup *g) -{ - // init jobs list - BPending__List_Init(&g->jobs); - - // init pending counter - DebugCounter_Init(&g->pending_ctr); - - // init debug object - DebugObject_Init(&g->d_obj); -} - -void BPendingGroup_Free (BPendingGroup *g) -{ - DebugCounter_Free(&g->pending_ctr); - ASSERT(BPending__List_IsEmpty(&g->jobs)) - DebugObject_Free(&g->d_obj); -} - -int BPendingGroup_HasJobs (BPendingGroup *g) -{ - DebugObject_Access(&g->d_obj); - - return !BPending__List_IsEmpty(&g->jobs); -} - -void BPendingGroup_ExecuteJob (BPendingGroup *g) -{ - ASSERT(!BPending__List_IsEmpty(&g->jobs)) - DebugObject_Access(&g->d_obj); - - // get a job - BSmallPending *p = BPending__List_First(&g->jobs); - ASSERT(!BPending__ListIsRemoved(p)) - ASSERT(p->pending) - - // remove from jobs list - BPending__List_RemoveFirst(&g->jobs); - - // set not pending - BPending__ListMarkRemoved(p); -#ifndef NDEBUG - p->pending = 0; -#endif - - // execute job - p->handler(p->user); - return; -} - -BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g) -{ - DebugObject_Access(&g->d_obj); - - return BPending__List_First(&g->jobs); -} - -void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user) -{ - // init arguments - o->handler = handler; - o->user = user; - - // set not pending - BPending__ListMarkRemoved(o); -#ifndef NDEBUG - o->pending = 0; -#endif - - // increment pending counter - DebugCounter_Increment(&g->pending_ctr); - - // init debug object - DebugObject_Init(&o->d_obj); -} - -void BSmallPending_Free (BSmallPending *o, BPendingGroup *g) -{ - DebugCounter_Decrement(&g->pending_ctr); - DebugObject_Free(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - // remove from jobs list - if (!BPending__ListIsRemoved(o)) { - BPending__List_Remove(&g->jobs, o); - } -} - -void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - // set handler - o->handler = handler; - o->user = user; -} - -void BSmallPending_Set (BSmallPending *o, BPendingGroup *g) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - // remove from jobs list - if (!BPending__ListIsRemoved(o)) { - BPending__List_Remove(&g->jobs, o); - } - - // insert to jobs list - BPending__List_Prepend(&g->jobs, o); - - // set pending -#ifndef NDEBUG - o->pending = 1; -#endif -} - -void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - if (!BPending__ListIsRemoved(o)) { - // remove from jobs list - BPending__List_Remove(&g->jobs, o); - - // set not pending - BPending__ListMarkRemoved(o); -#ifndef NDEBUG - o->pending = 0; -#endif - } -} - -int BSmallPending_IsSet (BSmallPending *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->pending == !BPending__ListIsRemoved(o)) - - return !BPending__ListIsRemoved(o); -} - -void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user) -{ - BSmallPending_Init(&o->base, g, handler, user); - o->g = g; -} - -void BPending_Free (BPending *o) -{ - BSmallPending_Free(&o->base, o->g); -} - -void BPending_Set (BPending *o) -{ - BSmallPending_Set(&o->base, o->g); -} - -void BPending_Unset (BPending *o) -{ - BSmallPending_Unset(&o->base, o->g); -} - -int BPending_IsSet (BPending *o) -{ - return BSmallPending_IsSet(&o->base); -} diff --git a/v2rayng/badvpn/base/BPending.h b/v2rayng/badvpn/base/BPending.h deleted file mode 100644 index 07644beae0..0000000000 --- a/v2rayng/badvpn/base/BPending.h +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file BPending.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Module for managing a queue of jobs pending execution. - */ - -#ifndef BADVPN_BPENDING_H -#define BADVPN_BPENDING_H - -#include - -#include -#include -#include - -struct BSmallPending_s; - -#include "BPending_list.h" -#include - -/** - * Job execution handler. - * It is guaranteed that the associated {@link BSmallPending} object was - * in set state. - * The {@link BSmallPending} object enters not set state before the handler - * is called. - * - * @param user as in {@link BSmallPending_Init} - */ -typedef void (*BSmallPending_handler) (void *user); - -/** - * Job execution handler. - * It is guaranteed that the associated {@link BPending} object was - * in set state. - * The {@link BPending} object enters not set state before the handler - * is called. - * - * @param user as in {@link BPending_Init} - */ -typedef void (*BPending_handler) (void *user); - -/** - * Object that contains a list of jobs pending execution. - */ -typedef struct { - BPending__List jobs; - DebugCounter pending_ctr; - DebugObject d_obj; -} BPendingGroup; - -/** - * Object for queuing a job for execution. - */ -typedef struct BSmallPending_s { - BPending_handler handler; - void *user; - BPending__ListNode pending_node; // optimization: if not pending, .next is this -#ifndef NDEBUG - uint8_t pending; -#endif - DebugObject d_obj; -} BSmallPending; - -/** - * Object for queuing a job for execution. This is a convenience wrapper - * around {@link BSmallPending} with an extra field to remember the - * {@link BPendingGroup} being used. - */ -typedef struct { - BSmallPending base; - BPendingGroup *g; -} BPending; - -/** - * Initializes the object. - * - * @param g the object - */ -void BPendingGroup_Init (BPendingGroup *g); - -/** - * Frees the object. - * There must be no {@link BPending} or {@link BSmallPending} objects using - * this group. - * - * @param g the object - */ -void BPendingGroup_Free (BPendingGroup *g); - -/** - * Checks if there is at least one job in the queue. - * - * @param g the object - * @return 1 if there is at least one job, 0 if not - */ -int BPendingGroup_HasJobs (BPendingGroup *g); - -/** - * Executes the top job on the job list. - * The job is removed from the list and enters - * not set state before being executed. - * There must be at least one job in job list. - * - * @param g the object - */ -void BPendingGroup_ExecuteJob (BPendingGroup *g); - -/** - * Returns the top job on the job list, or NULL if there are none. - * - * @param g the object - * @return the top job if there is at least one job, NULL if not - */ -BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g); - -/** - * Initializes the object. - * The object is initialized in not set state. - * - * @param o the object - * @param g pending group to use - * @param handler job execution handler - * @param user value to pass to handler - */ -void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user); - -/** - * Frees the object. - * The execution handler will not be called after the object - * is freed. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Free (BSmallPending *o, BPendingGroup *g); - -/** - * Changes the job execution handler. - * - * @param o the object - * @param handler job execution handler - * @param user value to pass to handler - */ -void BSmallPending_SetHandler (BSmallPending *o, BSmallPending_handler handler, void *user); - -/** - * Enables the job, pushing it to the top of the job list. - * If the object was already in set state, the job is removed from its - * current position in the list before being pushed. - * The object enters set state. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Set (BSmallPending *o, BPendingGroup *g); - -/** - * Disables the job, removing it from the job list. - * If the object was not in set state, nothing is done. - * The object enters not set state. - * - * @param o the object - * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}. - */ -void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g); - -/** - * Checks if the job is in set state. - * - * @param o the object - * @return 1 if in set state, 0 if not - */ -int BSmallPending_IsSet (BSmallPending *o); - -/** - * Initializes the object. - * The object is initialized in not set state. - * - * @param o the object - * @param g pending group to use - * @param handler job execution handler - * @param user value to pass to handler - */ -void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user); - -/** - * Frees the object. - * The execution handler will not be called after the object - * is freed. - * - * @param o the object - */ -void BPending_Free (BPending *o); - -/** - * Enables the job, pushing it to the top of the job list. - * If the object was already in set state, the job is removed from its - * current position in the list before being pushed. - * The object enters set state. - * - * @param o the object - */ -void BPending_Set (BPending *o); - -/** - * Disables the job, removing it from the job list. - * If the object was not in set state, nothing is done. - * The object enters not set state. - * - * @param o the object - */ -void BPending_Unset (BPending *o); - -/** - * Checks if the job is in set state. - * - * @param o the object - * @return 1 if in set state, 0 if not - */ -int BPending_IsSet (BPending *o); - -#endif diff --git a/v2rayng/badvpn/base/BPending_list.h b/v2rayng/badvpn/base/BPending_list.h deleted file mode 100644 index eadac61ab7..0000000000 --- a/v2rayng/badvpn/base/BPending_list.h +++ /dev/null @@ -1,4 +0,0 @@ -#define SLINKEDLIST_PARAM_NAME BPending__List -#define SLINKEDLIST_PARAM_FEATURE_LAST 0 -#define SLINKEDLIST_PARAM_TYPE_ENTRY struct BSmallPending_s -#define SLINKEDLIST_PARAM_MEMBER_NODE pending_node diff --git a/v2rayng/badvpn/base/CMakeLists.txt b/v2rayng/badvpn/base/CMakeLists.txt deleted file mode 100644 index cf1f0f0fcc..0000000000 --- a/v2rayng/badvpn/base/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(BASE_ADDITIONAL_SOURCES) - -if (HAVE_SYSLOG_H) - list(APPEND BASE_ADDITIONAL_SOURCES BLog_syslog.c) -endif () - -set(BASE_SOURCES - DebugObject.c - BLog.c - BPending.c - ${BASE_ADDITIONAL_SOURCES} -) -badvpn_add_library(base "" "" "${BASE_SOURCES}") diff --git a/v2rayng/badvpn/base/DebugObject.c b/v2rayng/badvpn/base/DebugObject.c deleted file mode 100644 index e69461771e..0000000000 --- a/v2rayng/badvpn/base/DebugObject.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file DebugObject.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "DebugObject.h" - -#ifndef BADVPN_PLUGIN -#ifndef NDEBUG -DebugCounter debugobject_counter = DEBUGCOUNTER_STATIC; -#if BADVPN_THREAD_SAFE -pthread_mutex_t debugobject_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif -#endif -#endif diff --git a/v2rayng/badvpn/base/DebugObject.h b/v2rayng/badvpn/base/DebugObject.h deleted file mode 100644 index dd9d4bad10..0000000000 --- a/v2rayng/badvpn/base/DebugObject.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file DebugObject.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used for detecting leaks. - */ - -#ifndef BADVPN_DEBUGOBJECT_H -#define BADVPN_DEBUGOBJECT_H - -#include - -#if !defined(BADVPN_THREAD_SAFE) || (BADVPN_THREAD_SAFE != 0 && BADVPN_THREAD_SAFE != 1) -#error BADVPN_THREAD_SAFE is not defined or incorrect -#endif - -#if BADVPN_THREAD_SAFE -#include -#endif - -#include -#include - -#define DEBUGOBJECT_VALID UINT32_C(0x31415926) - -/** - * Object used for detecting leaks. - */ -typedef struct { - #ifndef NDEBUG - uint32_t c; - #else - int dummy_field; // struct must have at least one field - #endif -} DebugObject; - -/** - * Initializes the object. - * - * @param obj the object - */ -static void DebugObject_Init (DebugObject *obj); - -/** - * Frees the object. - * - * @param obj the object - */ -static void DebugObject_Free (DebugObject *obj); - -/** - * Does nothing. - * - * @param obj the object - */ -static void DebugObject_Access (const DebugObject *obj); - -/** - * Does nothing. - * There must be no {@link DebugObject}'s initialized. - */ -static void DebugObjectGlobal_Finish (void); - -#ifndef NDEBUG -extern DebugCounter debugobject_counter; -#if BADVPN_THREAD_SAFE -extern pthread_mutex_t debugobject_mutex; -#endif -#endif - -void DebugObject_Init (DebugObject *obj) -{ - #ifndef NDEBUG - - obj->c = DEBUGOBJECT_VALID; - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0) - #endif - - DebugCounter_Increment(&debugobject_counter); - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0) - #endif - - #endif -} - -void DebugObject_Free (DebugObject *obj) -{ - ASSERT(obj->c == DEBUGOBJECT_VALID) - - #ifndef NDEBUG - - obj->c = 0; - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_lock(&debugobject_mutex) == 0) - #endif - - DebugCounter_Decrement(&debugobject_counter); - - #if BADVPN_THREAD_SAFE - ASSERT_FORCE(pthread_mutex_unlock(&debugobject_mutex) == 0) - #endif - - #endif -} - -void DebugObject_Access (const DebugObject *obj) -{ - ASSERT(obj->c == DEBUGOBJECT_VALID) -} - -void DebugObjectGlobal_Finish (void) -{ - #ifndef NDEBUG - DebugCounter_Free(&debugobject_counter); - #endif -} - -#endif diff --git a/v2rayng/badvpn/blog_channels.txt b/v2rayng/badvpn/blog_channels.txt deleted file mode 100644 index 18657d5eb2..0000000000 --- a/v2rayng/badvpn/blog_channels.txt +++ /dev/null @@ -1,148 +0,0 @@ -server 4 -client 4 -flooder 4 -tun2socks 4 -ncd 4 -ncd_var 4 -ncd_list 4 -ncd_depend 4 -ncd_multidepend 4 -ncd_dynamic_depend 4 -ncd_concat 4 -ncd_if 4 -ncd_strcmp 4 -ncd_regex_match 4 -ncd_logical 4 -ncd_sleep 4 -ncd_print 4 -ncd_blocker 4 -ncd_run 4 -ncd_runonce 4 -ncd_daemon 4 -ncd_spawn 4 -ncd_imperative 4 -ncd_ref 4 -ncd_index 4 -ncd_alias 4 -ncd_process_manager 4 -ncd_ondemand 4 -ncd_foreach 4 -ncd_choose 4 -ncd_net_backend_waitdevice 4 -ncd_net_backend_waitlink 4 -ncd_net_backend_badvpn 4 -ncd_net_backend_wpa_supplicant 4 -ncd_net_backend_rfkill 4 -ncd_net_up 4 -ncd_net_dns 4 -ncd_net_iptables 4 -ncd_net_ipv4_addr 4 -ncd_net_ipv4_route 4 -ncd_net_ipv4_dhcp 4 -ncd_net_ipv4_arp_probe 4 -ncd_net_watch_interfaces 4 -ncd_sys_watch_input 4 -ncd_sys_watch_usb 4 -ncd_sys_evdev 4 -ncd_sys_watch_directory 4 -StreamPeerIO 4 -DatagramPeerIO 4 -BReactor 3 -BSignal 3 -FragmentProtoAssembler 4 -BPredicate 3 -ServerConnection 4 -Listener 4 -DataProto 4 -FrameDecider 4 -BSocksClient 4 -BDHCPClientCore 4 -BDHCPClient 4 -NCDIfConfig 4 -BUnixSignal 4 -BProcess 4 -PRStreamSink 4 -PRStreamSource 4 -PacketProtoDecoder 4 -DPRelay 4 -BThreadWork 4 -DPReceive 4 -BInputProcess 4 -NCDUdevMonitorParser 4 -NCDUdevMonitor 4 -NCDUdevCache 4 -NCDUdevManager 4 -BTime 4 -BEncryption 4 -SPProtoDecoder 4 -LineBuffer 4 -BTap 4 -lwip 4 -NCDConfigTokenizer 4 -NCDConfigParser 4 -NCDValParser 4 -nsskey 4 -addr 4 -PasswordListener 4 -NCDInterfaceMonitor 4 -NCDRfkillMonitor 4 -udpgw 4 -UdpGwClient 4 -SocksUdpGwClient 4 -SocksUdpClient 4 -BNetwork 4 -BConnection 4 -BSSLConnection 4 -BDatagram 4 -PeerChat 4 -BArpProbe 4 -NCDModuleIndex 4 -NCDModuleProcess 4 -NCDValGenerator 4 -ncd_from_string 4 -ncd_to_string 4 -ncd_value 4 -ncd_try 4 -ncd_sys_request_server 4 -NCDRequest 4 -ncd_net_ipv6_wait_dynamic_addr 4 -NCDRequestClient 4 -ncd_request 4 -ncd_sys_request_client 4 -ncd_exit 4 -ncd_getargs 4 -ncd_arithmetic 4 -ncd_parse 4 -ncd_valuemetic 4 -ncd_file 4 -ncd_netmask 4 -ncd_implode 4 -ncd_call2 4 -ncd_assert 4 -ncd_reboot 4 -ncd_explode 4 -NCDPlaceholderDb 4 -NCDVal 4 -ncd_net_ipv6_addr 4 -ncd_net_ipv6_route 4 -ncd_net_ipv4_addr_in_network 4 -ncd_net_ipv6_addr_in_network 4 -dostest_server 4 -dostest_attacker 4 -ncd_timer 4 -ncd_file_open 4 -ncd_backtrack 4 -ncd_socket 4 -ncd_depend_scope 4 -ncd_substr 4 -ncd_sys_start_process 4 -NCDBuildProgram 4 -ncd_log 4 -ncd_log_msg 4 -ncd_buffer 4 -ncd_getenv 4 -BThreadSignal 4 -BLockReactor 4 -ncd_load_module 4 -ncd_basic_functions 4 -ncd_objref 4 diff --git a/v2rayng/badvpn/blog_generator/blog.php b/v2rayng/badvpn/blog_generator/blog.php deleted file mode 100644 index fd436bc8ca..0000000000 --- a/v2rayng/badvpn/blog_generator/blog.php +++ /dev/null @@ -1,121 +0,0 @@ - Input channels file. - --output-dir Destination directory for generated files. - -EOD; -} - -$input_file = ""; -$output_dir = ""; - -for ($i = 1; $i < $argc;) { - $arg = $argv[$i++]; - switch ($arg) { - case "--input-file": - $input_file = $argv[$i++]; - break; - case "--output-dir": - $output_dir = $argv[$i++]; - break; - case "--help": - print_help($argv[0]); - exit(0); - default: - fatal_error("Unknown option: {$arg}"); - } -} - -if ($input_file == "") { - fatal_error("--input-file missing"); -} - -if ($output_dir == "") { - fatal_error("--output-dir missing"); -} - -if (($data = file_get_contents($input_file)) === FALSE) { - fatal_error("Failed to read input file"); -} - -if (!tokenize($data, $tokens)) { - fatal_error("Failed to tokenize"); -} - -$i = 0; -$channels_defines = ""; -$channels_list = ""; - -reset($tokens); - -while (1) { - if (($ch_name = current($tokens)) === FALSE) { - break; - } - next($tokens); - if (($ch_priority = current($tokens)) === FALSE) { - fatal_error("missing priority"); - } - next($tokens); - if ($ch_name[0] != "name") { - fatal_error("name is not a name"); - } - if ($ch_priority[0] != "number") { - fatal_error("priority is not a number"); - } - - $channel_file = << 0) { - if (preg_match('/^\\/\\/.*/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\\s+/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[0-9]+/', $str, $matches)) { - $out[] = array('number', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*/', $str, $matches)) { - $out[] = array('name', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else { - return FALSE; - } - } - - return TRUE; -} - -function fatal_error ($message) -{ - fwrite(STDERR, "Fatal error: $message\n"); - - ob_get_clean(); - exit(1); -} diff --git a/v2rayng/badvpn/bproto/BProto.h b/v2rayng/badvpn/bproto/BProto.h deleted file mode 100644 index 5f2a6969d9..0000000000 --- a/v2rayng/badvpn/bproto/BProto.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file BProto.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Definitions for BProto serialization. - */ - -#ifndef BADVPN_BPROTO_BPROTO_H -#define BADVPN_BPROTO_BPROTO_H - -#include - -#include - -#define BPROTO_TYPE_UINT8 1 -#define BPROTO_TYPE_UINT16 2 -#define BPROTO_TYPE_UINT32 3 -#define BPROTO_TYPE_UINT64 4 -#define BPROTO_TYPE_DATA 5 -#define BPROTO_TYPE_CONSTDATA 6 - -B_START_PACKED -struct BProto_header_s { - uint16_t id; - uint16_t type; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint8_s { - uint8_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint16_s { - uint16_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint32_s { - uint32_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_uint64_s { - uint64_t v; -} B_PACKED; -B_END_PACKED - -B_START_PACKED -struct BProto_data_header_s { - uint32_t len; -} B_PACKED; -B_END_PACKED - -#endif diff --git a/v2rayng/badvpn/bproto_generator/ProtoParser.lime b/v2rayng/badvpn/bproto_generator/ProtoParser.lime deleted file mode 100644 index f039e1d348..0000000000 --- a/v2rayng/badvpn/bproto_generator/ProtoParser.lime +++ /dev/null @@ -1,99 +0,0 @@ -%class ProtoParser -%start file - -file = - directives messages { - $$ = array( - "directives" => $1, - "messages" => $2 - ); - }. - -directives = - { - $$ = array(); - } | - directive semicolon directives { - $$ = array_merge(array($1), $3); - }. - -directive = - include string { - $$ = array( - "type" => "include", - "file" => $2 - ); - }. - -messages = - msgspec { - $$ = array($1); - } | - msgspec messages { - $$ = array_merge(array($1), $2); - }. - -msgspec = - message name spar entries epar semicolon { - $$ = array( - "name" => $2, - "entries" => $4 - ); -}. - -entries = - entry { - $$ = array($1); - } | - entry entries { - $$ = array_merge(array($1), $2); - }. - -entry = - cardinality type name equals number semicolon { - $$ = array( - "cardinality" => $1, - "type" => $2, - "name" => $3, - "id" => $5 - ); - }. - -cardinality = - repeated { - $$ = "repeated"; - } | - optional { - $$ = "optional"; - } | - required { - $$ = "required"; - } | - required repeated { - $$ = "required repeated"; - }. - -type = - uint { - $$ = array( - "type" => "uint", - "size" => $1 - ); - } | - data { - $$ = array( - "type" => "data" - ); - } | - data srpar string erpar { - $$ = array( - "type" => "constdata", - "size" => $3 - ); - } | - message name { - $$ = array( - "type" => "message", - "message" => $2 - ); - }. diff --git a/v2rayng/badvpn/bproto_generator/ProtoParser.php b/v2rayng/badvpn/bproto_generator/ProtoParser.php deleted file mode 100644 index 0477dbaf24..0000000000 --- a/v2rayng/badvpn/bproto_generator/ProtoParser.php +++ /dev/null @@ -1,560 +0,0 @@ - - array ( - 'directives' => 's 1', - 'directive' => 's 30', - 'include' => 's 33', - 'file' => 's 35', - '\'start\'' => 'a \'start\'', - 'message' => 'r 1', - ), - 1 => - array ( - 'messages' => 's 2', - 'msgspec' => 's 3', - 'message' => 's 5', - ), - 2 => - array ( - '#' => 'r 0', - ), - 3 => - array ( - 'msgspec' => 's 3', - 'messages' => 's 4', - 'message' => 's 5', - '#' => 'r 4', - ), - 4 => - array ( - '#' => 'r 5', - ), - 5 => - array ( - 'name' => 's 6', - ), - 6 => - array ( - 'spar' => 's 7', - ), - 7 => - array ( - 'entries' => 's 8', - 'entry' => 's 11', - 'cardinality' => 's 13', - 'repeated' => 's 26', - 'optional' => 's 27', - 'required' => 's 28', - ), - 8 => - array ( - 'epar' => 's 9', - ), - 9 => - array ( - 'semicolon' => 's 10', - ), - 10 => - array ( - 'message' => 'r 6', - '#' => 'r 6', - ), - 11 => - array ( - 'entry' => 's 11', - 'entries' => 's 12', - 'cardinality' => 's 13', - 'repeated' => 's 26', - 'optional' => 's 27', - 'required' => 's 28', - 'epar' => 'r 7', - ), - 12 => - array ( - 'epar' => 'r 8', - ), - 13 => - array ( - 'type' => 's 14', - 'uint' => 's 19', - 'data' => 's 20', - 'message' => 's 24', - ), - 14 => - array ( - 'name' => 's 15', - ), - 15 => - array ( - 'equals' => 's 16', - ), - 16 => - array ( - 'number' => 's 17', - ), - 17 => - array ( - 'semicolon' => 's 18', - ), - 18 => - array ( - 'repeated' => 'r 9', - 'optional' => 'r 9', - 'required' => 'r 9', - 'epar' => 'r 9', - ), - 19 => - array ( - 'name' => 'r 14', - ), - 20 => - array ( - 'srpar' => 's 21', - 'name' => 'r 15', - ), - 21 => - array ( - 'string' => 's 22', - ), - 22 => - array ( - 'erpar' => 's 23', - ), - 23 => - array ( - 'name' => 'r 16', - ), - 24 => - array ( - 'name' => 's 25', - ), - 25 => - array ( - 'name' => 'r 17', - ), - 26 => - array ( - 'uint' => 'r 10', - 'data' => 'r 10', - 'message' => 'r 10', - ), - 27 => - array ( - 'uint' => 'r 11', - 'data' => 'r 11', - 'message' => 'r 11', - ), - 28 => - array ( - 'repeated' => 's 29', - 'uint' => 'r 12', - 'data' => 'r 12', - 'message' => 'r 12', - ), - 29 => - array ( - 'uint' => 'r 13', - 'data' => 'r 13', - 'message' => 'r 13', - ), - 30 => - array ( - 'semicolon' => 's 31', - ), - 31 => - array ( - 'directive' => 's 30', - 'directives' => 's 32', - 'include' => 's 33', - 'message' => 'r 1', - ), - 32 => - array ( - 'message' => 'r 2', - ), - 33 => - array ( - 'string' => 's 34', - ), - 34 => - array ( - 'semicolon' => 'r 3', - ), - 35 => - array ( - '#' => 'r 18', - ), -); -function reduce_0_file_1($tokens, &$result) { -# -# (0) file := directives messages -# -$result = reset($tokens); - - $result = array( - "directives" => $tokens[0], - "messages" => $tokens[1] - ); - -} - -function reduce_1_directives_1($tokens, &$result) { -# -# (1) directives := -# -$result = reset($tokens); - - $result = array(); - -} - -function reduce_2_directives_2($tokens, &$result) { -# -# (2) directives := directive semicolon directives -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[2]); - -} - -function reduce_3_directive_1($tokens, &$result) { -# -# (3) directive := include string -# -$result = reset($tokens); - - $result = array( - "type" => "include", - "file" => $tokens[1] - ); - -} - -function reduce_4_messages_1($tokens, &$result) { -# -# (4) messages := msgspec -# -$result = reset($tokens); - - $result = array($tokens[0]); - -} - -function reduce_5_messages_2($tokens, &$result) { -# -# (5) messages := msgspec messages -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[1]); - -} - -function reduce_6_msgspec_1($tokens, &$result) { -# -# (6) msgspec := message name spar entries epar semicolon -# -$result = reset($tokens); - - $result = array( - "name" => $tokens[1], - "entries" => $tokens[3] - ); - -} - -function reduce_7_entries_1($tokens, &$result) { -# -# (7) entries := entry -# -$result = reset($tokens); - - $result = array($tokens[0]); - -} - -function reduce_8_entries_2($tokens, &$result) { -# -# (8) entries := entry entries -# -$result = reset($tokens); - - $result = array_merge(array($tokens[0]), $tokens[1]); - -} - -function reduce_9_entry_1($tokens, &$result) { -# -# (9) entry := cardinality type name equals number semicolon -# -$result = reset($tokens); - - $result = array( - "cardinality" => $tokens[0], - "type" => $tokens[1], - "name" => $tokens[2], - "id" => $tokens[4] - ); - -} - -function reduce_10_cardinality_1($tokens, &$result) { -# -# (10) cardinality := repeated -# -$result = reset($tokens); - - $result = "repeated"; - -} - -function reduce_11_cardinality_2($tokens, &$result) { -# -# (11) cardinality := optional -# -$result = reset($tokens); - - $result = "optional"; - -} - -function reduce_12_cardinality_3($tokens, &$result) { -# -# (12) cardinality := required -# -$result = reset($tokens); - - $result = "required"; - -} - -function reduce_13_cardinality_4($tokens, &$result) { -# -# (13) cardinality := required repeated -# -$result = reset($tokens); - - $result = "required repeated"; - -} - -function reduce_14_type_1($tokens, &$result) { -# -# (14) type := uint -# -$result = reset($tokens); - - $result = array( - "type" => "uint", - "size" => $tokens[0] - ); - -} - -function reduce_15_type_2($tokens, &$result) { -# -# (15) type := data -# -$result = reset($tokens); - - $result = array( - "type" => "data" - ); - -} - -function reduce_16_type_3($tokens, &$result) { -# -# (16) type := data srpar string erpar -# -$result = reset($tokens); - - $result = array( - "type" => "constdata", - "size" => $tokens[2] - ); - -} - -function reduce_17_type_4($tokens, &$result) { -# -# (17) type := message name -# -$result = reset($tokens); - - $result = array( - "type" => "message", - "message" => $tokens[1] - ); - -} - -function reduce_18_start_1($tokens, &$result) { -# -# (18) 'start' := file -# -$result = reset($tokens); - -} - -var $method = array ( - 0 => 'reduce_0_file_1', - 1 => 'reduce_1_directives_1', - 2 => 'reduce_2_directives_2', - 3 => 'reduce_3_directive_1', - 4 => 'reduce_4_messages_1', - 5 => 'reduce_5_messages_2', - 6 => 'reduce_6_msgspec_1', - 7 => 'reduce_7_entries_1', - 8 => 'reduce_8_entries_2', - 9 => 'reduce_9_entry_1', - 10 => 'reduce_10_cardinality_1', - 11 => 'reduce_11_cardinality_2', - 12 => 'reduce_12_cardinality_3', - 13 => 'reduce_13_cardinality_4', - 14 => 'reduce_14_type_1', - 15 => 'reduce_15_type_2', - 16 => 'reduce_16_type_3', - 17 => 'reduce_17_type_4', - 18 => 'reduce_18_start_1', -); -var $a = array ( - 0 => - array ( - 'symbol' => 'file', - 'len' => 2, - 'replace' => true, - ), - 1 => - array ( - 'symbol' => 'directives', - 'len' => 0, - 'replace' => true, - ), - 2 => - array ( - 'symbol' => 'directives', - 'len' => 3, - 'replace' => true, - ), - 3 => - array ( - 'symbol' => 'directive', - 'len' => 2, - 'replace' => true, - ), - 4 => - array ( - 'symbol' => 'messages', - 'len' => 1, - 'replace' => true, - ), - 5 => - array ( - 'symbol' => 'messages', - 'len' => 2, - 'replace' => true, - ), - 6 => - array ( - 'symbol' => 'msgspec', - 'len' => 6, - 'replace' => true, - ), - 7 => - array ( - 'symbol' => 'entries', - 'len' => 1, - 'replace' => true, - ), - 8 => - array ( - 'symbol' => 'entries', - 'len' => 2, - 'replace' => true, - ), - 9 => - array ( - 'symbol' => 'entry', - 'len' => 6, - 'replace' => true, - ), - 10 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 11 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 12 => - array ( - 'symbol' => 'cardinality', - 'len' => 1, - 'replace' => true, - ), - 13 => - array ( - 'symbol' => 'cardinality', - 'len' => 2, - 'replace' => true, - ), - 14 => - array ( - 'symbol' => 'type', - 'len' => 1, - 'replace' => true, - ), - 15 => - array ( - 'symbol' => 'type', - 'len' => 1, - 'replace' => true, - ), - 16 => - array ( - 'symbol' => 'type', - 'len' => 4, - 'replace' => true, - ), - 17 => - array ( - 'symbol' => 'type', - 'len' => 2, - 'replace' => true, - ), - 18 => - array ( - 'symbol' => '\'start\'', - 'len' => 1, - 'replace' => true, - ), -); -} diff --git a/v2rayng/badvpn/bproto_generator/bproto.php b/v2rayng/badvpn/bproto_generator/bproto.php deleted file mode 100644 index 76f8c6e487..0000000000 --- a/v2rayng/badvpn/bproto_generator/bproto.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -require_once "lime/parse_engine.php"; -require_once "ProtoParser.php"; -require_once "bproto_functions.php"; - -function assert_failure ($script, $line, $message) -{ - if ($message == "") { - fatal_error("Assertion failure at {$script}:{$line}"); - } else { - fatal_error("Assertion failure at {$script}:{$line}: {$message}"); - } -} - -assert_options(ASSERT_CALLBACK, "assert_failure"); - -function print_help ($name) -{ - echo << Output file prefix. - --input-file Message file to generate source for. - --output-dir Destination directory for generated files. - -EOD; -} - -$name = ""; -$input_file = ""; -$output_dir = ""; - -for ($i = 1; $i < $argc;) { - $arg = $argv[$i++]; - switch ($arg) { - case "--name": - $name = $argv[$i++]; - break; - case "--input-file": - $input_file = $argv[$i++]; - break; - case "--output-dir": - $output_dir = $argv[$i++]; - break; - case "--help": - print_help($argv[0]); - exit(0); - default: - fatal_error("Unknown option: {$arg}"); - } -} - -if ($name == "") { - fatal_error("--name missing"); -} - -if ($input_file == "") { - fatal_error("--input-file missing"); -} - -if ($output_dir == "") { - fatal_error("--output-dir missing"); -} - -if (($data = file_get_contents($input_file)) === FALSE) { - fatal_error("Failed to read input file"); -} - -if (!tokenize($data, $tokens)) { - fatal_error("Failed to tokenize"); -} - -$parser = new parse_engine(new ProtoParser()); - -try { - foreach ($tokens as $token) { - $parser->eat($token[0], $token[1]); - } - $parser->eat_eof(); -} catch (parse_error $e) { - fatal_error("$input_file: Parse error: ".$e->getMessage()); -} - -$data = generate_header($name, $parser->semantic["directives"], $parser->semantic["messages"]); -if (file_put_contents("{$output_dir}/{$name}.h", $data) === NULL) { - fatal_error("{$input_file}: Failed to write .h file"); -} diff --git a/v2rayng/badvpn/bproto_generator/bproto_functions.php b/v2rayng/badvpn/bproto_generator/bproto_functions.php deleted file mode 100644 index 490c1bf124..0000000000 --- a/v2rayng/badvpn/bproto_generator/bproto_functions.php +++ /dev/null @@ -1,777 +0,0 @@ - 0) { - if (preg_match('/^\\/\\/.*/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\\s+/', $str, $matches)) { - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^include/', $str, $matches)) { - $out[] = array('include', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^message/', $str, $matches)) { - $out[] = array('message', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^repeated/', $str, $matches)) { - $out[] = array('repeated', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^required/', $str, $matches)) { - $out[] = array('required', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^optional/', $str, $matches)) { - $out[] = array('optional', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^{/', $str, $matches)) { - $out[] = array('spar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^}/', $str, $matches)) { - $out[] = array('epar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\(/', $str, $matches)) { - $out[] = array('srpar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^\)/', $str, $matches)) { - $out[] = array('erpar', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^=/', $str, $matches)) { - $out[] = array('equals', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^;/', $str, $matches)) { - $out[] = array('semicolon', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^uint(8|16|32|64)/', $str, $matches)) { - $out[] = array('uint', $matches[1]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^data/', $str, $matches)) { - $out[] = array('data', null); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[0-9]+/', $str, $matches)) { - $out[] = array('number', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*/', $str, $matches)) { - $out[] = array('name', $matches[0]); - $str = substr($str, strlen($matches[0])); - } - else if (preg_match('/^"([^"]*)"/', $str, $matches)) { - $out[] = array('string', $matches[1]); - $str = substr($str, strlen($matches[0])); - } - else { - return FALSE; - } - } - - return TRUE; -} - -function fatal_error ($message) -{ - fwrite(STDERR, "Fatal error: $message\n"); - - ob_get_clean(); - exit(1); -} - -function make_writer_decl ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "void {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o, uint{$entry["type"]["size"]}_t v)"; - case "data": - return "uint8_t * {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o, int len)"; - case "constdata": - return "uint8_t * {$msg["name"]}Writer_Add{$entry["name"]} ({$msg["name"]}Writer *o)"; - default: - assert(0); - } -} - -function make_parser_decl ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint{$entry["type"]["size"]}_t *v)"; - case "data": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint8_t **data, int *data_len)"; - case "constdata": - return "int {$msg["name"]}Parser_Get{$entry["name"]} ({$msg["name"]}Parser *o, uint8_t **data)"; - default: - assert(0); - } -} - -function make_parser_reset_decl ($msg, $entry) -{ - return "void {$msg["name"]}Parser_Reset{$entry["name"]} ({$msg["name"]}Parser *o)"; -} - -function make_parser_forward_decl ($msg, $entry) -{ - return "void {$msg["name"]}Parser_Forward{$entry["name"]} ({$msg["name"]}Parser *o)"; -} - -function make_type_name ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "BPROTO_TYPE_UINT{$entry["type"]["size"]}"; - case "data": - return "BPROTO_TYPE_DATA"; - case "constdata": - return "BPROTO_TYPE_CONSTDATA"; - default: - assert(0); - } -} - -function make_finish_assert ($msg, $entry) -{ - switch ($entry["cardinality"]) { - case "repeated": - return "ASSERT(o->{$entry["name"]}_count >= 0)"; - case "required repeated": - return "ASSERT(o->{$entry["name"]}_count >= 1)"; - case "optional": - return "ASSERT(o->{$entry["name"]}_count >= 0 && o->{$entry["name"]}_count <= 1)"; - case "required": - return "ASSERT(o->{$entry["name"]}_count == 1)"; - default: - assert(0); - } -} - -function make_add_count_assert ($msg, $entry) -{ - if (in_array($entry["cardinality"], array("optional", "required"))) { - return "ASSERT(o->{$entry["name"]}_count == 0)"; - } - return ""; -} - -function make_add_length_assert ($msg, $entry) -{ - if ($entry["type"]["type"] == "data") { - return "ASSERT(len >= 0 && len <= UINT32_MAX)"; - } - return ""; -} - -function make_size_define ($msg, $entry) -{ - switch ($entry["type"]["type"]) { - case "uint": - return "#define {$msg["name"]}_SIZE{$entry["name"]} (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint{$entry["type"]["size"]}_s))"; - case "data": - return "#define {$msg["name"]}_SIZE{$entry["name"]}(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len))"; - case "constdata": - return "#define {$msg["name"]}_SIZE{$entry["name"]} (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + ({$entry["type"]["size"]}))"; - default: - assert(0); - } -} - -function generate_header ($name, $directives, $messages) { - ob_start(); - - echo << -#include - -#include -#include -#include - - -EOD; - - foreach ($directives as $directive) { - if ($directive["type"] == "include") { - echo <<out = out; - o->used = 0; - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<{$entry["name"]}_count = 0; - -EOD; - } - - echo <<used >= 0) - -EOD; - - foreach ($msg["entries"] as $entry) { - $ass = make_finish_assert($msg, $entry); - echo <<used; -} - - -EOD; - - foreach ($msg["entries"] as $entry) { - $decl = make_writer_decl($msg, $entry); - $type = make_type_name($msg, $entry); - $add_count_assert = make_add_count_assert($msg, $entry); - $add_length_assert = make_add_length_assert($msg, $entry); - - echo <<used >= 0) - {$add_count_assert} - {$add_length_assert} - - struct BProto_header_s header; - header.id = htol16({$entry["id"]}); - header.type = htol16({$type}); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - -EOD; - switch ($entry["type"]["type"]) { - case "uint": - echo <<out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint{$entry["type"]["size"]}_s); - -EOD; - break; - case "data": - echo <<out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - -EOD; - break; - case "constdata": - echo <<out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += ({$entry["type"]["size"]}); - -EOD; - break; - default: - assert(0); - } - - echo <<{$entry["name"]}_count++; - -EOD; - if (in_array($entry["type"]["type"], array("data", "constdata"))) { - echo <<= 0) - - o->buf = buf; - o->buf_len = buf_len; - -EOD; - - foreach ($msg["entries"] as $entry) { - echo <<{$entry["name"]}_start = o->buf_len; - o->{$entry["name"]}_span = 0; - o->{$entry["name"]}_pos = 0; - -EOD; - } - - echo <<buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - -EOD; - - foreach (array(8, 16, 32, 64) as $bits) { - echo <<= sizeof(struct BProto_uint{$bits}_s))) { - return 0; - } - pos += sizeof(struct BProto_uint{$bits}_s); - left -= sizeof(struct BProto_uint{$bits}_s); - - switch (id) { - -EOD; - - foreach ($msg["entries"] as $entry) { - if (!($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits)) { - continue; - } - $type = make_type_name($msg, $entry); - echo <<{$entry["name"]}_start == o->buf_len) { - o->{$entry["name"]}_start = entry_pos; - } - o->{$entry["name"]}_span = pos - o->{$entry["name"]}_start; - {$entry["name"]}_count++; - break; - -EOD; - } - - echo <<= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - -EOD; - - foreach ($msg["entries"] as $entry) { - if (!in_array($entry["type"]["type"], array("data", "constdata"))) { - continue; - } - $type = make_type_name($msg, $entry); - echo <<{$entry["name"]}_start == o->buf_len) { - o->{$entry["name"]}_start = entry_pos; - } - o->{$entry["name"]}_span = pos - o->{$entry["name"]}_start; - {$entry["name"]}_count++; - break; - -EOD; - } - - echo <<= 1"; - break; - case "optional": - $cond = "{$entry["name"]}_count <= 1"; - break; - case "required": - $cond = "{$entry["name"]}_count == 1"; - break; - default: - assert(0); - } - if ($cond) { - echo <<{$entry["name"]}_pos == o->{$entry["name"]}_span - -EOD; - } - - - echo <<{$entry["name"]}_pos >= 0) - ASSERT(o->{$entry["name"]}_pos <= o->{$entry["name"]}_span) - - int left = o->{$entry["name"]}_span - o->{$entry["name"]}_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(header)); - o->{$entry["name"]}_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - -EOD; - - foreach (array(8, 16, 32, 64) as $bits) { - echo <<= sizeof(struct BProto_uint{$bits}_s)) - -EOD; - if ($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits) { - echo <<buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(val)); - -EOD; - } - echo <<{$entry["name"]}_pos += sizeof(struct BProto_uint{$bits}_s); - left -= sizeof(struct BProto_uint{$bits}_s); - -EOD; - if ($entry["type"]["type"] == "uint" && $entry["type"]["size"] == $bits) { - echo <<= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos, sizeof(val)); - o->{$entry["name"]}_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - -EOD; - if ($entry["type"]["type"] == "data" || $entry["type"]["type"] == "constdata") { - echo <<buf + o->{$entry["name"]}_start + o->{$entry["name"]}_pos; - -EOD; - } - echo <<{$entry["name"]}_pos += payload_len; - left -= payload_len; - -EOD; - if ($entry["type"]["type"] == "data") { - echo <<{$entry["name"]}_pos = 0; -} - -{$forward_decl} -{ - o->{$entry["name"]}_pos = o->{$entry["name"]}_span; -} - - -EOD; - } - } - - return ob_get_clean(); -} diff --git a/v2rayng/badvpn/build-win32.nix b/v2rayng/badvpn/build-win32.nix deleted file mode 100644 index 1609d74acc..0000000000 --- a/v2rayng/badvpn/build-win32.nix +++ /dev/null @@ -1,28 +0,0 @@ -# NOTE: Must be used with patched nixpkgs: -# https://github.com/ambrop72/nixpkgs/tree/cross-mingw-nss - -let - pkgsFun = import ; - - crossSystem = { - config = "i686-w64-mingw32"; - arch = "x86"; - libc = "msvcrt"; - platform = {}; - openssl.system = "mingw"; - is64bit = false; - }; - - pkgs = pkgsFun { - inherit crossSystem; - }; - -in -rec { - inherit pkgs; - - badvpnPkgsFunc = import ./badvpn-win32.nix; - - badvpnPkgs = pkgs.callPackage badvpnPkgsFunc {}; - badvpnDebugPkgs = pkgs.callPackage badvpnPkgsFunc { debug = true; }; -} diff --git a/v2rayng/badvpn/build.nix b/v2rayng/badvpn/build.nix deleted file mode 100644 index 8589ea2b37..0000000000 --- a/v2rayng/badvpn/build.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ pkgs ? (import {}) }: -with pkgs; -rec { - badvpnFunc = import ./badvpn.nix; - badvpn = pkgs.callPackage badvpnFunc {}; - badvpnDebug = pkgs.callPackage badvpnFunc { debug = true; }; -} diff --git a/v2rayng/badvpn/client/CMakeLists.txt b/v2rayng/badvpn/client/CMakeLists.txt deleted file mode 100644 index 1ea9e7e7b3..0000000000 --- a/v2rayng/badvpn/client/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -add_executable(badvpn-client - client.c - StreamPeerIO.c - DatagramPeerIO.c - PasswordListener.c - DataProto.c - FrameDecider.c - DPRelay.c - DPReceive.c - FragmentProtoDisassembler.c - FragmentProtoAssembler.c - SPProtoEncoder.c - SPProtoDecoder.c - DataProtoKeepaliveSource.c - PeerChat.c - SCOutmsgEncoder.c - SimpleStreamBuffer.c - SinglePacketSource.c -) -target_link_libraries(badvpn-client system flow flowextra tuntap server_conection security threadwork ${NSPR_LIBRARIES} ${NSS_LIBRARIES}) - -install( - TARGETS badvpn-client - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -install( - FILES badvpn-client.8 - DESTINATION ${CMAKE_INSTALL_MANDIR}/man8 -) diff --git a/v2rayng/badvpn/client/DPReceive.c b/v2rayng/badvpn/client/DPReceive.c deleted file mode 100644 index da70c745d9..0000000000 --- a/v2rayng/badvpn/client/DPReceive.c +++ /dev/null @@ -1,324 +0,0 @@ -/** - * @file DPReceive.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -static DPReceivePeer * find_peer (DPReceiveDevice *o, peerid_t id) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->peers_list); node; node = LinkedList1Node_Next(node)) { - DPReceivePeer *p = UPPER_OBJECT(node, DPReceivePeer, list_node); - if (p->peer_id == id) { - return p; - } - } - - return NULL; -} - -static void receiver_recv_handler_send (DPReceiveReceiver *o, uint8_t *packet, int packet_len) -{ - DebugObject_Access(&o->d_obj); - DPReceivePeer *peer = o->peer; - DPReceiveDevice *device = peer->device; - ASSERT(packet_len >= 0) - ASSERT(packet_len <= device->packet_mtu) - - uint8_t *data = packet; - int data_len = packet_len; - - int local = 0; - DPReceivePeer *src_peer; - DPReceivePeer *relay_dest_peer = NULL; - - // check header - if (data_len < sizeof(struct dataproto_header)) { - BLog(BLOG_WARNING, "no dataproto header"); - goto out; - } - struct dataproto_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(header); - data_len -= sizeof(header); - uint8_t flags = ltoh8(header.flags); - peerid_t from_id = ltoh16(header.from_id); - int num_ids = ltoh16(header.num_peer_ids); - - // check destination ID - if (!(num_ids == 0 || num_ids == 1)) { - BLog(BLOG_WARNING, "wrong number of destinations"); - goto out; - } - peerid_t to_id = 0; // to remove warning - if (num_ids == 1) { - if (data_len < sizeof(struct dataproto_peer_id)) { - BLog(BLOG_WARNING, "missing destination"); - goto out; - } - struct dataproto_peer_id id; - memcpy(&id, data, sizeof(id)); - to_id = ltoh16(id.id); - data += sizeof(id); - data_len -= sizeof(id); - } - - // check remaining data - if (data_len > device->device_mtu) { - BLog(BLOG_WARNING, "frame too large"); - goto out; - } - - // inform sink of received packet - if (peer->dp_sink) { - DataProtoSink_Received(peer->dp_sink, !!(flags & DATAPROTO_FLAGS_RECEIVING_KEEPALIVES)); - } - - if (num_ids == 1) { - // find source peer - if (!(src_peer = find_peer(device, from_id))) { - BLog(BLOG_INFO, "source peer %d not known", (int)from_id); - goto out; - } - - // is frame for device or another peer? - if (device->have_peer_id && to_id == device->peer_id) { - // let the frame decider analyze the frame - FrameDeciderPeer_Analyze(src_peer->decider_peer, data, data_len); - - // pass frame to device - local = 1; - } else { - // check if relaying is allowed - if (!peer->is_relay_client) { - BLog(BLOG_WARNING, "relaying not allowed"); - goto out; - } - - // provided source ID must be the peer sending the frame - if (src_peer != peer) { - BLog(BLOG_WARNING, "relay source must be the sending peer"); - goto out; - } - - // find destination peer - DPReceivePeer *dest_peer = find_peer(device, to_id); - if (!dest_peer) { - BLog(BLOG_INFO, "relay destination peer not known"); - goto out; - } - - // destination cannot be source - if (dest_peer == src_peer) { - BLog(BLOG_WARNING, "relay destination cannot be the source"); - goto out; - } - - relay_dest_peer = dest_peer; - } - } - -out: - // accept packet - PacketPassInterface_Done(&o->recv_if); - - // pass packet to device - if (local) { - o->device->output_func(o->device->output_func_user, data, data_len); - } - - // relay frame - if (relay_dest_peer) { - DPRelayRouter_SubmitFrame(&device->relay_router, &src_peer->relay_source, &relay_dest_peer->relay_sink, data, data_len, device->relay_flow_buffer_size, device->relay_flow_inactivity_time); - } -} - -int DPReceiveDevice_Init (DPReceiveDevice *o, int device_mtu, DPReceiveDevice_output_func output_func, void *output_func_user, BReactor *reactor, int relay_flow_buffer_size, int relay_flow_inactivity_time) -{ - ASSERT(device_mtu >= 0) - ASSERT(device_mtu <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - ASSERT(output_func) - ASSERT(relay_flow_buffer_size > 0) - - // init arguments - o->device_mtu = device_mtu; - o->output_func = output_func; - o->output_func_user = output_func_user; - o->reactor = reactor; - o->relay_flow_buffer_size = relay_flow_buffer_size; - o->relay_flow_inactivity_time = relay_flow_inactivity_time; - - // remember packet MTU - o->packet_mtu = DATAPROTO_MAX_OVERHEAD + o->device_mtu; - - // init relay router - if (!DPRelayRouter_Init(&o->relay_router, o->device_mtu, o->reactor)) { - BLog(BLOG_ERROR, "DPRelayRouter_Init failed"); - goto fail0; - } - - // have no peer ID - o->have_peer_id = 0; - - // init peers list - LinkedList1_Init(&o->peers_list); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void DPReceiveDevice_Free (DPReceiveDevice *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(LinkedList1_IsEmpty(&o->peers_list)) - - // free relay router - DPRelayRouter_Free(&o->relay_router); -} - -void DPReceiveDevice_SetPeerID (DPReceiveDevice *o, peerid_t peer_id) -{ - DebugObject_Access(&o->d_obj); - - // remember peer ID - o->peer_id = peer_id; - o->have_peer_id = 1; -} - -void DPReceivePeer_Init (DPReceivePeer *o, DPReceiveDevice *device, peerid_t peer_id, FrameDeciderPeer *decider_peer, int is_relay_client) -{ - DebugObject_Access(&device->d_obj); - ASSERT(is_relay_client == 0 || is_relay_client == 1) - - // init arguments - o->device = device; - o->peer_id = peer_id; - o->decider_peer = decider_peer; - o->is_relay_client = is_relay_client; - - // init relay source - DPRelaySource_Init(&o->relay_source, &device->relay_router, o->peer_id, device->reactor); - - // init relay sink - DPRelaySink_Init(&o->relay_sink, o->peer_id); - - // have no sink - o->dp_sink = NULL; - - // insert to peers list - LinkedList1_Append(&device->peers_list, &o->list_node); - - DebugCounter_Init(&o->d_receivers_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPReceivePeer_Free (DPReceivePeer *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_receivers_ctr); - ASSERT(!o->dp_sink) - - // remove from peers list - LinkedList1_Remove(&o->device->peers_list, &o->list_node); - - // free relay sink - DPRelaySink_Free(&o->relay_sink); - - // free relay source - DPRelaySource_Free(&o->relay_source); -} - -void DPReceivePeer_AttachSink (DPReceivePeer *o, DataProtoSink *dp_sink) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->dp_sink) - ASSERT(dp_sink) - - // attach relay sink - DPRelaySink_Attach(&o->relay_sink, dp_sink); - - o->dp_sink = dp_sink; -} - -void DPReceivePeer_DetachSink (DPReceivePeer *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->dp_sink) - - // detach relay sink - DPRelaySink_Detach(&o->relay_sink); - - o->dp_sink = NULL; -} - -void DPReceiveReceiver_Init (DPReceiveReceiver *o, DPReceivePeer *peer) -{ - DebugObject_Access(&peer->d_obj); - DPReceiveDevice *device = peer->device; - - // init arguments - o->peer = peer; - - // remember device - o->device = device; - - // init receive interface - PacketPassInterface_Init(&o->recv_if, device->packet_mtu, (PacketPassInterface_handler_send)receiver_recv_handler_send, o, BReactor_PendingGroup(device->reactor)); - - DebugCounter_Increment(&peer->d_receivers_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPReceiveReceiver_Free (DPReceiveReceiver *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->peer->d_receivers_ctr); - - // free receive interface - PacketPassInterface_Free(&o->recv_if); -} - -PacketPassInterface * DPReceiveReceiver_GetInput (DPReceiveReceiver *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->recv_if; -} diff --git a/v2rayng/badvpn/client/DPReceive.h b/v2rayng/badvpn/client/DPReceive.h deleted file mode 100644 index ecc5a05a5f..0000000000 --- a/v2rayng/badvpn/client/DPReceive.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file DPReceive.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Receive processing for the VPN client. - */ - -#ifndef BADVPN_CLIENT_DPRECEIVE_H -#define BADVPN_CLIENT_DPRECEIVE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -typedef void (*DPReceiveDevice_output_func) (void *output_user, uint8_t *data, int data_len); - -struct DPReceiveReceiver_s; - -typedef struct { - int device_mtu; - DPReceiveDevice_output_func output_func; - void *output_func_user; - BReactor *reactor; - int relay_flow_buffer_size; - int relay_flow_inactivity_time; - int packet_mtu; - DPRelayRouter relay_router; - int have_peer_id; - peerid_t peer_id; - LinkedList1 peers_list; - DebugObject d_obj; -} DPReceiveDevice; - -typedef struct { - DPReceiveDevice *device; - peerid_t peer_id; - FrameDeciderPeer *decider_peer; - int is_relay_client; - DPRelaySource relay_source; - DPRelaySink relay_sink; - DataProtoSink *dp_sink; - LinkedList1Node list_node; - DebugObject d_obj; - DebugCounter d_receivers_ctr; -} DPReceivePeer; - -typedef struct DPReceiveReceiver_s { - DPReceivePeer *peer; - DPReceiveDevice *device; - PacketPassInterface recv_if; - DebugObject d_obj; -} DPReceiveReceiver; - -int DPReceiveDevice_Init (DPReceiveDevice *o, int device_mtu, DPReceiveDevice_output_func output_func, void *output_func_user, BReactor *reactor, int relay_flow_buffer_size, int relay_flow_inactivity_time) WARN_UNUSED; -void DPReceiveDevice_Free (DPReceiveDevice *o); -void DPReceiveDevice_SetPeerID (DPReceiveDevice *o, peerid_t peer_id); - -void DPReceivePeer_Init (DPReceivePeer *o, DPReceiveDevice *device, peerid_t peer_id, FrameDeciderPeer *decider_peer, int is_relay_client); -void DPReceivePeer_Free (DPReceivePeer *o); -void DPReceivePeer_AttachSink (DPReceivePeer *o, DataProtoSink *dp_sink); -void DPReceivePeer_DetachSink (DPReceivePeer *o); - -void DPReceiveReceiver_Init (DPReceiveReceiver *o, DPReceivePeer *peer); -void DPReceiveReceiver_Free (DPReceiveReceiver *o); -PacketPassInterface * DPReceiveReceiver_GetInput (DPReceiveReceiver *o); - -#endif diff --git a/v2rayng/badvpn/client/DPRelay.c b/v2rayng/badvpn/client/DPRelay.c deleted file mode 100644 index 983e3ad328..0000000000 --- a/v2rayng/badvpn/client/DPRelay.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - * @file DPRelay.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -#include - -#include - -static void flow_inactivity_handler (struct DPRelay_flow *flow); - -static struct DPRelay_flow * create_flow (DPRelaySource *src, DPRelaySink *sink, int num_packets, int inactivity_time) -{ - ASSERT(num_packets > 0) - - // allocate structure - struct DPRelay_flow *flow = (struct DPRelay_flow *)malloc(sizeof(*flow)); - if (!flow) { - BLog(BLOG_ERROR, "relay flow %d->%d: malloc failed", (int)src->source_id, (int)sink->dest_id); - goto fail0; - } - - // set src and sink - flow->src = src; - flow->sink = sink; - - // init DataProtoFlow - if (!DataProtoFlow_Init(&flow->dp_flow, &src->router->dp_source, src->source_id, sink->dest_id, num_packets, inactivity_time, flow, (DataProtoFlow_handler_inactivity)flow_inactivity_handler)) { - BLog(BLOG_ERROR, "relay flow %d->%d: DataProtoFlow_Init failed", (int)src->source_id, (int)sink->dest_id); - goto fail1; - } - - // insert to source list - LinkedList1_Append(&src->flows_list, &flow->src_list_node); - - // insert to sink list - LinkedList1_Append(&sink->flows_list, &flow->sink_list_node); - - // attach flow if needed - if (sink->dp_sink) { - DataProtoFlow_Attach(&flow->dp_flow, sink->dp_sink); - } - - BLog(BLOG_INFO, "relay flow %d->%d: created", (int)src->source_id, (int)sink->dest_id); - - return flow; - -fail1: - free(flow); -fail0: - return NULL; -} - -static void free_flow (struct DPRelay_flow *flow) -{ - // detach flow if needed - if (flow->sink->dp_sink) { - DataProtoFlow_Detach(&flow->dp_flow); - } - - // remove posible router reference - if (flow->src->router->current_flow == flow) { - flow->src->router->current_flow = NULL; - } - - // remove from sink list - LinkedList1_Remove(&flow->sink->flows_list, &flow->sink_list_node); - - // remove from source list - LinkedList1_Remove(&flow->src->flows_list, &flow->src_list_node); - - // free DataProtoFlow - DataProtoFlow_Free(&flow->dp_flow); - - // free structore - free(flow); -} - -static void flow_inactivity_handler (struct DPRelay_flow *flow) -{ - BLog(BLOG_INFO, "relay flow %d->%d: timed out", (int)flow->src->source_id, (int)flow->sink->dest_id); - - free_flow(flow); -} - -static struct DPRelay_flow * source_find_flow (DPRelaySource *o, DPRelaySink *sink) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, src_list_node); - ASSERT(flow->src == o) - if (flow->sink == sink) { - return flow; - } - } - - return NULL; -} - -static void router_dp_source_handler (DPRelayRouter *o, const uint8_t *frame, int frame_len) -{ - DebugObject_Access(&o->d_obj); - - if (!o->current_flow) { - return; - } - - // route frame to current flow - DataProtoFlow_Route(&o->current_flow->dp_flow, 0); - - // set no current flow - o->current_flow = NULL; -} - -int DPRelayRouter_Init (DPRelayRouter *o, int frame_mtu, BReactor *reactor) -{ - ASSERT(frame_mtu >= 0) - ASSERT(frame_mtu <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - - // init arguments - o->frame_mtu = frame_mtu; - - // init BufferWriter - BufferWriter_Init(&o->writer, frame_mtu, BReactor_PendingGroup(reactor)); - - // init DataProtoSource - if (!DataProtoSource_Init(&o->dp_source, BufferWriter_GetOutput(&o->writer), (DataProtoSource_handler)router_dp_source_handler, o, reactor)) { - BLog(BLOG_ERROR, "DataProtoSource_Init failed"); - goto fail1; - } - - // have no current flow - o->current_flow = NULL; - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - BufferWriter_Free(&o->writer); - return 0; -} - -void DPRelayRouter_Free (DPRelayRouter *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - ASSERT(!o->current_flow) // have no sources - - // free DataProtoSource - DataProtoSource_Free(&o->dp_source); - - // free BufferWriter - BufferWriter_Free(&o->writer); -} - -void DPRelayRouter_SubmitFrame (DPRelayRouter *o, DPRelaySource *src, DPRelaySink *sink, uint8_t *data, int data_len, int num_packets, int inactivity_time) -{ - DebugObject_Access(&o->d_obj); - DebugObject_Access(&src->d_obj); - DebugObject_Access(&sink->d_obj); - ASSERT(!o->current_flow) - ASSERT(src->router == o) - ASSERT(data_len >= 0) - ASSERT(data_len <= o->frame_mtu) - ASSERT(num_packets > 0) - - // get memory location - uint8_t *out; - if (!BufferWriter_StartPacket(&o->writer, &out)) { - BLog(BLOG_ERROR, "BufferWriter_StartPacket failed for frame %d->%d !?", (int)src->source_id, (int)sink->dest_id); - return; - } - - // write frame - memcpy(out, data, data_len); - - // submit frame - BufferWriter_EndPacket(&o->writer, data_len); - - // get a flow - // this comes _after_ writing the packet, in case flow initialization schedules jobs - struct DPRelay_flow *flow = source_find_flow(src, sink); - if (!flow) { - if (!(flow = create_flow(src, sink, num_packets, inactivity_time))) { - return; - } - } - - // remember flow so we know where to route the frame in router_dp_source_handler - o->current_flow = flow; -} - -void DPRelaySource_Init (DPRelaySource *o, DPRelayRouter *router, peerid_t source_id, BReactor *reactor) -{ - DebugObject_Access(&router->d_obj); - - // init arguments - o->router = router; - o->source_id = source_id; - - // init flows list - LinkedList1_Init(&o->flows_list); - - DebugCounter_Increment(&o->router->d_ctr); - DebugObject_Init(&o->d_obj); -} - -void DPRelaySource_Free (DPRelaySource *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->router->d_ctr); - - // free flows, detaching them if needed - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&o->flows_list)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, src_list_node); - free_flow(flow); - } -} - -void DPRelaySink_Init (DPRelaySink *o, peerid_t dest_id) -{ - // init arguments - o->dest_id = dest_id; - - // init flows list - LinkedList1_Init(&o->flows_list); - - // have no sink - o->dp_sink = NULL; - - DebugObject_Init(&o->d_obj); -} - -void DPRelaySink_Free (DPRelaySink *o) -{ - DebugObject_Free(&o->d_obj); - ASSERT(!o->dp_sink) - - // free flows - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&o->flows_list)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - free_flow(flow); - } -} - -void DPRelaySink_Attach (DPRelaySink *o, DataProtoSink *dp_sink) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->dp_sink) - ASSERT(dp_sink) - - // attach flows - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - DataProtoFlow_Attach(&flow->dp_flow, dp_sink); - } - - // set sink - o->dp_sink = dp_sink; -} - -void DPRelaySink_Detach (DPRelaySink *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->dp_sink) - - // detach flows - for (LinkedList1Node *node = LinkedList1_GetFirst(&o->flows_list); node; node = LinkedList1Node_Next(node)) { - struct DPRelay_flow *flow = UPPER_OBJECT(node, struct DPRelay_flow, sink_list_node); - DataProtoFlow_Detach(&flow->dp_flow); - } - - // set no sink - o->dp_sink = NULL; -} diff --git a/v2rayng/badvpn/client/DPRelay.h b/v2rayng/badvpn/client/DPRelay.h deleted file mode 100644 index c5e16eb4a0..0000000000 --- a/v2rayng/badvpn/client/DPRelay.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file DPRelay.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_CLIENT_DPRELAY_H -#define BADVPN_CLIENT_DPRELAY_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -struct DPRelay_flow; - -typedef struct { - int frame_mtu; - BufferWriter writer; - DataProtoSource dp_source; - struct DPRelay_flow *current_flow; - DebugObject d_obj; - DebugCounter d_ctr; -} DPRelayRouter; - -typedef struct { - DPRelayRouter *router; - peerid_t source_id; - LinkedList1 flows_list; - DebugObject d_obj; -} DPRelaySource; - -typedef struct { - peerid_t dest_id; - LinkedList1 flows_list; - DataProtoSink *dp_sink; - DebugObject d_obj; -} DPRelaySink; - -struct DPRelay_flow { - DPRelaySource *src; - DPRelaySink *sink; - DataProtoFlow dp_flow; - LinkedList1Node src_list_node; - LinkedList1Node sink_list_node; -}; - -int DPRelayRouter_Init (DPRelayRouter *o, int frame_mtu, BReactor *reactor) WARN_UNUSED; -void DPRelayRouter_Free (DPRelayRouter *o); -void DPRelayRouter_SubmitFrame (DPRelayRouter *o, DPRelaySource *src, DPRelaySink *sink, uint8_t *data, int data_len, int num_packets, int inactivity_time); - -void DPRelaySource_Init (DPRelaySource *o, DPRelayRouter *router, peerid_t source_id, BReactor *reactor); -void DPRelaySource_Free (DPRelaySource *o); - -void DPRelaySink_Init (DPRelaySink *o, peerid_t dest_id); -void DPRelaySink_Free (DPRelaySink *o); -void DPRelaySink_Attach (DPRelaySink *o, DataProtoSink *dp_sink); -void DPRelaySink_Detach (DPRelaySink *o); - -#endif diff --git a/v2rayng/badvpn/client/DataProto.c b/v2rayng/badvpn/client/DataProto.c deleted file mode 100644 index 255045a50e..0000000000 --- a/v2rayng/badvpn/client/DataProto.c +++ /dev/null @@ -1,566 +0,0 @@ -/** - * @file DataProto.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -static void monitor_handler (DataProtoSink *o); -static void refresh_up_job (DataProtoSink *o); -static void receive_timer_handler (DataProtoSink *o); -static void notifier_handler (DataProtoSink *o, uint8_t *data, int data_len); -static void up_job_handler (DataProtoSink *o); -static void flow_buffer_free (struct DataProtoFlow_buffer *b); -static void flow_buffer_attach (struct DataProtoFlow_buffer *b, DataProtoSink *sink); -static void flow_buffer_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_schedule_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_finish_detach (struct DataProtoFlow_buffer *b); -static void flow_buffer_qflow_handler_busy (struct DataProtoFlow_buffer *b); - -void monitor_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - - // send keep-alive - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); -} - -void refresh_up_job (DataProtoSink *o) -{ - if (o->up != o->up_report) { - BPending_Set(&o->up_job); - } else { - BPending_Unset(&o->up_job); - } -} - -void receive_timer_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - - // consider down - o->up = 0; - - refresh_up_job(o); -} - -void notifier_handler (DataProtoSink *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= sizeof(struct dataproto_header)) - - int flags = 0; - - // if we are receiving keepalives, set the flag - if (BTimer_IsRunning(&o->receive_timer)) { - flags |= DATAPROTO_FLAGS_RECEIVING_KEEPALIVES; - } - - // modify existing packet here - struct dataproto_header header; - memcpy(&header, data, sizeof(header)); - header.flags = hton8(flags); - memcpy(data, &header, sizeof(header)); -} - -void up_job_handler (DataProtoSink *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up != o->up_report) - - o->up_report = o->up; - - o->handler(o->user, o->up); - return; -} - -void source_router_handler (DataProtoSource *o, uint8_t *buf, int recv_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(buf) - ASSERT(recv_len >= 0) - ASSERT(recv_len <= o->frame_mtu) - - // remember packet - o->current_buf = buf; - o->current_recv_len = recv_len; - - // call handler - o->handler(o->user, buf + DATAPROTO_MAX_OVERHEAD, recv_len); - return; -} - -void flow_buffer_free (struct DataProtoFlow_buffer *b) -{ - ASSERT(!b->sink) - - // free route buffer - RouteBuffer_Free(&b->rbuf); - - // free inactivity monitor - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Free(&b->monitor); - } - - // free connector - PacketPassConnector_Free(&b->connector); - - // free buffer structure - free(b); -} - -void flow_buffer_attach (struct DataProtoFlow_buffer *b, DataProtoSink *sink) -{ - ASSERT(!b->sink) - - // init queue flow - PacketPassFairQueueFlow_Init(&b->sink_qflow, &sink->queue); - - // connect to queue flow - PacketPassConnector_ConnectOutput(&b->connector, PacketPassFairQueueFlow_GetInput(&b->sink_qflow)); - - // set DataProto - b->sink = sink; -} - -void flow_buffer_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - // disconnect from queue flow - PacketPassConnector_DisconnectOutput(&b->connector); - - // free queue flow - PacketPassFairQueueFlow_Free(&b->sink_qflow); - - // clear reference to this buffer in the sink - if (b->sink->detaching_buffer == b) { - b->sink->detaching_buffer = NULL; - } - - // set no DataProto - b->sink = NULL; -} - -void flow_buffer_schedule_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) - ASSERT(!b->sink->detaching_buffer || b->sink->detaching_buffer == b) - - if (b->sink->detaching_buffer == b) { - return; - } - - // request cancel - PacketPassFairQueueFlow_RequestCancel(&b->sink_qflow); - - // set busy handler - PacketPassFairQueueFlow_SetBusyHandler(&b->sink_qflow, (PacketPassFairQueue_handler_busy)flow_buffer_qflow_handler_busy, b); - - // remember this buffer in the sink so it can handle us if it goes away - b->sink->detaching_buffer = b; -} - -void flow_buffer_finish_detach (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(b->sink->detaching_buffer == b) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - // detach - flow_buffer_detach(b); - - if (!b->flow) { - // free - flow_buffer_free(b); - } else if (b->flow->sink_desired) { - // attach - flow_buffer_attach(b, b->flow->sink_desired); - } -} - -void flow_buffer_qflow_handler_busy (struct DataProtoFlow_buffer *b) -{ - ASSERT(b->sink) - ASSERT(b->sink->detaching_buffer == b) - PacketPassFairQueueFlow_AssertFree(&b->sink_qflow); - - flow_buffer_finish_detach(b); -} - -int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface *output, btime_t keepalive_time, btime_t tolerance_time, DataProtoSink_handler handler, void *user) -{ - ASSERT(PacketPassInterface_HasCancel(output)) - ASSERT(PacketPassInterface_GetMTU(output) >= DATAPROTO_MAX_OVERHEAD) - - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // set frame MTU - o->frame_mtu = PacketPassInterface_GetMTU(output) - DATAPROTO_MAX_OVERHEAD; - - // init notifier - PacketPassNotifier_Init(&o->notifier, output, BReactor_PendingGroup(o->reactor)); - PacketPassNotifier_SetHandler(&o->notifier, (PacketPassNotifier_handler_notify)notifier_handler, o); - - // init monitor - PacketPassInactivityMonitor_Init(&o->monitor, PacketPassNotifier_GetInput(&o->notifier), o->reactor, keepalive_time, (PacketPassInactivityMonitor_handler)monitor_handler, o); - PacketPassInactivityMonitor_Force(&o->monitor); - - // init queue - if (!PacketPassFairQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->monitor), BReactor_PendingGroup(o->reactor), 1, 1)) { - BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed"); - goto fail1; - } - - // init keepalive queue flow - PacketPassFairQueueFlow_Init(&o->ka_qflow, &o->queue); - - // init keepalive source - DataProtoKeepaliveSource_Init(&o->ka_source, BReactor_PendingGroup(o->reactor)); - - // init keepalive blocker - PacketRecvBlocker_Init(&o->ka_blocker, DataProtoKeepaliveSource_GetOutput(&o->ka_source), BReactor_PendingGroup(o->reactor)); - - // init keepalive buffer - if (!SinglePacketBuffer_Init(&o->ka_buffer, PacketRecvBlocker_GetOutput(&o->ka_blocker), PacketPassFairQueueFlow_GetInput(&o->ka_qflow), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init receive timer - BTimer_Init(&o->receive_timer, tolerance_time, (BTimer_handler)receive_timer_handler, o); - - // init handler job - BPending_Init(&o->up_job, BReactor_PendingGroup(o->reactor), (BPending_handler)up_job_handler, o); - - // set not up - o->up = 0; - o->up_report = 0; - - // set no detaching buffer - o->detaching_buffer = NULL; - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail2: - PacketRecvBlocker_Free(&o->ka_blocker); - DataProtoKeepaliveSource_Free(&o->ka_source); - PacketPassFairQueueFlow_Free(&o->ka_qflow); - PacketPassFairQueue_Free(&o->queue); -fail1: - PacketPassInactivityMonitor_Free(&o->monitor); - PacketPassNotifier_Free(&o->notifier); - return 0; -} - -void DataProtoSink_Free (DataProtoSink *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - - // allow freeing queue flows - PacketPassFairQueue_PrepareFree(&o->queue); - - // release detaching buffer - if (o->detaching_buffer) { - ASSERT(!o->detaching_buffer->flow || o->detaching_buffer->flow->sink_desired != o) - flow_buffer_finish_detach(o->detaching_buffer); - } - - // free handler job - BPending_Free(&o->up_job); - - // free receive timer - BReactor_RemoveTimer(o->reactor, &o->receive_timer); - - // free keepalive buffer - SinglePacketBuffer_Free(&o->ka_buffer); - - // free keepalive blocker - PacketRecvBlocker_Free(&o->ka_blocker); - - // free keepalive source - DataProtoKeepaliveSource_Free(&o->ka_source); - - // free keepalive queue flow - PacketPassFairQueueFlow_Free(&o->ka_qflow); - - // free queue - PacketPassFairQueue_Free(&o->queue); - - // free monitor - PacketPassInactivityMonitor_Free(&o->monitor); - - // free notifier - PacketPassNotifier_Free(&o->notifier); -} - -void DataProtoSink_Received (DataProtoSink *o, int peer_receiving) -{ - ASSERT(peer_receiving == 0 || peer_receiving == 1) - DebugObject_Access(&o->d_obj); - - // reset receive timer - BReactor_SetTimer(o->reactor, &o->receive_timer); - - if (!peer_receiving) { - // peer reports not receiving, consider down - o->up = 0; - // send keep-alive to converge faster - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); - } else { - // consider up - o->up = 1; - } - - refresh_up_job(o); -} - -int DataProtoSource_Init (DataProtoSource *o, PacketRecvInterface *input, DataProtoSource_handler handler, void *user, BReactor *reactor) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - DATAPROTO_MAX_OVERHEAD) - ASSERT(handler) - - // init arguments - o->handler = handler; - o->user = user; - o->reactor = reactor; - - // remember frame MTU - o->frame_mtu = PacketRecvInterface_GetMTU(input); - - // init router - if (!PacketRouter_Init(&o->router, DATAPROTO_MAX_OVERHEAD + o->frame_mtu, DATAPROTO_MAX_OVERHEAD, input, (PacketRouter_handler)source_router_handler, o, BReactor_PendingGroup(reactor))) { - BLog(BLOG_ERROR, "PacketRouter_Init failed"); - goto fail0; - } - - DebugCounter_Init(&o->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void DataProtoSource_Free (DataProtoSource *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_ctr); - - // free router - PacketRouter_Free(&o->router); -} - -int DataProtoFlow_Init (DataProtoFlow *o, DataProtoSource *source, peerid_t source_id, peerid_t dest_id, int num_packets, int inactivity_time, void *user, - DataProtoFlow_handler_inactivity handler_inactivity) -{ - DebugObject_Access(&source->d_obj); - ASSERT(num_packets > 0) - ASSERT(!(inactivity_time >= 0) || handler_inactivity) - - // init arguments - o->source = source; - o->source_id = source_id; - o->dest_id = dest_id; - - // set no desired sink - o->sink_desired = NULL; - - // allocate buffer structure - struct DataProtoFlow_buffer *b = (struct DataProtoFlow_buffer *)malloc(sizeof(*b)); - if (!b) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - o->b = b; - - // set parent - b->flow = o; - - // remember inactivity time - b->inactivity_time = inactivity_time; - - // init connector - PacketPassConnector_Init(&b->connector, DATAPROTO_MAX_OVERHEAD + source->frame_mtu, BReactor_PendingGroup(source->reactor)); - - // init inactivity monitor - PacketPassInterface *buf_out = PacketPassConnector_GetInput(&b->connector); - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Init(&b->monitor, buf_out, source->reactor, b->inactivity_time, handler_inactivity, user); - buf_out = PacketPassInactivityMonitor_GetInput(&b->monitor); - } - - // init route buffer - if (!RouteBuffer_Init(&b->rbuf, DATAPROTO_MAX_OVERHEAD + source->frame_mtu, buf_out, num_packets)) { - BLog(BLOG_ERROR, "RouteBuffer_Init failed"); - goto fail1; - } - - // set no sink - b->sink = NULL; - - DebugCounter_Increment(&source->d_ctr); - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_Free(&b->monitor); - } - PacketPassConnector_Free(&b->connector); - free(b); -fail0: - return 0; -} - -void DataProtoFlow_Free (DataProtoFlow *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&o->source->d_ctr); - ASSERT(!o->sink_desired) - struct DataProtoFlow_buffer *b = o->b; - - if (b->sink) { - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach, free buffer after detach - flow_buffer_schedule_detach(b); - b->flow = NULL; - - // remove inactivity handler - if (b->inactivity_time >= 0) { - PacketPassInactivityMonitor_SetHandler(&b->monitor, NULL, NULL); - } - } else { - // detach and free buffer now - flow_buffer_detach(b); - flow_buffer_free(b); - } - } else { - // free buffer - flow_buffer_free(b); - } -} - -void DataProtoFlow_Route (DataProtoFlow *o, int more) -{ - DebugObject_Access(&o->d_obj); - PacketRouter_AssertRoute(&o->source->router); - ASSERT(o->source->current_buf) - ASSERT(more == 0 || more == 1) - struct DataProtoFlow_buffer *b = o->b; - - // write header. Don't set flags, it will be set in notifier_handler. - struct dataproto_header header; - struct dataproto_peer_id id; - header.from_id = htol16(o->source_id); - header.num_peer_ids = htol16(1); - id.id = htol16(o->dest_id); - memcpy(o->source->current_buf, &header, sizeof(header)); - memcpy(o->source->current_buf + sizeof(header), &id, sizeof(id)); - - // route - uint8_t *next_buf; - if (!PacketRouter_Route(&o->source->router, DATAPROTO_MAX_OVERHEAD + o->source->current_recv_len, &b->rbuf, - &next_buf, DATAPROTO_MAX_OVERHEAD, (more ? o->source->current_recv_len : 0) - )) { - BLog(BLOG_NOTICE, "buffer full: %d->%d", (int)o->source_id, (int)o->dest_id); - return; - } - - // remember next buffer, or don't allow further routing if more==0 - o->source->current_buf = (more ? next_buf : NULL); -} - -void DataProtoFlow_Attach (DataProtoFlow *o, DataProtoSink *sink) -{ - DebugObject_Access(&o->d_obj); - DebugObject_Access(&sink->d_obj); - ASSERT(!o->sink_desired) - ASSERT(sink) - ASSERT(o->source->frame_mtu <= sink->frame_mtu) - struct DataProtoFlow_buffer *b = o->b; - - if (b->sink) { - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach and reattach - flow_buffer_schedule_detach(b); - } else { - // detach and reattach now - flow_buffer_detach(b); - flow_buffer_attach(b, sink); - } - } else { - // attach - flow_buffer_attach(b, sink); - } - - // set desired sink - o->sink_desired = sink; - - DebugCounter_Increment(&sink->d_ctr); -} - -void DataProtoFlow_Detach (DataProtoFlow *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->sink_desired) - struct DataProtoFlow_buffer *b = o->b; - ASSERT(b->sink) - - DataProtoSink *sink = o->sink_desired; - - if (PacketPassFairQueueFlow_IsBusy(&b->sink_qflow)) { - // schedule detach - flow_buffer_schedule_detach(b); - } else { - // detach now - flow_buffer_detach(b); - } - - // set no desired sink - o->sink_desired = NULL; - - DebugCounter_Decrement(&sink->d_ctr); -} diff --git a/v2rayng/badvpn/client/DataProto.h b/v2rayng/badvpn/client/DataProto.h deleted file mode 100644 index 0da3a20a5a..0000000000 --- a/v2rayng/badvpn/client/DataProto.h +++ /dev/null @@ -1,237 +0,0 @@ -/** - * @file DataProto.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Mudule for frame sending used in the VPN client program. - */ - -#ifndef BADVPN_CLIENT_DATAPROTO_H -#define BADVPN_CLIENT_DATAPROTO_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef void (*DataProtoSink_handler) (void *user, int up); -typedef void (*DataProtoSource_handler) (void *user, const uint8_t *frame, int frame_len); -typedef void (*DataProtoFlow_handler_inactivity) (void *user); - -struct DataProtoFlow_buffer; - -/** - * Frame destination. - * Represents a peer as a destination for sending frames to. - */ -typedef struct { - BReactor *reactor; - int frame_mtu; - PacketPassFairQueue queue; - PacketPassInactivityMonitor monitor; - PacketPassNotifier notifier; - DataProtoKeepaliveSource ka_source; - PacketRecvBlocker ka_blocker; - SinglePacketBuffer ka_buffer; - PacketPassFairQueueFlow ka_qflow; - BTimer receive_timer; - int up; - int up_report; - DataProtoSink_handler handler; - void *user; - BPending up_job; - struct DataProtoFlow_buffer *detaching_buffer; - DebugObject d_obj; - DebugCounter d_ctr; -} DataProtoSink; - -/** - * Receives frames from a {@link PacketRecvInterface} input and - * allows the user to route them to buffers in {@link DataProtoFlow}'s. - */ -typedef struct { - DataProtoSource_handler handler; - void *user; - BReactor *reactor; - int frame_mtu; - PacketRouter router; - uint8_t *current_buf; - int current_recv_len; - DebugObject d_obj; - DebugCounter d_ctr; -} DataProtoSource; - -/** - * Contains a buffer for frames from a specific peer to a specific peer. - * Receives frames from a {@link DataProtoSource} as routed by the user. - * Can be attached to a {@link DataProtoSink} to send out frames. - */ -typedef struct { - DataProtoSource *source; - peerid_t source_id; - peerid_t dest_id; - DataProtoSink *sink_desired; - struct DataProtoFlow_buffer *b; - DebugObject d_obj; -} DataProtoFlow; - -struct DataProtoFlow_buffer { - DataProtoFlow *flow; - int inactivity_time; - RouteBuffer rbuf; - PacketPassInactivityMonitor monitor; - PacketPassConnector connector; - DataProtoSink *sink; - PacketPassFairQueueFlow sink_qflow; -}; - -/** - * Initializes the sink. - * - * @param o the object - * @param reactor reactor we live in - * @param output output interface. Must support cancel functionality. Its MTU must be - * >=DATAPROTO_MAX_OVERHEAD. - * @param keepalive_time keepalive time - * @param tolerance_time after how long of not having received anything from the peer - * to consider the link down - * @param handler up state handler - * @param user value to pass to handler - * @return 1 on success, 0 on failure - */ -int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface *output, btime_t keepalive_time, btime_t tolerance_time, DataProtoSink_handler handler, void *user) WARN_UNUSED; - -/** - * Frees the sink. - * There must be no local sources attached. - * - * @param o the object - */ -void DataProtoSink_Free (DataProtoSink *o); - -/** - * Notifies the sink that a packet was received from the peer. - * Must not be in freeing state. - * - * @param o the object - * @param peer_receiving whether the DATAPROTO_FLAGS_RECEIVING_KEEPALIVES flag was set in the packet. - * Must be 0 or 1. - */ -void DataProtoSink_Received (DataProtoSink *o, int peer_receiving); - -/** - * Initiazes the source. - * - * @param o the object - * @param input frame input. Its input MTU must be <= INT_MAX - DATAPROTO_MAX_OVERHEAD. - * @param handler handler called when a frame arrives to allow the user to route it to - * appropriate {@link DataProtoFlow}'s. - * @param user value passed to handler - * @param reactor reactor we live in - * @return 1 on success, 0 on failure - */ -int DataProtoSource_Init (DataProtoSource *o, PacketRecvInterface *input, DataProtoSource_handler handler, void *user, BReactor *reactor) WARN_UNUSED; - -/** - * Frees the source. - * There must be no {@link DataProtoFlow}'s using this source. - * - * @param o the object - */ -void DataProtoSource_Free (DataProtoSource *o); - -/** - * Initializes the flow. - * The flow is initialized in not attached state. - * - * @param o the object - * @param source source to receive frames from - * @param source_id source peer ID to encode in the headers (i.e. our ID) - * @param dest_id destination peer ID to encode in the headers (i.e. ID if the peer this - * flow belongs to) - * @param num_packets number of packets the buffer should hold. Must be >0. - * @param inactivity_time milliseconds of output inactivity after which to call the - * inactivity handler; <0 to disable. Note that the flow is considered - * active as long as its buffer is non-empty, even if is not attached to - * a {@link DataProtoSink}. - * @param user value to pass to handler - * @param handler_inactivity inactivity handler, if inactivity_time >=0 - * @return 1 on success, 0 on failure - */ -int DataProtoFlow_Init (DataProtoFlow *o, DataProtoSource *source, peerid_t source_id, peerid_t dest_id, int num_packets, int inactivity_time, void *user, - DataProtoFlow_handler_inactivity handler_inactivity) WARN_UNUSED; - -/** - * Frees the flow. - * The flow must be in not attached state. - * - * @param o the object - */ -void DataProtoFlow_Free (DataProtoFlow *o); - -/** - * Routes a frame from the flow's source to this flow. - * Must be called from within the job context of the {@link DataProtoSource_handler} handler. - * Must not be called after this has been called with more=0 for the current frame. - * - * @param o the object - * @param more whether the current frame may have to be routed to more - * flows. If 0, must not be called again until the handler is - * called for the next frame. Must be 0 or 1. - */ -void DataProtoFlow_Route (DataProtoFlow *o, int more); - -/** - * Attaches the flow to a sink. - * The flow must be in not attached state. - * - * @param o the object - * @param sink sink to attach to. This flow's frame_mtu must be <= - * (output MTU of sink) - DATAPROTO_MAX_OVERHEAD. - */ -void DataProtoFlow_Attach (DataProtoFlow *o, DataProtoSink *sink); - -/** - * Detaches the flow from a destination. - * The flow must be in attached state. - * - * @param o the object - */ -void DataProtoFlow_Detach (DataProtoFlow *o); - -#endif diff --git a/v2rayng/badvpn/client/DataProtoKeepaliveSource.c b/v2rayng/badvpn/client/DataProtoKeepaliveSource.c deleted file mode 100644 index 834c42f715..0000000000 --- a/v2rayng/badvpn/client/DataProtoKeepaliveSource.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file DataProtoKeepaliveSource.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "DataProtoKeepaliveSource.h" - -static void output_handler_recv (DataProtoKeepaliveSource *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - struct dataproto_header header; - header.flags = htol8(0); - header.from_id = htol16(0); - header.num_peer_ids = htol16(0); - memcpy(data, &header, sizeof(header)); - - // finish packet - PacketRecvInterface_Done(&o->output, sizeof(struct dataproto_header)); -} - -void DataProtoKeepaliveSource_Init (DataProtoKeepaliveSource *o, BPendingGroup *pg) -{ - // init output - PacketRecvInterface_Init(&o->output, sizeof(struct dataproto_header), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DataProtoKeepaliveSource_Free (DataProtoKeepaliveSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * DataProtoKeepaliveSource_GetOutput (DataProtoKeepaliveSource *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/client/DataProtoKeepaliveSource.h b/v2rayng/badvpn/client/DataProtoKeepaliveSource.h deleted file mode 100644 index 4488e24915..0000000000 --- a/v2rayng/badvpn/client/DataProtoKeepaliveSource.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file DataProtoKeepaliveSource.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketRecvInterface} source which provides DataProto keepalive packets. - */ - -#ifndef BADVPN_DATAPROTOKEEPALIVESOURCE_H -#define BADVPN_DATAPROTOKEEPALIVESOURCE_H - -#include -#include - -/** - * A {@link PacketRecvInterface} source which provides DataProto keepalive packets. - * These packets have no payload, no destination peers and flags zero. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface output; -} DataProtoKeepaliveSource; - -/** - * Initializes the object. - * - * @param o the object - * @param pg pending group - */ -void DataProtoKeepaliveSource_Init (DataProtoKeepaliveSource *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void DataProtoKeepaliveSource_Free (DataProtoKeepaliveSource *o); - -/** - * Returns the output interface. - * The MTU of the output interface will be sizeof(struct dataproto_header). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * DataProtoKeepaliveSource_GetOutput (DataProtoKeepaliveSource *o); - -#endif diff --git a/v2rayng/badvpn/client/DatagramPeerIO.c b/v2rayng/badvpn/client/DatagramPeerIO.c deleted file mode 100644 index e3a8f686a8..0000000000 --- a/v2rayng/badvpn/client/DatagramPeerIO.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @file DatagramPeerIO.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#define DATAGRAMPEERIO_MODE_NONE 0 -#define DATAGRAMPEERIO_MODE_CONNECT 1 -#define DATAGRAMPEERIO_MODE_BIND 2 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void init_io (DatagramPeerIO *o); -static void free_io (DatagramPeerIO *o); -static void dgram_handler (DatagramPeerIO *o, int event); -static void reset_mode (DatagramPeerIO *o); -static void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len); - -void init_io (DatagramPeerIO *o) -{ - // init dgram recv interface - BDatagram_RecvAsync_Init(&o->dgram, o->effective_socket_mtu); - - // connect source - PacketRecvConnector_ConnectInput(&o->recv_connector, BDatagram_RecvAsync_GetIf(&o->dgram)); - - // init dgram send interface - BDatagram_SendAsync_Init(&o->dgram, o->effective_socket_mtu); - - // connect sink - PacketPassConnector_ConnectOutput(&o->send_connector, BDatagram_SendAsync_GetIf(&o->dgram)); -} - -void free_io (DatagramPeerIO *o) -{ - // disconnect sink - PacketPassConnector_DisconnectOutput(&o->send_connector); - - // free dgram send interface - BDatagram_SendAsync_Free(&o->dgram); - - // disconnect source - PacketRecvConnector_DisconnectInput(&o->recv_connector); - - // free dgram recv interface - BDatagram_RecvAsync_Free(&o->dgram); -} - -void dgram_handler (DatagramPeerIO *o, int event) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND) - - PeerLog(o, BLOG_NOTICE, "error"); - - // reset mode - reset_mode(o); - - // report error - if (o->handler_error) { - o->handler_error(o->user); - return; - } -} - -void reset_mode (DatagramPeerIO *o) -{ - ASSERT(o->mode == DATAGRAMPEERIO_MODE_NONE || o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND) - - if (o->mode == DATAGRAMPEERIO_MODE_NONE) { - return; - } - - // remove recv notifier handler - PacketPassNotifier_SetHandler(&o->recv_notifier, NULL, NULL); - - // free I/O - free_io(o); - - // free datagram object - BDatagram_Free(&o->dgram); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_NONE; -} - -void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len) -{ - ASSERT(o->mode == DATAGRAMPEERIO_MODE_BIND) - DebugObject_Access(&o->d_obj); - - // obtain addresses from last received packet - BAddr addr; - BIPAddr local_addr; - ASSERT_EXECUTE(BDatagram_GetLastReceiveAddrs(&o->dgram, &addr, &local_addr)) - - // check address family just in case - if (!BDatagram_AddressFamilySupported(addr.type)) { - PeerLog(o, BLOG_ERROR, "unsupported receive address"); - return; - } - - // update addresses - BDatagram_SetSendAddrs(&o->dgram, addr, local_addr); -} - -int DatagramPeerIO_Init ( - DatagramPeerIO *o, - BReactor *reactor, - int payload_mtu, - int socket_mtu, - struct spproto_security_params sp_params, - btime_t latency, - int num_frames, - PacketPassInterface *recv_userif, - int otp_warning_count, - BThreadWorkDispatcher *twd, - void *user, - BLog_logfunc logfunc, - DatagramPeerIO_handler_error handler_error, - DatagramPeerIO_handler_otp_warning handler_otp_warning, - DatagramPeerIO_handler_otp_ready handler_otp_ready -) -{ - ASSERT(payload_mtu >= 0) - ASSERT(socket_mtu >= 0) - spproto_assert_security_params(sp_params); - ASSERT(num_frames > 0) - ASSERT(PacketPassInterface_GetMTU(recv_userif) >= payload_mtu) - if (SPPROTO_HAVE_OTP(sp_params)) { - ASSERT(otp_warning_count > 0) - ASSERT(otp_warning_count <= sp_params.otp_num) - } - - // set parameters - o->reactor = reactor; - o->payload_mtu = payload_mtu; - o->sp_params = sp_params; - o->user = user; - o->logfunc = logfunc; - o->handler_error = handler_error; - - // check num frames (for FragmentProtoAssembler) - if (num_frames >= FPA_MAX_TIME) { - PeerLog(o, BLOG_ERROR, "num_frames is too big"); - goto fail0; - } - - // check payload MTU (for FragmentProto) - if (o->payload_mtu > UINT16_MAX) { - PeerLog(o, BLOG_ERROR, "payload MTU is too big"); - goto fail0; - } - - // calculate SPProto payload MTU - if ((o->spproto_payload_mtu = spproto_payload_mtu_for_carrier_mtu(o->sp_params, socket_mtu)) <= (int)sizeof(struct fragmentproto_chunk_header)) { - PeerLog(o, BLOG_ERROR, "socket MTU is too small"); - goto fail0; - } - - // calculate effective socket MTU - if ((o->effective_socket_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->spproto_payload_mtu)) < 0) { - PeerLog(o, BLOG_ERROR, "spproto_carrier_mtu_for_payload_mtu failed !?"); - goto fail0; - } - - // init receiving - - // init assembler - if (!FragmentProtoAssembler_Init(&o->recv_assembler, o->spproto_payload_mtu, recv_userif, num_frames, fragmentproto_max_chunks_for_frame(o->spproto_payload_mtu, o->payload_mtu), - BReactor_PendingGroup(o->reactor), o->user, o->logfunc - )) { - PeerLog(o, BLOG_ERROR, "FragmentProtoAssembler_Init failed"); - goto fail0; - } - - // init notifier - PacketPassNotifier_Init(&o->recv_notifier, FragmentProtoAssembler_GetInput(&o->recv_assembler), BReactor_PendingGroup(o->reactor)); - - // init decoder - if (!SPProtoDecoder_Init(&o->recv_decoder, PacketPassNotifier_GetInput(&o->recv_notifier), o->sp_params, 2, BReactor_PendingGroup(o->reactor), twd, o->user, o->logfunc)) { - PeerLog(o, BLOG_ERROR, "SPProtoDecoder_Init failed"); - goto fail1; - } - SPProtoDecoder_SetHandlers(&o->recv_decoder, handler_otp_ready, user); - - // init connector - PacketRecvConnector_Init(&o->recv_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->recv_buffer, PacketRecvConnector_GetOutput(&o->recv_connector), SPProtoDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init sending base - - // init disassembler - FragmentProtoDisassembler_Init(&o->send_disassembler, o->reactor, o->payload_mtu, o->spproto_payload_mtu, -1, latency); - - // init encoder - if (!SPProtoEncoder_Init(&o->send_encoder, FragmentProtoDisassembler_GetOutput(&o->send_disassembler), o->sp_params, otp_warning_count, BReactor_PendingGroup(o->reactor), twd)) { - PeerLog(o, BLOG_ERROR, "SPProtoEncoder_Init failed"); - goto fail3; - } - SPProtoEncoder_SetHandlers(&o->send_encoder, handler_otp_warning, user); - - // init connector - PacketPassConnector_Init(&o->send_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->send_buffer, SPProtoEncoder_GetOutput(&o->send_encoder), PacketPassConnector_GetInput(&o->send_connector), BReactor_PendingGroup(o->reactor))) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail4; - } - - // set mode - o->mode = DATAGRAMPEERIO_MODE_NONE; - - DebugObject_Init(&o->d_obj); - return 1; - -fail4: - PacketPassConnector_Free(&o->send_connector); - SPProtoEncoder_Free(&o->send_encoder); -fail3: - FragmentProtoDisassembler_Free(&o->send_disassembler); - SinglePacketBuffer_Free(&o->recv_buffer); -fail2: - PacketRecvConnector_Free(&o->recv_connector); - SPProtoDecoder_Free(&o->recv_decoder); -fail1: - PacketPassNotifier_Free(&o->recv_notifier); - FragmentProtoAssembler_Free(&o->recv_assembler); -fail0: - return 0; -} - -void DatagramPeerIO_Free (DatagramPeerIO *o) -{ - DebugObject_Free(&o->d_obj); - - // reset mode - reset_mode(o); - - // free sending base - SinglePacketBuffer_Free(&o->send_buffer); - PacketPassConnector_Free(&o->send_connector); - SPProtoEncoder_Free(&o->send_encoder); - FragmentProtoDisassembler_Free(&o->send_disassembler); - - // free receiving - SinglePacketBuffer_Free(&o->recv_buffer); - PacketRecvConnector_Free(&o->recv_connector); - SPProtoDecoder_Free(&o->recv_decoder); - PacketPassNotifier_Free(&o->recv_notifier); - FragmentProtoAssembler_Free(&o->recv_assembler); -} - -PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o) -{ - DebugObject_Access(&o->d_obj); - - return FragmentProtoDisassembler_GetInput(&o->send_disassembler); -} - -int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - - // reset mode - reset_mode(o); - - // check address - if (!BDatagram_AddressFamilySupported(addr.type)) { - PeerLog(o, BLOG_ERROR, "BDatagram_AddressFamilySupported failed"); - goto fail0; - } - - // init dgram - if (!BDatagram_Init(&o->dgram, addr.type, o->reactor, o, (BDatagram_handler)dgram_handler)) { - PeerLog(o, BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // set send address - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, addr, local_addr); - - // init I/O - init_io(o); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_CONNECT; - - return 1; - -fail0: - return 0; -} - -int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr) -{ - DebugObject_Access(&o->d_obj); - ASSERT(BDatagram_AddressFamilySupported(addr.type)) - - // reset mode - reset_mode(o); - - // init dgram - if (!BDatagram_Init(&o->dgram, addr.type, o->reactor, o, (BDatagram_handler)dgram_handler)) { - PeerLog(o, BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // bind dgram - if (!BDatagram_Bind(&o->dgram, addr)) { - PeerLog(o, BLOG_INFO, "BDatagram_Bind failed"); - goto fail1; - } - - // init I/O - init_io(o); - - // set recv notifier handler - PacketPassNotifier_SetHandler(&o->recv_notifier, (PacketPassNotifier_handler_notify)recv_decoder_notifier_handler, o); - - // set mode - o->mode = DATAGRAMPEERIO_MODE_BIND; - - return 1; - -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // set sending key - SPProtoEncoder_SetEncryptionKey(&o->send_encoder, encryption_key); - - // set receiving key - SPProtoDecoder_SetEncryptionKey(&o->recv_decoder, encryption_key); -} - -void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove sending key - SPProtoEncoder_RemoveEncryptionKey(&o->send_encoder); - - // remove receiving key - SPProtoDecoder_RemoveEncryptionKey(&o->recv_decoder); -} - -void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // set sending seed - SPProtoEncoder_SetOTPSeed(&o->send_encoder, seed_id, key, iv); -} - -void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove sending seed - SPProtoEncoder_RemoveOTPSeed(&o->send_encoder); -} - -void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // add receiving seed - SPProtoDecoder_AddOTPSeed(&o->recv_decoder, seed_id, key, iv); -} - -void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remove receiving seeds - SPProtoDecoder_RemoveOTPSeeds(&o->recv_decoder); -} diff --git a/v2rayng/badvpn/client/DatagramPeerIO.h b/v2rayng/badvpn/client/DatagramPeerIO.h deleted file mode 100644 index 5d19b5ac6c..0000000000 --- a/v2rayng/badvpn/client/DatagramPeerIO.h +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file DatagramPeerIO.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object for comminicating with a peer using a datagram socket. - */ - -#ifndef BADVPN_CLIENT_DATAGRAMPEERIO_H -#define BADVPN_CLIENT_DATAGRAMPEERIO_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * Callback function invoked when an error occurs with the peer connection. - * The object has entered default state. - * May be called from within a sending Send call. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_error) (void *user); - -/** - * Handler function invoked when the number of used OTPs has reached - * the specified warning number in {@link DatagramPeerIO_SetOTPWarningHandler}. - * May be called from within a sending Send call. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_otp_warning) (void *user); - -/** - * Handler called when OTP generation for a new receive seed is finished. - * - * @param user as in {@link DatagramPeerIO_SetHandlers} - */ -typedef void (*DatagramPeerIO_handler_otp_ready) (void *user); - -/** - * Object for comminicating with a peer using a datagram socket. - * - * The user provides data for sending to the peer through {@link PacketPassInterface}. - * Received data is provided to the user through {@link PacketPassInterface}. - * - * The object has a logical state called a mode, which is one of the following: - * - default - nothing is send or received - * - connecting - an address was provided by the user for sending datagrams to. - * Datagrams are being sent to that address through a socket, - * and datagrams are being received on the same socket. - * - binding - an address was provided by the user to bind a socket to. - * Datagrams are being received on the socket. Datagrams are not being - * sent initially. When a datagram is received, its source address is - * used as a destination address for sending datagrams. - */ -typedef struct { - DebugObject d_obj; - BReactor *reactor; - int payload_mtu; - struct spproto_security_params sp_params; - void *user; - BLog_logfunc logfunc; - DatagramPeerIO_handler_error handler_error; - int spproto_payload_mtu; - int effective_socket_mtu; - - // sending base - FragmentProtoDisassembler send_disassembler; - SPProtoEncoder send_encoder; - SinglePacketBuffer send_buffer; - PacketPassConnector send_connector; - - // receiving - PacketRecvConnector recv_connector; - SinglePacketBuffer recv_buffer; - SPProtoDecoder recv_decoder; - PacketPassNotifier recv_notifier; - FragmentProtoAssembler recv_assembler; - - // mode - int mode; - - // datagram object - BDatagram dgram; -} DatagramPeerIO; - -/** - * Initializes the object. - * The interface is initialized in default mode. - * {@link BLog_Init} must have been done. - * {@link BNetwork_GlobalInit} must have been done. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param reactor {@link BReactor} we live in - * @param payload_mtu maximum payload size. Must be >=0. - * @param socket_mtu maximum datagram size for the socket. Must be >=0. Must be large enough so it is possible to - * send a FragmentProto chunk with one byte of data over SPProto, i.e. the following has to hold: - * spproto_payload_mtu_for_carrier_mtu(sp_params, socket_mtu) > sizeof(struct fragmentproto_chunk_header) - * @param sp_params SPProto security parameters - * @param latency latency parameter to {@link FragmentProtoDisassembler_Init}. - * @param num_frames num_frames parameter to {@link FragmentProtoAssembler_Init}. Must be >0. - * @param recv_userif interface to pass received packets to the user. Its MTU must be >=payload_mtu. - * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler. - * In this case, must be >0 and <=sp_params.otp_num. - * @param twd thread work dispatcher - * @param user value to pass to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @param handler_error error handler - * @param handler_otp_warning OTP warning handler - * @param handler_otp_ready handler called when OTP generation for a new receive seed is finished - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Init ( - DatagramPeerIO *o, - BReactor *reactor, - int payload_mtu, - int socket_mtu, - struct spproto_security_params sp_params, - btime_t latency, - int num_frames, - PacketPassInterface *recv_userif, - int otp_warning_count, - BThreadWorkDispatcher *twd, - void *user, - BLog_logfunc logfunc, - DatagramPeerIO_handler_error handler_error, - DatagramPeerIO_handler_otp_warning handler_otp_warning, - DatagramPeerIO_handler_otp_ready handler_otp_ready -) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void DatagramPeerIO_Free (DatagramPeerIO *o); - -/** - * Returns an interface the user should use to send packets. - * The OTP warning handler may be called from within Send calls - * to the interface. - * - * @param o the object - * @return sending interface - */ -PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o); - -/** - * Attempts to establish connection to the peer which has bound to an address. - * On success, the interface enters connecting mode. - * On failure, the interface enters default mode. - * - * @param o the object - * @param addr address to send packets to - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr) WARN_UNUSED; - -/** - * Attempts to establish connection to the peer by binding to an address. - * On success, the interface enters connecting mode. - * On failure, the interface enters default mode. - * - * @param o the object - * @param addr address to bind to. Must be supported according to - * {@link BDatagram_AddressFamilySupported}. - * @return 1 on success, 0 on failure - */ -int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr) WARN_UNUSED; - -/** - * Sets the encryption key to use for sending and receiving. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key); - -/** - * Removed the encryption key to use for sending and receiving. - * Encryption must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o); - -/** - * Sets the OTP seed for sending. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes the OTP seed for sending of one is configured. - * OTPs must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o); - -/** - * Adds an OTP seed for reciving. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes all OTP seeds for reciving. - * OTPs must be enabled. - * - * @param o the object - */ -void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o); - -#endif diff --git a/v2rayng/badvpn/client/FragmentProtoAssembler.c b/v2rayng/badvpn/client/FragmentProtoAssembler.c deleted file mode 100644 index 8588c2e7de..0000000000 --- a/v2rayng/badvpn/client/FragmentProtoAssembler.c +++ /dev/null @@ -1,469 +0,0 @@ -/** - * @file FragmentProtoAssembler.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include - -#include "FragmentProtoAssembler.h" - -#include - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -#include "FragmentProtoAssembler_tree.h" -#include - -static void free_frame (FragmentProtoAssembler *o, struct FragmentProtoAssembler_frame *frame) -{ - // remove from used list - LinkedList1_Remove(&o->frames_used, &frame->list_node); - // remove from used tree - FPAFramesTree_Remove(&o->frames_used_tree, 0, frame); - - // append to free list - LinkedList1_Append(&o->frames_free, &frame->list_node); -} - -static void free_oldest_frame (FragmentProtoAssembler *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->frames_used)) - - // obtain oldest frame (first on the list) - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_used); - ASSERT(list_node) - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - - // free frame - free_frame(o, frame); -} - -static struct FragmentProtoAssembler_frame * allocate_new_frame (FragmentProtoAssembler *o, fragmentproto_frameid id) -{ - ASSERT(!FPAFramesTree_LookupExact(&o->frames_used_tree, 0, id)) - - // if there are no free entries, free the oldest used one - if (LinkedList1_IsEmpty(&o->frames_free)) { - PeerLog(o, BLOG_INFO, "freeing used frame"); - free_oldest_frame(o); - } - - // obtain frame entry - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_free); - ASSERT(list_node) - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - - // remove from free list - LinkedList1_Remove(&o->frames_free, &frame->list_node); - - // initialize values - frame->id = id; - frame->time = o->time; - frame->num_chunks = 0; - frame->sum = 0; - frame->length = -1; - frame->length_so_far = 0; - - // append to used list - LinkedList1_Append(&o->frames_used, &frame->list_node); - // insert to used tree - int res = FPAFramesTree_Insert(&o->frames_used_tree, 0, frame, NULL); - ASSERT_EXECUTE(res) - - return frame; -} - -static int chunks_overlap (int c1_start, int c1_len, int c2_start, int c2_len) -{ - return (c1_start + c1_len > c2_start && c2_start + c2_len > c1_start); -} - -static int frame_is_timed_out (FragmentProtoAssembler *o, struct FragmentProtoAssembler_frame *frame) -{ - ASSERT(frame->time <= o->time) - - return (o->time - frame->time > o->time_tolerance); -} - -static void reduce_times (FragmentProtoAssembler *o) -{ - // find the frame with minimal time, removing timed out frames - struct FragmentProtoAssembler_frame *minframe = NULL; - LinkedList1Node *list_node = LinkedList1_GetFirst(&o->frames_used); - while (list_node) { - LinkedList1Node *next = LinkedList1Node_Next(list_node); - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - if (frame_is_timed_out(o, frame)) { - PeerLog(o, BLOG_INFO, "freeing timed out frame (while reducing times)"); - free_frame(o, frame); - } else { - if (!minframe || frame->time < minframe->time) { - minframe = frame; - } - } - list_node = next; - } - - if (!minframe) { - // have no frames, set packet time to zero - o->time = 0; - return; - } - - uint32_t min_time = minframe->time; - - // subtract minimal time from all frames - for (list_node = LinkedList1_GetFirst(&o->frames_used); list_node; list_node = LinkedList1Node_Next(list_node)) { - struct FragmentProtoAssembler_frame *frame = UPPER_OBJECT(list_node, struct FragmentProtoAssembler_frame, list_node); - frame->time -= min_time; - } - - // subtract minimal time from packet time - o->time -= min_time; -} - -static int process_chunk (FragmentProtoAssembler *o, fragmentproto_frameid frame_id, int chunk_start, int chunk_len, int is_last, uint8_t *payload) -{ - ASSERT(chunk_start >= 0) - ASSERT(chunk_len >= 0) - ASSERT(is_last == 0 || is_last == 1) - - // verify chunk - - // check start - if (chunk_start > o->output_mtu) { - PeerLog(o, BLOG_INFO, "chunk starts outside"); - return 0; - } - - // check frame size bound - if (chunk_len > o->output_mtu - chunk_start) { - PeerLog(o, BLOG_INFO, "chunk ends outside"); - return 0; - } - - // calculate end - int chunk_end = chunk_start + chunk_len; - ASSERT(chunk_end >= 0) - ASSERT(chunk_end <= o->output_mtu) - - // lookup frame - struct FragmentProtoAssembler_frame *frame = FPAFramesTree_LookupExact(&o->frames_used_tree, 0, frame_id); - if (!frame) { - // frame not found, add a new one - frame = allocate_new_frame(o, frame_id); - } else { - // have existing frame with that ID - // check frame time - if (frame_is_timed_out(o, frame)) { - // frame is timed out, remove it and use a new one - PeerLog(o, BLOG_INFO, "freeing timed out frame (while processing chunk)"); - free_frame(o, frame); - frame = allocate_new_frame(o, frame_id); - } - } - - ASSERT(frame->num_chunks < o->num_chunks) - - // check if the chunk overlaps with any existing chunks - for (int i = 0; i < frame->num_chunks; i++) { - struct FragmentProtoAssembler_chunk *chunk = &frame->chunks[i]; - if (chunks_overlap(chunk->start, chunk->len, chunk_start, chunk_len)) { - PeerLog(o, BLOG_INFO, "chunk overlaps with existing chunk"); - goto fail_frame; - } - } - - if (is_last) { - // this chunk is marked as last - if (frame->length >= 0) { - PeerLog(o, BLOG_INFO, "got last chunk, but already have one"); - goto fail_frame; - } - // check if frame size according to this packet is consistent - // with existing chunks - if (frame->length_so_far > chunk_end) { - PeerLog(o, BLOG_INFO, "got last chunk, but already have data over its bound"); - goto fail_frame; - } - } else { - // if we have length, chunk must be in its bound - if (frame->length >= 0) { - if (chunk_end > frame->length) { - PeerLog(o, BLOG_INFO, "chunk out of length bound"); - goto fail_frame; - } - } - } - - // chunk is good, add it - - // update frame time - frame->time = o->time; - - // add chunk entry - struct FragmentProtoAssembler_chunk *chunk = &frame->chunks[frame->num_chunks]; - chunk->start = chunk_start; - chunk->len = chunk_len; - frame->num_chunks++; - - // update sum - frame->sum += chunk_len; - - // update length - if (is_last) { - frame->length = chunk_end; - } else { - if (frame->length < 0) { - if (frame->length_so_far < chunk_end) { - frame->length_so_far = chunk_end; - } - } - } - - // copy chunk payload to buffer - memcpy(frame->buffer + chunk_start, payload, chunk_len); - - // is frame incomplete? - if (frame->length < 0 || frame->sum < frame->length) { - // if all chunks are used, fail it - if (frame->num_chunks == o->num_chunks) { - PeerLog(o, BLOG_INFO, "all chunks used, but frame not complete"); - goto fail_frame; - } - - // wait for more chunks - return 0; - } - - ASSERT(frame->sum == frame->length) - - PeerLog(o, BLOG_DEBUG, "frame complete"); - - // free frame entry - free_frame(o, frame); - - // send frame - PacketPassInterface_Sender_Send(o->output, frame->buffer, frame->length); - - return 1; - -fail_frame: - free_frame(o, frame); - return 0; -} - -static void process_input (FragmentProtoAssembler *o) -{ - ASSERT(o->in_len >= 0) - - // read chunks - while (o->in_pos < o->in_len) { - // obtain header - if (o->in_len - o->in_pos < sizeof(struct fragmentproto_chunk_header)) { - PeerLog(o, BLOG_INFO, "too little data for chunk header"); - break; - } - struct fragmentproto_chunk_header header; - memcpy(&header, o->in + o->in_pos, sizeof(header)); - o->in_pos += sizeof(struct fragmentproto_chunk_header); - fragmentproto_frameid frame_id = ltoh16(header.frame_id); - int chunk_start = ltoh16(header.chunk_start); - int chunk_len = ltoh16(header.chunk_len); - int is_last = ltoh8(header.is_last); - - // check is_last field - if (!(is_last == 0 || is_last == 1)) { - PeerLog(o, BLOG_INFO, "chunk is_last wrong"); - break; - } - - // obtain data - if (o->in_len - o->in_pos < chunk_len) { - PeerLog(o, BLOG_INFO, "too little data for chunk data"); - break; - } - - // process chunk - int res = process_chunk(o, frame_id, chunk_start, chunk_len, is_last, o->in + o->in_pos); - o->in_pos += chunk_len; - - if (res) { - // sending complete frame, stop processing input - return; - } - } - - // increment packet time - if (o->time == FPA_MAX_TIME) { - reduce_times(o); - if (!LinkedList1_IsEmpty(&o->frames_used)) { - ASSERT(o->time < FPA_MAX_TIME) // If there was a frame with zero time, it was removed because - // time_tolerance < FPA_MAX_TIME. So something >0 was subtracted. - o->time++; - } else { - // it was set to zero by reduce_times - ASSERT(o->time == 0) - } - } else { - o->time++; - } - - // set no input packet - o->in_len = -1; - - // finish input - PacketPassInterface_Done(&o->input); -} - -static void input_handler_send (FragmentProtoAssembler *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // save input packet - o->in_len = data_len; - o->in = data; - o->in_pos = 0; - - process_input(o); -} - -static void output_handler_done (FragmentProtoAssembler *o) -{ - ASSERT(o->in_len >= 0) - DebugObject_Access(&o->d_obj); - - process_input(o); -} - -int FragmentProtoAssembler_Init (FragmentProtoAssembler *o, int input_mtu, PacketPassInterface *output, int num_frames, int num_chunks, BPendingGroup *pg, void *user, BLog_logfunc logfunc) -{ - ASSERT(input_mtu >= 0) - ASSERT(num_frames > 0) - ASSERT(num_frames < FPA_MAX_TIME) // needed so we can always subtract times when packet time is maximum - ASSERT(num_chunks > 0) - - // init arguments - o->output = output; - o->num_chunks = num_chunks; - o->user = user; - o->logfunc = logfunc; - - // init input - PacketPassInterface_Init(&o->input, input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // remebmer output MTU - o->output_mtu = PacketPassInterface_GetMTU(o->output); - - // set packet time to zero - o->time = 0; - - // set time tolerance to num_frames - o->time_tolerance = num_frames; - - // allocate frames - if (!(o->frames_entries = (struct FragmentProtoAssembler_frame *)BAllocArray(num_frames, sizeof(o->frames_entries[0])))) { - goto fail1; - } - - // allocate chunks - if (!(o->frames_chunks = (struct FragmentProtoAssembler_chunk *)BAllocArray2(num_frames, o->num_chunks, sizeof(o->frames_chunks[0])))) { - goto fail2; - } - - // allocate buffers - if (!(o->frames_buffer = (uint8_t *)BAllocArray(num_frames, o->output_mtu))) { - goto fail3; - } - - // init frame lists - LinkedList1_Init(&o->frames_free); - LinkedList1_Init(&o->frames_used); - - // initialize frame entries - for (int i = 0; i < num_frames; i++) { - struct FragmentProtoAssembler_frame *frame = &o->frames_entries[i]; - // set chunks array pointer - frame->chunks = o->frames_chunks + (size_t)i * o->num_chunks; - // set buffer pointer - frame->buffer = o->frames_buffer + (size_t)i * o->output_mtu; - // add to free list - LinkedList1_Append(&o->frames_free, &frame->list_node); - } - - // init tree - FPAFramesTree_Init(&o->frames_used_tree); - - // have no input packet - o->in_len = -1; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail3: - BFree(o->frames_chunks); -fail2: - BFree(o->frames_entries); -fail1: - PacketPassInterface_Free(&o->input); - return 0; -} - -void FragmentProtoAssembler_Free (FragmentProtoAssembler *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffers - BFree(o->frames_buffer); - - // free chunks - BFree(o->frames_chunks); - - // free frames - BFree(o->frames_entries); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * FragmentProtoAssembler_GetInput (FragmentProtoAssembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/v2rayng/badvpn/client/FragmentProtoAssembler.h b/v2rayng/badvpn/client/FragmentProtoAssembler.h deleted file mode 100644 index bbc5483a4a..0000000000 --- a/v2rayng/badvpn/client/FragmentProtoAssembler.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file FragmentProtoAssembler.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes packets according to FragmentProto. - */ - -#ifndef BADVPN_CLIENT_FRAGMENTPROTOASSEMBLER_H -#define BADVPN_CLIENT_FRAGMENTPROTOASSEMBLER_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define FPA_MAX_TIME UINT32_MAX - -struct FragmentProtoAssembler_frame; - -#include "FragmentProtoAssembler_tree.h" -#include - -struct FragmentProtoAssembler_chunk { - int start; - int len; -}; - -struct FragmentProtoAssembler_frame { - LinkedList1Node list_node; // node in free or used list - struct FragmentProtoAssembler_chunk *chunks; // array of chunks, up to num_chunks - uint8_t *buffer; // buffer with frame data, size output_mtu - // everything below only defined when frame entry is used - fragmentproto_frameid id; // frame identifier - uint32_t time; // packet time when the last chunk was received - FPAFramesTreeNode tree_node; // node fields in tree for searching frames by id - int num_chunks; // number of valid chunks - int sum; // sum of all chunks' lengths - int length; // length of the frame, or -1 if not yet known - int length_so_far; // if length=-1, current data set's upper bound -}; - -/** - * Object which decodes packets according to FragmentProto. - * - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - void *user; - BLog_logfunc logfunc; - PacketPassInterface input; - PacketPassInterface *output; - int output_mtu; - int num_chunks; - uint32_t time; - int time_tolerance; - struct FragmentProtoAssembler_frame *frames_entries; - struct FragmentProtoAssembler_chunk *frames_chunks; - uint8_t *frames_buffer; - LinkedList1 frames_free; - LinkedList1 frames_used; - FPAFramesTree frames_used_tree; - int in_len; - uint8_t *in; - int in_pos; - DebugObject d_obj; -} FragmentProtoAssembler; - -/** - * Initializes the object. - * {@link BLog_Init} must have been done. - * - * @param o the object - * @param input_mtu maximum input packet size. Must be >=0. - * @param output output interface - * @param num_frames number of frames we can hold. Must be >0 and < FPA_MAX_TIME. - * To make the assembler tolerate out-of-order input of degree D, set to D+2. - * Here, D is the minimum size of a hypothetical buffer needed to order the input. - * @param num_chunks maximum number of chunks a frame can come in. Must be >0. - * @param pg pending group - * @param user argument to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int FragmentProtoAssembler_Init (FragmentProtoAssembler *o, int input_mtu, PacketPassInterface *output, int num_frames, int num_chunks, BPendingGroup *pg, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void FragmentProtoAssembler_Free (FragmentProtoAssembler *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * FragmentProtoAssembler_GetInput (FragmentProtoAssembler *o); - -#endif diff --git a/v2rayng/badvpn/client/FragmentProtoAssembler_tree.h b/v2rayng/badvpn/client/FragmentProtoAssembler_tree.h deleted file mode 100644 index 744c63398d..0000000000 --- a/v2rayng/badvpn/client/FragmentProtoAssembler_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FPAFramesTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct FragmentProtoAssembler_frame -#define SAVL_PARAM_TYPE_KEY fragmentproto_frameid -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->id, (entry2)->id) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->id) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/v2rayng/badvpn/client/FragmentProtoDisassembler.c b/v2rayng/badvpn/client/FragmentProtoDisassembler.c deleted file mode 100644 index e67a1dc027..0000000000 --- a/v2rayng/badvpn/client/FragmentProtoDisassembler.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - * @file FragmentProtoDisassembler.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include - -#include "client/FragmentProtoDisassembler.h" - -static void write_chunks (FragmentProtoDisassembler *o) -{ - #define IN_AVAIL (o->in_len - o->in_used) - #define OUT_AVAIL ((o->output_mtu - o->out_used) - (int)sizeof(struct fragmentproto_chunk_header)) - - ASSERT(o->in_len >= 0) - ASSERT(o->out) - ASSERT(OUT_AVAIL > 0) - - // write chunks to output packet - do { - // calculate chunk length - int chunk_len = bmin_int(IN_AVAIL, OUT_AVAIL); - if (o->chunk_mtu > 0) { - chunk_len = bmin_int(chunk_len, o->chunk_mtu); - } - - // write chunk header - struct fragmentproto_chunk_header header; - header.frame_id = htol16(o->frame_id); - header.chunk_start = htol16(o->in_used); - header.chunk_len = htol16(chunk_len); - header.is_last = (chunk_len == IN_AVAIL); - memcpy(o->out + o->out_used, &header, sizeof(header)); - - // write chunk data - memcpy(o->out + o->out_used + sizeof(struct fragmentproto_chunk_header), o->in + o->in_used, chunk_len); - - // increment pointers - o->in_used += chunk_len; - o->out_used += sizeof(struct fragmentproto_chunk_header) + chunk_len; - } while (IN_AVAIL > 0 && OUT_AVAIL > 0); - - // have we finished the input packet? - if (IN_AVAIL == 0) { - // set no input packet - o->in_len = -1; - - // increment frame ID - o->frame_id++; - - // finish input - PacketPassInterface_Done(&o->input); - } - - // should we finish the output packet? - if (OUT_AVAIL <= 0 || o->latency < 0) { - // set no output packet - o->out = NULL; - - // stop timer (if it's running) - if (o->latency >= 0) { - BReactor_RemoveTimer(o->reactor, &o->timer); - } - - // finish output - PacketRecvInterface_Done(&o->output, o->out_used); - } else { - // start timer if we have output and it's not running (output was empty before) - if (!BTimer_IsRunning(&o->timer)) { - BReactor_SetTimer(o->reactor, &o->timer); - } - } -} - -static void input_handler_send (FragmentProtoDisassembler *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(o->in_len == -1) - - // set input packet - o->in_len = data_len; - o->in = data; - o->in_used = 0; - - // if there is no output, wait for it - if (!o->out) { - return; - } - - write_chunks(o); -} - -static void input_handler_requestcancel (FragmentProtoDisassembler *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->out) - - // set no input packet - o->in_len = -1; - - // finish input - PacketPassInterface_Done(&o->input); -} - -static void output_handler_recv (FragmentProtoDisassembler *o, uint8_t *data) -{ - ASSERT(data) - ASSERT(!o->out) - - // set output packet - o->out = data; - o->out_used = 0; - - // if there is no input, wait for it - if (o->in_len < 0) { - return; - } - - write_chunks(o); -} - -static void timer_handler (FragmentProtoDisassembler *o) -{ - ASSERT(o->latency >= 0) - ASSERT(o->out) - ASSERT(o->in_len == -1) - - // set no output packet - o->out = NULL; - - // finish output - PacketRecvInterface_Done(&o->output, o->out_used); -} - -void FragmentProtoDisassembler_Init (FragmentProtoDisassembler *o, BReactor *reactor, int input_mtu, int output_mtu, int chunk_mtu, btime_t latency) -{ - ASSERT(input_mtu >= 0) - ASSERT(input_mtu <= UINT16_MAX) - ASSERT(output_mtu > sizeof(struct fragmentproto_chunk_header)) - ASSERT(chunk_mtu > 0 || chunk_mtu < 0) - - // init arguments - o->reactor = reactor; - o->output_mtu = output_mtu; - o->chunk_mtu = chunk_mtu; - o->latency = latency; - - // init input - PacketPassInterface_Init(&o->input, input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(reactor)); - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, BReactor_PendingGroup(reactor)); - - // init timer - if (o->latency >= 0) { - BTimer_Init(&o->timer, o->latency, (BTimer_handler)timer_handler, o); - } - - // have no input packet - o->in_len = -1; - - // have no output packet - o->out = NULL; - - // start with zero frame ID - o->frame_id = 0; - - DebugObject_Init(&o->d_obj); -} - -void FragmentProtoDisassembler_Free (FragmentProtoDisassembler *o) -{ - DebugObject_Free(&o->d_obj); - - // free timer - if (o->latency >= 0) { - BReactor_RemoveTimer(o->reactor, &o->timer); - } - - // free output - PacketRecvInterface_Free(&o->output); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * FragmentProtoDisassembler_GetInput (FragmentProtoDisassembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -PacketRecvInterface * FragmentProtoDisassembler_GetOutput (FragmentProtoDisassembler *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/client/FragmentProtoDisassembler.h b/v2rayng/badvpn/client/FragmentProtoDisassembler.h deleted file mode 100644 index 49fe9c89d6..0000000000 --- a/v2rayng/badvpn/client/FragmentProtoDisassembler.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file FragmentProtoDisassembler.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets into packets composed of chunks - * according to FragmentProto. - */ - -#ifndef BADVPN_CLIENT_CCPROTODISASSEMBLER_H -#define BADVPN_CLIENT_CCPROTODISASSEMBLER_H - -#include - -#include -#include -#include -#include -#include -#include - -/** - * Object which encodes packets into packets composed of chunks - * according to FragmentProto. - * - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - BReactor *reactor; - int output_mtu; - int chunk_mtu; - btime_t latency; - PacketPassInterface input; - PacketRecvInterface output; - BTimer timer; - int in_len; - uint8_t *in; - int in_used; - uint8_t *out; - int out_used; - fragmentproto_frameid frame_id; - DebugObject d_obj; -} FragmentProtoDisassembler; - -/** - * Initializes the object. - * - * @param o the object - * @param reactor reactor we live in - * @param input_mtu maximum input packet size. Must be >=0 and <=UINT16_MAX. - * @param output_mtu maximum output packet size. Must be >sizeof(struct fragmentproto_chunk_header). - * @param chunk_mtu maximum chunk size. Must be >0, or <0 for no explicit limit. - * @param latency maximum time a pending output packet with some data can wait for more data - * before being sent out. If nonnegative, a timer will be used. If negative, - * packets will always be sent out immediately. If low latency is desired, - * prefer setting this to zero rather than negative. - */ -void FragmentProtoDisassembler_Init (FragmentProtoDisassembler *o, BReactor *reactor, int input_mtu, int output_mtu, int chunk_mtu, btime_t latency); - -/** - * Frees the object. - * - * @param o the object - */ -void FragmentProtoDisassembler_Free (FragmentProtoDisassembler *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * FragmentProtoDisassembler_GetInput (FragmentProtoDisassembler *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * FragmentProtoDisassembler_GetOutput (FragmentProtoDisassembler *o); - -#endif diff --git a/v2rayng/badvpn/client/FrameDecider.c b/v2rayng/badvpn/client/FrameDecider.c deleted file mode 100644 index e7bb4dedfc..0000000000 --- a/v2rayng/badvpn/client/FrameDecider.c +++ /dev/null @@ -1,795 +0,0 @@ -/** - * @file FrameDecider.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define DECIDE_STATE_NONE 1 -#define DECIDE_STATE_UNICAST 2 -#define DECIDE_STATE_FLOOD 3 -#define DECIDE_STATE_MULTICAST 4 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static int compare_macs (const uint8_t *mac1, const uint8_t *mac2) -{ - int c = memcmp(mac1, mac2, 6); - return B_COMPARE(c, 0); -} - -#include "FrameDecider_macs_tree.h" -#include - -#include "FrameDecider_groups_tree.h" -#include - -#include "FrameDecider_multicast_tree.h" -#include - -static void add_mac_to_peer (FrameDeciderPeer *o, uint8_t *mac) -{ - FrameDecider *d = o->d; - - // locate entry in tree - struct _FrameDecider_mac_entry *e_entry = FDMacsTree_LookupExact(&d->macs_tree, 0, mac); - if (e_entry) { - if (e_entry->peer == o) { - // this is our MAC; only move it to the end of the used list - LinkedList1_Remove(&o->mac_entries_used, &e_entry->list_node); - LinkedList1_Append(&o->mac_entries_used, &e_entry->list_node); - return; - } - - // some other peer has that MAC; disassociate it - FDMacsTree_Remove(&d->macs_tree, 0, e_entry); - LinkedList1_Remove(&e_entry->peer->mac_entries_used, &e_entry->list_node); - LinkedList1_Append(&e_entry->peer->mac_entries_free, &e_entry->list_node); - } - - // aquire MAC address entry, if there are no free ones reuse the oldest used one - LinkedList1Node *list_node; - struct _FrameDecider_mac_entry *entry; - if (list_node = LinkedList1_GetFirst(&o->mac_entries_free)) { - entry = UPPER_OBJECT(list_node, struct _FrameDecider_mac_entry, list_node); - ASSERT(entry->peer == o) - - // remove from free - LinkedList1_Remove(&o->mac_entries_free, &entry->list_node); - } else { - list_node = LinkedList1_GetFirst(&o->mac_entries_used); - ASSERT(list_node) - entry = UPPER_OBJECT(list_node, struct _FrameDecider_mac_entry, list_node); - ASSERT(entry->peer == o) - - // remove from used - FDMacsTree_Remove(&d->macs_tree, 0, entry); - LinkedList1_Remove(&o->mac_entries_used, &entry->list_node); - } - - PeerLog(o, BLOG_INFO, "adding MAC %02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8"", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - // set MAC in entry - memcpy(entry->mac, mac, sizeof(entry->mac)); - - // add to used - LinkedList1_Append(&o->mac_entries_used, &entry->list_node); - int res = FDMacsTree_Insert(&d->macs_tree, 0, entry, NULL); - ASSERT_EXECUTE(res) -} - -static uint32_t compute_sig_for_group (uint32_t group) -{ - return hton32(ntoh32(group)&0x7FFFFF); -} - -static uint32_t compute_sig_for_mac (uint8_t *mac) -{ - uint32_t sig; - memcpy(&sig, mac + 2, 4); - sig = hton32(ntoh32(sig)&0x7FFFFF); - return sig; -} - -static void add_to_multicast (FrameDecider *d, struct _FrameDecider_group_entry *group_entry) -{ - // compute sig - uint32_t sig = compute_sig_for_group(group_entry->group); - - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&d->multicast_tree, 0, sig); - if (master) { - // use existing master - ASSERT(master->is_master) - - // set not master - group_entry->is_master = 0; - - // insert to list - LinkedList3Node_InitAfter(&group_entry->sig_list_node, &master->sig_list_node); - } else { - // make this entry master - - // set master - group_entry->is_master = 1; - - // set sig - group_entry->master.sig = sig; - - // insert to multicast tree - int res = FDMulticastTree_Insert(&d->multicast_tree, 0, group_entry, NULL); - ASSERT_EXECUTE(res) - - // init list node - LinkedList3Node_InitLonely(&group_entry->sig_list_node); - } -} - -static void remove_from_multicast (FrameDecider *d, struct _FrameDecider_group_entry *group_entry) -{ - // compute sig - uint32_t sig = compute_sig_for_group(group_entry->group); - - if (group_entry->is_master) { - // remove master from multicast tree - FDMulticastTree_Remove(&d->multicast_tree, 0, group_entry); - - if (!LinkedList3Node_IsLonely(&group_entry->sig_list_node)) { - // at least one more group entry for this sig; make another entry the master - - // get an entry - LinkedList3Node *list_node = LinkedList3Node_NextOrPrev(&group_entry->sig_list_node); - struct _FrameDecider_group_entry *newmaster = UPPER_OBJECT(list_node, struct _FrameDecider_group_entry, sig_list_node); - ASSERT(!newmaster->is_master) - - // set master - newmaster->is_master = 1; - - // set sig - newmaster->master.sig = sig; - - // insert to multicast tree - int res = FDMulticastTree_Insert(&d->multicast_tree, 0, newmaster, NULL); - ASSERT_EXECUTE(res) - } - } - - // free linked list node - LinkedList3Node_Free(&group_entry->sig_list_node); -} - -static void add_group_to_peer (FrameDeciderPeer *o, uint32_t group) -{ - FrameDecider *d = o->d; - - struct _FrameDecider_group_entry *group_entry = FDGroupsTree_LookupExact(&o->groups_tree, 0, group); - if (group_entry) { - // move to end of used list - LinkedList1_Remove(&o->group_entries_used, &group_entry->list_node); - LinkedList1_Append(&o->group_entries_used, &group_entry->list_node); - } else { - PeerLog(o, BLOG_INFO, "joined group %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", - ((uint8_t *)&group)[0], ((uint8_t *)&group)[1], ((uint8_t *)&group)[2], ((uint8_t *)&group)[3] - ); - - // aquire group entry, if there are no free ones reuse the earliest used one - LinkedList1Node *node; - if (node = LinkedList1_GetFirst(&o->group_entries_free)) { - group_entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from free list - LinkedList1_Remove(&o->group_entries_free, &group_entry->list_node); - } else { - node = LinkedList1_GetFirst(&o->group_entries_used); - ASSERT(node) - group_entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from multicast - remove_from_multicast(d, group_entry); - - // remove from peer's groups tree - FDGroupsTree_Remove(&o->groups_tree, 0, group_entry); - - // remove from used list - LinkedList1_Remove(&o->group_entries_used, &group_entry->list_node); - } - - // add entry to used list - LinkedList1_Append(&o->group_entries_used, &group_entry->list_node); - - // set group address - group_entry->group = group; - - // insert to peer's groups tree - int res = FDGroupsTree_Insert(&o->groups_tree, 0, group_entry, NULL); - ASSERT_EXECUTE(res) - - // add to multicast - add_to_multicast(d, group_entry); - } - - // set timer - group_entry->timer_endtime = btime_gettime() + d->igmp_group_membership_interval; - BReactor_SetTimerAbsolute(d->reactor, &group_entry->timer, group_entry->timer_endtime); -} - -static void remove_group_entry (struct _FrameDecider_group_entry *group_entry) -{ - FrameDeciderPeer *peer = group_entry->peer; - FrameDecider *d = peer->d; - - uint32_t group = group_entry->group; - - PeerLog(peer, BLOG_INFO, "left group %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", - ((uint8_t *)&group)[0], ((uint8_t *)&group)[1], ((uint8_t *)&group)[2], ((uint8_t *)&group)[3] - ); - - // remove from multicast - remove_from_multicast(d, group_entry); - - // remove from peer's groups tree - FDGroupsTree_Remove(&peer->groups_tree, 0, group_entry); - - // remove from used list - LinkedList1_Remove(&peer->group_entries_used, &group_entry->list_node); - - // add to free list - LinkedList1_Append(&peer->group_entries_free, &group_entry->list_node); - - // stop timer - BReactor_RemoveTimer(d->reactor, &group_entry->timer); -} - -static void lower_group_timers_to_lmqt (FrameDecider *d, uint32_t group) -{ - // have to lower all the group timers of this group down to LMQT - - // compute sig - uint32_t sig = compute_sig_for_group(group); - - // look up the sig in multicast tree - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&d->multicast_tree, 0, sig); - if (!master) { - return; - } - ASSERT(master->is_master) - - // iterate all group entries with this sig - LinkedList3Iterator it; - LinkedList3Iterator_Init(&it, LinkedList3Node_First(&master->sig_list_node), 1); - LinkedList3Node *sig_list_node; - while (sig_list_node = LinkedList3Iterator_Next(&it)) { - struct _FrameDecider_group_entry *group_entry = UPPER_OBJECT(sig_list_node, struct _FrameDecider_group_entry, sig_list_node); - - // skip wrong groups - if (group_entry->group != group) { - continue; - } - - // lower timer down to LMQT - btime_t now = btime_gettime(); - if (group_entry->timer_endtime > now + d->igmp_last_member_query_time) { - group_entry->timer_endtime = now + d->igmp_last_member_query_time; - BReactor_SetTimerAbsolute(d->reactor, &group_entry->timer, group_entry->timer_endtime); - } - } -} - -static void group_entry_timer_handler (struct _FrameDecider_group_entry *group_entry) -{ - DebugObject_Access(&group_entry->peer->d_obj); - - remove_group_entry(group_entry); -} - -void FrameDecider_Init (FrameDecider *o, int max_peer_macs, int max_peer_groups, btime_t igmp_group_membership_interval, btime_t igmp_last_member_query_time, BReactor *reactor) -{ - ASSERT(max_peer_macs > 0) - ASSERT(max_peer_groups > 0) - - // init arguments - o->max_peer_macs = max_peer_macs; - o->max_peer_groups = max_peer_groups; - o->igmp_group_membership_interval = igmp_group_membership_interval; - o->igmp_last_member_query_time = igmp_last_member_query_time; - o->reactor = reactor; - - // init peers list - LinkedList1_Init(&o->peers_list); - - // init MAC tree - FDMacsTree_Init(&o->macs_tree); - - // init multicast tree - FDMulticastTree_Init(&o->multicast_tree); - - // init decide state - o->decide_state = DECIDE_STATE_NONE; - - // set no current flood peer - o->decide_flood_current = NULL; - - DebugObject_Init(&o->d_obj); -} - -void FrameDecider_Free (FrameDecider *o) -{ - ASSERT(FDMulticastTree_IsEmpty(&o->multicast_tree)) - ASSERT(FDMacsTree_IsEmpty(&o->macs_tree)) - ASSERT(LinkedList1_IsEmpty(&o->peers_list)) - DebugObject_Free(&o->d_obj); -} - -void FrameDecider_AnalyzeAndDecide (FrameDecider *o, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - DebugObject_Access(&o->d_obj); - - // reset decide state - switch (o->decide_state) { - case DECIDE_STATE_NONE: - break; - case DECIDE_STATE_UNICAST: - break; - case DECIDE_STATE_FLOOD: - break; - case DECIDE_STATE_MULTICAST: - LinkedList3Iterator_Free(&o->decide_multicast_it); - return; - default: - ASSERT(0); - } - o->decide_state = DECIDE_STATE_NONE; - o->decide_flood_current = NULL; - - // analyze frame - - const uint8_t *pos = frame; - int len = frame_len; - - if (len < sizeof(struct ethernet_header)) { - return; - } - struct ethernet_header eh; - memcpy(&eh, pos, sizeof(eh)); - pos += sizeof(struct ethernet_header); - len -= sizeof(struct ethernet_header); - - int is_igmp = 0; - - switch (ntoh16(eh.type)) { - case ETHERTYPE_IPV4: { - // check IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check((uint8_t *)pos, len, &ipv4_header, (uint8_t **)&pos, &len)) { - BLog(BLOG_INFO, "decide: wrong IP packet"); - goto out; - } - - // check if it's IGMP - if (ntoh8(ipv4_header.protocol) != IPV4_PROTOCOL_IGMP) { - goto out; - } - - // remember that it's IGMP; we have to flood IGMP frames - is_igmp = 1; - - // check IGMP header - if (len < sizeof(struct igmp_base)) { - BLog(BLOG_INFO, "decide: IGMP: short packet"); - goto out; - } - struct igmp_base igmp_base; - memcpy(&igmp_base, pos, sizeof(igmp_base)); - pos += sizeof(struct igmp_base); - len -= sizeof(struct igmp_base); - - switch (ntoh8(igmp_base.type)) { - case IGMP_TYPE_MEMBERSHIP_QUERY: { - if (len == sizeof(struct igmp_v2_extra) && ntoh8(igmp_base.max_resp_code) != 0) { - // V2 query - struct igmp_v2_extra query; - memcpy(&query, pos, sizeof(query)); - pos += sizeof(struct igmp_v2_extra); - len -= sizeof(struct igmp_v2_extra); - - if (ntoh32(query.group) != 0) { - // got a Group-Specific Query, lower group timers to LMQT - lower_group_timers_to_lmqt(o, query.group); - } - } - else if (len >= sizeof(struct igmp_v3_query_extra)) { - // V3 query - struct igmp_v3_query_extra query; - memcpy(&query, pos, sizeof(query)); - pos += sizeof(struct igmp_v3_query_extra); - len -= sizeof(struct igmp_v3_query_extra); - - // iterate sources - uint16_t num_sources = ntoh16(query.number_of_sources); - int i; - for (i = 0; i < num_sources; i++) { - // check source - if (len < sizeof(struct igmp_source)) { - BLog(BLOG_NOTICE, "decide: IGMP: short source"); - goto out; - } - pos += sizeof(struct igmp_source); - len -= sizeof(struct igmp_source); - } - - if (ntoh32(query.group) != 0 && num_sources == 0) { - // got a Group-Specific Query, lower group timers to LMQT - lower_group_timers_to_lmqt(o, query.group); - } - } - } break; - } - } break; - } - -out:; - - const uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const uint8_t multicast_mac_header[] = {0x01, 0x00, 0x5e}; - - // if it's broadcast or IGMP, flood it - if (is_igmp || !memcmp(eh.dest, broadcast_mac, sizeof(broadcast_mac))) { - o->decide_state = DECIDE_STATE_FLOOD; - o->decide_flood_current = LinkedList1_GetFirst(&o->peers_list); - return; - } - - // if it's multicast, forward to all peers with the given sig - if (!memcmp(eh.dest, multicast_mac_header, sizeof(multicast_mac_header))) { - // extract group's sig from destination MAC - uint32_t sig = compute_sig_for_mac(eh.dest); - - // look up the sig in multicast tree - struct _FrameDecider_group_entry *master = FDMulticastTree_LookupExact(&o->multicast_tree, 0, sig); - if (master) { - ASSERT(master->is_master) - - o->decide_state = DECIDE_STATE_MULTICAST; - LinkedList3Iterator_Init(&o->decide_multicast_it, LinkedList3Node_First(&master->sig_list_node), 1); - } - - return; - } - - // look for MAC entry - struct _FrameDecider_mac_entry *entry = FDMacsTree_LookupExact(&o->macs_tree, 0, eh.dest); - if (entry) { - o->decide_state = DECIDE_STATE_UNICAST; - o->decide_unicast_peer = entry->peer; - return; - } - - // unknown destination MAC, flood - o->decide_state = DECIDE_STATE_FLOOD; - o->decide_flood_current = LinkedList1_GetFirst(&o->peers_list); - return; -} - -FrameDeciderPeer * FrameDecider_NextDestination (FrameDecider *o) -{ - DebugObject_Access(&o->d_obj); - - switch (o->decide_state) { - case DECIDE_STATE_NONE: { - return NULL; - } break; - - case DECIDE_STATE_UNICAST: { - o->decide_state = DECIDE_STATE_NONE; - - return o->decide_unicast_peer; - } break; - - case DECIDE_STATE_FLOOD: { - if (!o->decide_flood_current) { - o->decide_state = DECIDE_STATE_NONE; - return NULL; - } - - LinkedList1Node *list_node = o->decide_flood_current; - o->decide_flood_current = LinkedList1Node_Next(o->decide_flood_current); - - FrameDeciderPeer *peer = UPPER_OBJECT(list_node, FrameDeciderPeer, list_node); - - return peer; - } break; - - case DECIDE_STATE_MULTICAST: { - LinkedList3Node *list_node = LinkedList3Iterator_Next(&o->decide_multicast_it); - if (!list_node) { - o->decide_state = DECIDE_STATE_NONE; - return NULL; - } - struct _FrameDecider_group_entry *group_entry = UPPER_OBJECT(list_node, struct _FrameDecider_group_entry, sig_list_node); - - return group_entry->peer; - } break; - - default: - ASSERT(0); - return NULL; - } -} - -int FrameDeciderPeer_Init (FrameDeciderPeer *o, FrameDecider *d, void *user, BLog_logfunc logfunc) -{ - // init arguments - o->d = d; - o->user = user; - o->logfunc = logfunc; - - // allocate MAC entries - if (!(o->mac_entries = (struct _FrameDecider_mac_entry *)BAllocArray(d->max_peer_macs, sizeof(struct _FrameDecider_mac_entry)))) { - PeerLog(o, BLOG_ERROR, "failed to allocate MAC entries"); - goto fail0; - } - - // allocate group entries - if (!(o->group_entries = (struct _FrameDecider_group_entry *)BAllocArray(d->max_peer_groups, sizeof(struct _FrameDecider_group_entry)))) { - PeerLog(o, BLOG_ERROR, "failed to allocate group entries"); - goto fail1; - } - - // insert to peers list - LinkedList1_Append(&d->peers_list, &o->list_node); - - // init MAC entry lists - LinkedList1_Init(&o->mac_entries_free); - LinkedList1_Init(&o->mac_entries_used); - - // initialize MAC entries - for (int i = 0; i < d->max_peer_macs; i++) { - struct _FrameDecider_mac_entry *entry = &o->mac_entries[i]; - - // set peer - entry->peer = o; - - // insert to free list - LinkedList1_Append(&o->mac_entries_free, &entry->list_node); - } - - // init group entry lists - LinkedList1_Init(&o->group_entries_free); - LinkedList1_Init(&o->group_entries_used); - - // initialize group entries - for (int i = 0; i < d->max_peer_groups; i++) { - struct _FrameDecider_group_entry *entry = &o->group_entries[i]; - - // set peer - entry->peer = o; - - // insert to free list - LinkedList1_Append(&o->group_entries_free, &entry->list_node); - - // init timer - BTimer_Init(&entry->timer, 0, (BTimer_handler)group_entry_timer_handler, entry); - } - - // initialize groups tree - FDGroupsTree_Init(&o->groups_tree); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - BFree(o->mac_entries); -fail0: - return 0; -} - -void FrameDeciderPeer_Free (FrameDeciderPeer *o) -{ - DebugObject_Free(&o->d_obj); - - FrameDecider *d = o->d; - - // remove decide unicast reference - if (d->decide_state == DECIDE_STATE_UNICAST && d->decide_unicast_peer == o) { - d->decide_state = DECIDE_STATE_NONE; - } - - LinkedList1Node *node; - - // free group entries - for (node = LinkedList1_GetFirst(&o->group_entries_used); node; node = LinkedList1Node_Next(node)) { - struct _FrameDecider_group_entry *entry = UPPER_OBJECT(node, struct _FrameDecider_group_entry, list_node); - - // remove from multicast - remove_from_multicast(d, entry); - - // stop timer - BReactor_RemoveTimer(d->reactor, &entry->timer); - } - - // remove used MAC entries from tree - for (node = LinkedList1_GetFirst(&o->mac_entries_used); node; node = LinkedList1Node_Next(node)) { - struct _FrameDecider_mac_entry *entry = UPPER_OBJECT(node, struct _FrameDecider_mac_entry, list_node); - - // remove from tree - FDMacsTree_Remove(&d->macs_tree, 0, entry); - } - - // remove from peers list - if (d->decide_flood_current == &o->list_node) { - d->decide_flood_current = LinkedList1Node_Next(d->decide_flood_current); - } - LinkedList1_Remove(&d->peers_list, &o->list_node); - - // free group entries - BFree(o->group_entries); - - // free MAC entries - BFree(o->mac_entries); -} - -void FrameDeciderPeer_Analyze (FrameDeciderPeer *o, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - DebugObject_Access(&o->d_obj); - - const uint8_t *pos = frame; - int len = frame_len; - - if (len < sizeof(struct ethernet_header)) { - goto out; - } - struct ethernet_header eh; - memcpy(&eh, pos, sizeof(eh)); - pos += sizeof(struct ethernet_header); - len -= sizeof(struct ethernet_header); - - // register source MAC address with this peer - add_mac_to_peer(o, eh.source); - - switch (ntoh16(eh.type)) { - case ETHERTYPE_IPV4: { - // check IPv4 header - struct ipv4_header ipv4_header; - if (!ipv4_check((uint8_t *)pos, len, &ipv4_header, (uint8_t **)&pos, &len)) { - PeerLog(o, BLOG_INFO, "analyze: wrong IP packet"); - goto out; - } - - // check if it's IGMP - if (ntoh8(ipv4_header.protocol) != IPV4_PROTOCOL_IGMP) { - goto out; - } - - // check IGMP header - if (len < sizeof(struct igmp_base)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short packet"); - goto out; - } - struct igmp_base igmp_base; - memcpy(&igmp_base, pos, sizeof(igmp_base)); - pos += sizeof(struct igmp_base); - len -= sizeof(struct igmp_base); - - switch (ntoh8(igmp_base.type)) { - case IGMP_TYPE_V2_MEMBERSHIP_REPORT: { - // check extra - if (len < sizeof(struct igmp_v2_extra)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short v2 report"); - goto out; - } - struct igmp_v2_extra report; - memcpy(&report, pos, sizeof(report)); - pos += sizeof(struct igmp_v2_extra); - len -= sizeof(struct igmp_v2_extra); - - // add to group - add_group_to_peer(o, report.group); - } break; - - case IGMP_TYPE_V3_MEMBERSHIP_REPORT: { - // check extra - if (len < sizeof(struct igmp_v3_report_extra)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short v3 report"); - goto out; - } - struct igmp_v3_report_extra report; - memcpy(&report, pos, sizeof(report)); - pos += sizeof(struct igmp_v3_report_extra); - len -= sizeof(struct igmp_v3_report_extra); - - // iterate records - uint16_t num_records = ntoh16(report.number_of_group_records); - for (int i = 0; i < num_records; i++) { - // check record - if (len < sizeof(struct igmp_v3_report_record)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short record header"); - goto out; - } - struct igmp_v3_report_record record; - memcpy(&record, pos, sizeof(record)); - pos += sizeof(struct igmp_v3_report_record); - len -= sizeof(struct igmp_v3_report_record); - - // iterate sources - uint16_t num_sources = ntoh16(record.number_of_sources); - int j; - for (j = 0; j < num_sources; j++) { - // check source - if (len < sizeof(struct igmp_source)) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short source"); - goto out; - } - pos += sizeof(struct igmp_source); - len -= sizeof(struct igmp_source); - } - - // check aux data - uint16_t aux_len = ntoh16(record.aux_data_len); - if (len < aux_len) { - PeerLog(o, BLOG_INFO, "analyze: IGMP: short record aux data"); - goto out; - } - pos += aux_len; - len -= aux_len; - - switch (record.type) { - case IGMP_RECORD_TYPE_MODE_IS_INCLUDE: - case IGMP_RECORD_TYPE_CHANGE_TO_INCLUDE_MODE: - if (num_sources != 0) { - add_group_to_peer(o, record.group); - } - break; - case IGMP_RECORD_TYPE_MODE_IS_EXCLUDE: - case IGMP_RECORD_TYPE_CHANGE_TO_EXCLUDE_MODE: - add_group_to_peer(o, record.group); - break; - } - } - } break; - } - } break; - } - -out:; -} diff --git a/v2rayng/badvpn/client/FrameDecider.h b/v2rayng/badvpn/client/FrameDecider.h deleted file mode 100644 index f2a29372ca..0000000000 --- a/v2rayng/badvpn/client/FrameDecider.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @file FrameDecider.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Mudule which decides to which peers frames from the device are to be - * forwarded. - */ - -#ifndef BADVPN_CLIENT_FRAMEDECIDER_H -#define BADVPN_CLIENT_FRAMEDECIDER_H - -#include - -#include -#include -#include -#include -#include -#include - -struct _FrameDeciderPeer; -struct _FrameDecider_mac_entry; -struct _FrameDecider_group_entry; - -typedef const uint8_t *FDMacsTree_key; - -#include "FrameDecider_macs_tree.h" -#include - -#include "FrameDecider_groups_tree.h" -#include - -#include "FrameDecider_multicast_tree.h" -#include - -struct _FrameDecider_mac_entry { - struct _FrameDeciderPeer *peer; - LinkedList1Node list_node; // node in FrameDeciderPeer.mac_entries_free or FrameDeciderPeer.mac_entries_used - // defined when used: - uint8_t mac[6]; - FDMacsTreeNode tree_node; // node in FrameDecider.macs_tree, indexed by mac -}; - -struct _FrameDecider_group_entry { - struct _FrameDeciderPeer *peer; - LinkedList1Node list_node; // node in FrameDeciderPeer.group_entries_free or FrameDeciderPeer.group_entries_used - BTimer timer; // timer for removing the group entry, running when used - // defined when used: - // basic group data - uint32_t group; // group address - FDGroupsTreeNode tree_node; // node in FrameDeciderPeer.groups_tree, indexed by group - // all that folows is managed by add_to_multicast() and remove_from_multicast() - LinkedList3Node sig_list_node; // node in list of group entries with the same sig - btime_t timer_endtime; - int is_master; - // defined when used and we are master: - struct { - uint32_t sig; // last 23 bits of group address - FDMulticastTreeNode tree_node; // node in FrameDecider.multicast_tree, indexed by sig - } master; -}; - -/** - * Object that represents a local device. - */ -typedef struct { - int max_peer_macs; - int max_peer_groups; - btime_t igmp_group_membership_interval; - btime_t igmp_last_member_query_time; - BReactor *reactor; - LinkedList1 peers_list; - FDMacsTree macs_tree; - FDMulticastTree multicast_tree; - int decide_state; - LinkedList1Node *decide_flood_current; - struct _FrameDeciderPeer *decide_unicast_peer; - LinkedList3Iterator decide_multicast_it; - DebugObject d_obj; -} FrameDecider; - -/** - * Object that represents a peer that a local device can send frames to. - */ -typedef struct _FrameDeciderPeer { - FrameDecider *d; - void *user; - BLog_logfunc logfunc; - struct _FrameDecider_mac_entry *mac_entries; - struct _FrameDecider_group_entry *group_entries; - LinkedList1Node list_node; // node in FrameDecider.peers_list - LinkedList1 mac_entries_free; - LinkedList1 mac_entries_used; - LinkedList1 group_entries_free; - LinkedList1 group_entries_used; - FDGroupsTree groups_tree; - DebugObject d_obj; -} FrameDeciderPeer; - -/** - * Initializes the object. - * - * @param o the object - * @param max_peer_macs maximum number of MAC addresses a peer may posess. Must be >0. - * @param max_peer_groups maximum number of multicast groups a peer may belong to. Must be >0. - * @param igmp_group_membership_interval IGMP Group Membership Interval value. When a join - * is detected for a peer in {@link FrameDeciderPeer_Analyze}, this is how long we wait - * for another join before we remove the group from the peer. Note that the group may - * be removed sooner if the peer fails to respond to a Group-Specific Query (see below). - * @param igmp_last_member_query_time IGMP Last Member Query Time value. When a Group-Specific - * Query is detected in {@link FrameDecider_AnalyzeAndDecide}, this is how long we wait for a peer - * belonging to the group to send a join before we remove the group from it. - */ -void FrameDecider_Init (FrameDecider *o, int max_peer_macs, int max_peer_groups, btime_t igmp_group_membership_interval, btime_t igmp_last_member_query_time, BReactor *reactor); - -/** - * Frees the object. - * There must be no {@link FrameDeciderPeer} objects using this decider. - * - * @param o the object - */ -void FrameDecider_Free (FrameDecider *o); - -/** - * Analyzes a frame read from the local device and starts deciding which peers - * the frame should be forwarded to. - * - * @param o the object - * @param frame frame data - * @param frame_len frame length. Must be >=0. - */ -void FrameDecider_AnalyzeAndDecide (FrameDecider *o, const uint8_t *frame, int frame_len); - -/** - * Returns the next peer that the frame submitted to {@link FrameDecider_AnalyzeAndDecide} should be - * forwarded to. - * - * @param o the object - * @return peer to forward the frame to, or NULL if no more - */ -FrameDeciderPeer * FrameDecider_NextDestination (FrameDecider *o); - -/** - * Initializes the object. - * - * @param o the object - * @param d decider this peer will belong to - * @param user argument to log function - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int FrameDeciderPeer_Init (FrameDeciderPeer *o, FrameDecider *d, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void FrameDeciderPeer_Free (FrameDeciderPeer *o); - -/** - * Analyzes a frame received from the peer. - * - * @param o the object - * @param frame frame data - * @param frame_len frame length. Must be >=0. - */ -void FrameDeciderPeer_Analyze (FrameDeciderPeer *o, const uint8_t *frame, int frame_len); - -#endif diff --git a/v2rayng/badvpn/client/FrameDecider_groups_tree.h b/v2rayng/badvpn/client/FrameDecider_groups_tree.h deleted file mode 100644 index b52a947ba4..0000000000 --- a/v2rayng/badvpn/client/FrameDecider_groups_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDGroupsTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_group_entry -#define SAVL_PARAM_TYPE_KEY uint32_t -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->group, (entry2)->group) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->group) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/v2rayng/badvpn/client/FrameDecider_macs_tree.h b/v2rayng/badvpn/client/FrameDecider_macs_tree.h deleted file mode 100644 index 21459180a8..0000000000 --- a/v2rayng/badvpn/client/FrameDecider_macs_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDMacsTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_mac_entry -#define SAVL_PARAM_TYPE_KEY FDMacsTree_key -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_macs((entry1)->mac, (entry2)->mac) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) compare_macs((key1), (entry2)->mac) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/v2rayng/badvpn/client/FrameDecider_multicast_tree.h b/v2rayng/badvpn/client/FrameDecider_multicast_tree.h deleted file mode 100644 index 2731684ac7..0000000000 --- a/v2rayng/badvpn/client/FrameDecider_multicast_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME FDMulticastTree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 0 -#define SAVL_PARAM_TYPE_ENTRY struct _FrameDecider_group_entry -#define SAVL_PARAM_TYPE_KEY uint32_t -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->master.sig, (entry2)->master.sig) -#define SAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2)->master.sig) -#define SAVL_PARAM_MEMBER_NODE master.tree_node diff --git a/v2rayng/badvpn/client/PasswordListener.c b/v2rayng/badvpn/client/PasswordListener.c deleted file mode 100644 index e712f5e459..0000000000 --- a/v2rayng/badvpn/client/PasswordListener.c +++ /dev/null @@ -1,374 +0,0 @@ -/** - * @file PasswordListener.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static int password_comparator (void *user, uint64_t *p1, uint64_t *p2); -static void remove_client (struct PasswordListenerClient *client); -static void listener_handler (PasswordListener *l); -static void client_connection_handler (struct PasswordListenerClient *client, int event); -static void client_sslcon_handler (struct PasswordListenerClient *client, int event); -static void client_receiver_handler (struct PasswordListenerClient *client); - -int password_comparator (void *user, uint64_t *p1, uint64_t *p2) -{ - return B_COMPARE(*p1, *p2); -} - -void remove_client (struct PasswordListenerClient *client) -{ - PasswordListener *l = client->l; - - // stop using any buffers before they get freed - if (l->ssl) { - BSSLConnection_ReleaseBuffers(&client->sslcon); - } - - // free receiver - SingleStreamReceiver_Free(&client->receiver); - - // free SSL - if (l->ssl) { - BSSLConnection_Free(&client->sslcon); - ASSERT_FORCE(PR_Close(client->sock->ssl_prfd) == PR_SUCCESS) - } - - // free connection interfaces - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - - // free connection - BConnection_Free(&client->sock->con); - - // free sslsocket structure - free(client->sock); - - // move to free list - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); -} - -void listener_handler (PasswordListener *l) -{ - DebugObject_Access(&l->d_obj); - - // obtain client entry - if (LinkedList1_IsEmpty(&l->clients_free)) { - struct PasswordListenerClient *client = UPPER_OBJECT(LinkedList1_GetFirst(&l->clients_used), struct PasswordListenerClient, list_node); - remove_client(client); - } - struct PasswordListenerClient *client = UPPER_OBJECT(LinkedList1_GetLast(&l->clients_free), struct PasswordListenerClient, list_node); - LinkedList1_Remove(&l->clients_free, &client->list_node); - LinkedList1_Append(&l->clients_used, &client->list_node); - - // allocate sslsocket structure - if (!(client->sock = (sslsocket *)malloc(sizeof(*client->sock)))) { - BLog(BLOG_ERROR, "malloc failedt"); - goto fail0; - } - - // accept connection - if (!BConnection_Init(&client->sock->con, BConnection_source_listener(&l->listener, NULL), l->bsys, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - BLog(BLOG_INFO, "Connection accepted"); - - // init connection interfaces - BConnection_SendAsync_Init(&client->sock->con); - BConnection_RecvAsync_Init(&client->sock->con); - - StreamPassInterface *send_if = BConnection_SendAsync_GetIf(&client->sock->con); - StreamRecvInterface *recv_if = BConnection_RecvAsync_GetIf(&client->sock->con); - - if (l->ssl) { - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&client->sock->bottom_prfd, send_if, recv_if, l->twd, l->ssl_flags)) { - BLog(BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail2; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(client->sock->ssl_prfd = SSL_ImportFD(l->model_prfd, &client->sock->bottom_prfd))) { - ASSERT_FORCE(PR_Close(&client->sock->bottom_prfd) == PR_SUCCESS) - goto fail2; - } - - // set server mode - if (SSL_ResetHandshake(client->sock->ssl_prfd, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail3; - } - - // set require client certificate - if (SSL_OptionSet(client->sock->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed"); - goto fail3; - } - if (SSL_OptionSet(client->sock->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed"); - goto fail3; - } - - // initialize SSLConnection - BSSLConnection_Init(&client->sslcon, client->sock->ssl_prfd, 0, BReactor_PendingGroup(l->bsys), client, (BSSLConnection_handler)client_sslcon_handler); - - send_if = BSSLConnection_GetSendIf(&client->sslcon); - recv_if = BSSLConnection_GetRecvIf(&client->sslcon); - } - - // init receiver - SingleStreamReceiver_Init(&client->receiver, (uint8_t *)&client->recv_buffer, sizeof(client->recv_buffer), recv_if, BReactor_PendingGroup(l->bsys), client, (SingleStreamReceiver_handler)client_receiver_handler); - - return; - - // cleanup on error -fail3: - if (l->ssl) { - ASSERT_FORCE(PR_Close(client->sock->ssl_prfd) == PR_SUCCESS) - } -fail2: - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - BConnection_Free(&client->sock->con); -fail1: - free(client->sock); -fail0: - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); -} - -void client_connection_handler (struct PasswordListenerClient *client, int event) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - BLog(BLOG_INFO, "connection closed"); - } else { - BLog(BLOG_INFO, "connection error"); - } - - remove_client(client); -} - -void client_sslcon_handler (struct PasswordListenerClient *client, int event) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - ASSERT(l->ssl) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - BLog(BLOG_INFO, "SSL error"); - - remove_client(client); -} - -void client_receiver_handler (struct PasswordListenerClient *client) -{ - PasswordListener *l = client->l; - DebugObject_Access(&l->d_obj); - - // check password - uint64_t received_pass = ltoh64(client->recv_buffer); - BAVLNode *pw_tree_node = BAVL_LookupExact(&l->passwords, &received_pass); - if (!pw_tree_node) { - BLog(BLOG_WARNING, "unknown password"); - remove_client(client); - return; - } - PasswordListener_pwentry *pw_entry = UPPER_OBJECT(pw_tree_node, PasswordListener_pwentry, tree_node); - - BLog(BLOG_INFO, "Password recognized"); - - // remove password entry - BAVL_Remove(&l->passwords, &pw_entry->tree_node); - - // stop using any buffers before they get freed - if (l->ssl) { - BSSLConnection_ReleaseBuffers(&client->sslcon); - } - - // free receiver - SingleStreamReceiver_Free(&client->receiver); - - if (l->ssl) { - // free SSL connection - BSSLConnection_Free(&client->sslcon); - } else { - // free connection interfaces - BConnection_RecvAsync_Free(&client->sock->con); - BConnection_SendAsync_Free(&client->sock->con); - } - - // remove connection handler - BConnection_SetHandlers(&client->sock->con, NULL, NULL); - - // move client entry to free list - LinkedList1_Remove(&l->clients_used, &client->list_node); - LinkedList1_Append(&l->clients_free, &client->list_node); - - // give the socket to the handler - pw_entry->handler_client(pw_entry->user, client->sock); - return; -} - -int PasswordListener_Init (PasswordListener *l, BReactor *bsys, BThreadWorkDispatcher *twd, BAddr listen_addr, int max_clients, int ssl, int ssl_flags, CERTCertificate *cert, SECKEYPrivateKey *key) -{ - ASSERT(BConnection_AddressSupported(listen_addr)) - ASSERT(max_clients > 0) - ASSERT(ssl == 0 || ssl == 1) - - // init arguments - l->bsys = bsys; - l->twd = twd; - l->ssl = ssl; - l->ssl_flags = ssl_flags; - - // allocate client entries - if (!(l->clients_data = (struct PasswordListenerClient *)BAllocArray(max_clients, sizeof(struct PasswordListenerClient)))) { - BLog(BLOG_ERROR, "BAllocArray failed"); - goto fail0; - } - - if (l->ssl) { - // initialize model SSL fd - DummyPRFileDesc_Create(&l->model_dprfd); - if (!(l->model_prfd = SSL_ImportFD(NULL, &l->model_dprfd))) { - BLog(BLOG_ERROR, "SSL_ImportFD failed"); - ASSERT_FORCE(PR_Close(&l->model_dprfd) == PR_SUCCESS) - goto fail1; - } - - // set server certificate - if (SSL_ConfigSecureServer(l->model_prfd, cert, key, NSS_FindCertKEAType(cert)) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigSecureServer failed"); - goto fail2; - } - } - - // initialize client entries - LinkedList1_Init(&l->clients_free); - LinkedList1_Init(&l->clients_used); - for (int i = 0; i < max_clients; i++) { - struct PasswordListenerClient *conn = &l->clients_data[i]; - conn->l = l; - LinkedList1_Append(&l->clients_free, &conn->list_node); - } - - // initialize passwords tree - BAVL_Init(&l->passwords, OFFSET_DIFF(PasswordListener_pwentry, password, tree_node), (BAVL_comparator)password_comparator, NULL); - - // initialize listener - if (!BListener_Init(&l->listener, listen_addr, l->bsys, l, (BListener_handler)listener_handler)) { - BLog(BLOG_ERROR, "Listener_Init failed"); - goto fail2; - } - - DebugObject_Init(&l->d_obj); - return 1; - - // cleanup -fail2: - if (l->ssl) { - ASSERT_FORCE(PR_Close(l->model_prfd) == PR_SUCCESS) - } -fail1: - BFree(l->clients_data); -fail0: - return 0; -} - -void PasswordListener_Free (PasswordListener *l) -{ - DebugObject_Free(&l->d_obj); - - // free clients - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&l->clients_used)) { - struct PasswordListenerClient *client = UPPER_OBJECT(node, struct PasswordListenerClient, list_node); - remove_client(client); - } - - // free listener - BListener_Free(&l->listener); - - // free model SSL file descriptor - if (l->ssl) { - ASSERT_FORCE(PR_Close(l->model_prfd) == PR_SUCCESS) - } - - // free client entries - BFree(l->clients_data); -} - -uint64_t PasswordListener_AddEntry (PasswordListener *l, PasswordListener_pwentry *entry, PasswordListener_handler_client handler_client, void *user) -{ - DebugObject_Access(&l->d_obj); - - while (1) { - // generate password - BRandom_randomize((uint8_t *)&entry->password, sizeof(entry->password)); - - // try inserting - if (BAVL_Insert(&l->passwords, &entry->tree_node, NULL)) { - break; - } - } - - entry->handler_client = handler_client; - entry->user = user; - - return entry->password; -} - -void PasswordListener_RemoveEntry (PasswordListener *l, PasswordListener_pwentry *entry) -{ - DebugObject_Access(&l->d_obj); - - // remove - BAVL_Remove(&l->passwords, &entry->tree_node); -} diff --git a/v2rayng/badvpn/client/PasswordListener.h b/v2rayng/badvpn/client/PasswordListener.h deleted file mode 100644 index 70f3ba7cb5..0000000000 --- a/v2rayng/badvpn/client/PasswordListener.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file PasswordListener.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used to listen on a socket, accept clients and identify them - * based on a number they send. - */ - -#ifndef BADVPN_CLIENT_PASSWORDLISTENER_H -#define BADVPN_CLIENT_PASSWORDLISTENER_H - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * Handler function called when a client identifies itself with a password - * belonging to one of the password entries. - * The password entry is unregistered before the handler is called - * and must not be unregistered again. - * - * @param user as in {@link PasswordListener_AddEntry} - * @param sock structure containing a {@link BConnection} and, if TLS is enabled, - * the SSL socket with the bottom layer connected to the async interfaces - * of the {@link BConnection} object. The structure was allocated with - * malloc() and the user is responsible for freeing it. - */ -typedef void (*PasswordListener_handler_client) (void *user, sslsocket *sock); - -struct PasswordListenerClient; - -/** - * Object used to listen on a socket, accept clients and identify them - * based on a number they send. - */ -typedef struct { - BReactor *bsys; - BThreadWorkDispatcher *twd; - int ssl; - int ssl_flags; - PRFileDesc model_dprfd; - PRFileDesc *model_prfd; - struct PasswordListenerClient *clients_data; - LinkedList1 clients_free; - LinkedList1 clients_used; - BAVL passwords; - BListener listener; - DebugObject d_obj; -} PasswordListener; - -typedef struct { - uint64_t password; - BAVLNode tree_node; - PasswordListener_handler_client handler_client; - void *user; -} PasswordListener_pwentry; - -struct PasswordListenerClient { - PasswordListener *l; - LinkedList1Node list_node; - sslsocket *sock; - BSSLConnection sslcon; - SingleStreamReceiver receiver; - uint64_t recv_buffer; -}; - -/** - * Initializes the object. - * - * @param l the object - * @param bsys reactor we live in - * @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL - * operations in threads. - * @param listen_addr address to listen on. Must be supported according to {@link BConnection_AddressSupported}. - * @param max_clients maximum number of client to hold until they are identified. - * Must be >0. - * @param ssl whether to use TLS. Must be 1 or 0. - * @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to - * request performing SSL operations in threads. - * @param cert if using TLS, the server certificate - * @param key if using TLS, the private key - * @return 1 on success, 0 on failure - */ -int PasswordListener_Init (PasswordListener *l, BReactor *bsys, BThreadWorkDispatcher *twd, BAddr listen_addr, int max_clients, int ssl, int ssl_flags, CERTCertificate *cert, SECKEYPrivateKey *key) WARN_UNUSED; - -/** - * Frees the object. - * - * @param l the object - */ -void PasswordListener_Free (PasswordListener *l); - -/** - * Registers a password entry. - * - * @param l the object - * @param entry uninitialized entry structure - * @param handler_client handler function to call when a client identifies - * with the password which this function returns - * @param user value to pass to handler function - * @return password which a client should send to be recognized and - * dispatched to the handler function. Should be treated as a numeric - * value, which a client should as a little-endian 64-bit unsigned integer - * when it connects. - */ -uint64_t PasswordListener_AddEntry (PasswordListener *l, PasswordListener_pwentry *entry, PasswordListener_handler_client handler_client, void *user); - -/** - * Unregisters a password entry. - * Note that when a client is dispatched, its entry is unregistered - * automatically and must not be unregistered again here. - * - * @param l the object - * @param entry entry to unregister - */ -void PasswordListener_RemoveEntry (PasswordListener *l, PasswordListener_pwentry *entry); - -#endif diff --git a/v2rayng/badvpn/client/PeerChat.c b/v2rayng/badvpn/client/PeerChat.c deleted file mode 100644 index a4bd5565e9..0000000000 --- a/v2rayng/badvpn/client/PeerChat.c +++ /dev/null @@ -1,433 +0,0 @@ -/** - * @file PeerChat.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include -#include - -#include "PeerChat.h" - -#include - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void report_error (PeerChat *o) -{ - DebugError_AssertNoError(&o->d_err); - - DEBUGERROR(&o->d_err, o->handler_error(o->user)) - return; -} - -static void recv_job_handler (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv_data_len >= 0) - ASSERT(o->recv_data_len <= SC_MAX_MSGLEN) - - int data_len = o->recv_data_len; - - // set no received data - o->recv_data_len = -1; - -#ifdef PEERCHAT_SIMULATE_ERROR - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < PEERCHAT_SIMULATE_ERROR) { - PeerLog(o, BLOG_ERROR, "simulate error"); - report_error(o); - return; - } -#endif - - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - // buffer data - if (!SimpleStreamBuffer_Write(&o->ssl_recv_buf, o->recv_data, data_len)) { - PeerLog(o, BLOG_ERROR, "out of recv buffer"); - report_error(o); - return; - } - } else { - // call message handler - o->handler_message(o->user, o->recv_data, data_len); - return; - } -} - -static void ssl_con_handler (PeerChat *o, int event) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - PeerLog(o, BLOG_ERROR, "SSL error"); - - report_error(o); - return; -} - -static SECStatus client_auth_data_callback (PeerChat *o, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT) - - CERTCertificate *cert = CERT_DupCertificate(o->ssl_cert); - if (!cert) { - PeerLog(o, BLOG_ERROR, "CERT_DupCertificate failed"); - goto fail0; - } - - SECKEYPrivateKey *key = SECKEY_CopyPrivateKey(o->ssl_key); - if (!key) { - PeerLog(o, BLOG_ERROR, "SECKEY_CopyPrivateKey failed"); - goto fail1; - } - - *pRetCert = cert; - *pRetKey = key; - return SECSuccess; - -fail1: - CERT_DestroyCertificate(cert); -fail0: - return SECFailure; -} - -static SECStatus auth_certificate_callback (PeerChat *o, PRFileDesc *fd, PRBool checkSig, PRBool isServer) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - - // This callback is used to bypass checking the server's domain name, as peers - // don't have domain names. We byte-compare the certificate to the one reported - // by the server anyway. - - SECStatus ret = SECFailure; - - CERTCertificate *cert = SSL_PeerCertificate(o->ssl_prfd); - if (!cert) { - PeerLog(o, BLOG_ERROR, "SSL_PeerCertificate failed"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail1; - } - - SECCertUsage cert_usage = (o->ssl_mode == PEERCHAT_SSL_CLIENT ? certUsageSSLServer : certUsageSSLClient); - - if (CERT_VerifyCertNow(CERT_GetDefaultCertDB(), cert, PR_TRUE, cert_usage, SSL_RevealPinArg(o->ssl_prfd)) != SECSuccess) { - goto fail2; - } - - // compare to certificate provided by the server - SECItem der = cert->derCert; - if (der.len != o->ssl_peer_cert_len || memcmp(der.data, o->ssl_peer_cert, der.len)) { - PeerLog(o, BLOG_ERROR, "peer certificate doesn't match"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail2; - } - - ret = SECSuccess; - -fail2: - CERT_DestroyCertificate(cert); -fail1: - return ret; -} - -static void ssl_recv_if_handler_send (PeerChat *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // accept packet - PacketPassInterface_Done(&o->ssl_recv_if); - - // call message handler - o->handler_message(o->user, data, data_len); - return; -} - -static void ssl_recv_decoder_handler_error (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->ssl_mode == PEERCHAT_SSL_CLIENT || o->ssl_mode == PEERCHAT_SSL_SERVER) - - PeerLog(o, BLOG_ERROR, "decoder error"); - - report_error(o); - return; -} - -int PeerChat_Init (PeerChat *o, peerid_t peer_id, int ssl_mode, int ssl_flags, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key, - uint8_t *ssl_peer_cert, int ssl_peer_cert_len, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, - BLog_logfunc logfunc, - PeerChat_handler_error handler_error, - PeerChat_handler_message handler_message) -{ - ASSERT(ssl_mode == PEERCHAT_SSL_NONE || ssl_mode == PEERCHAT_SSL_CLIENT || ssl_mode == PEERCHAT_SSL_SERVER) - ASSERT(ssl_mode == PEERCHAT_SSL_NONE || ssl_peer_cert_len >= 0) - ASSERT(logfunc) - ASSERT(handler_error) - ASSERT(handler_message) - - // init arguments - o->ssl_mode = ssl_mode; - o->ssl_cert = ssl_cert; - o->ssl_key = ssl_key; - o->ssl_peer_cert = ssl_peer_cert; - o->ssl_peer_cert_len = ssl_peer_cert_len; - o->user = user; - o->logfunc = logfunc; - o->handler_error = handler_error; - o->handler_message = handler_message; - - // init copier - PacketCopier_Init(&o->copier, SC_MAX_MSGLEN, pg); - - // init SC encoder - SCOutmsgEncoder_Init(&o->sc_encoder, peer_id, PacketCopier_GetOutput(&o->copier), pg); - - // init PacketProto encoder - PacketProtoEncoder_Init(&o->pp_encoder, SCOutmsgEncoder_GetOutput(&o->sc_encoder), pg); - - // init recv job - BPending_Init(&o->recv_job, pg, (BPending_handler)recv_job_handler, o); - - // set no received data - o->recv_data_len = -1; - - PacketPassInterface *send_buf_output = PacketCopier_GetInput(&o->copier); - - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - // init receive buffer - if (!SimpleStreamBuffer_Init(&o->ssl_recv_buf, PEERCHAT_SSL_RECV_BUF_SIZE, pg)) { - PeerLog(o, BLOG_ERROR, "SimpleStreamBuffer_Init failed"); - goto fail1; - } - - // init SSL StreamPacketSender - StreamPacketSender_Init(&o->ssl_sp_sender, send_buf_output, pg); - - // init SSL bottom prfd - if (!BSSLConnection_MakeBackend(&o->ssl_bottom_prfd, StreamPacketSender_GetInput(&o->ssl_sp_sender), SimpleStreamBuffer_GetOutput(&o->ssl_recv_buf), twd, ssl_flags)) { - PeerLog(o, BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail2; - } - - // init SSL prfd - if (!(o->ssl_prfd = SSL_ImportFD(NULL, &o->ssl_bottom_prfd))) { - ASSERT_FORCE(PR_Close(&o->ssl_bottom_prfd) == PR_SUCCESS) - PeerLog(o, BLOG_ERROR, "SSL_ImportFD failed"); - goto fail2; - } - - // set client or server mode - if (SSL_ResetHandshake(o->ssl_prfd, (o->ssl_mode == PEERCHAT_SSL_SERVER ? PR_TRUE : PR_FALSE)) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail3; - } - - if (o->ssl_mode == PEERCHAT_SSL_SERVER) { - // set server certificate - if (SSL_ConfigSecureServer(o->ssl_prfd, o->ssl_cert, o->ssl_key, NSS_FindCertKEAType(o->ssl_cert)) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_ConfigSecureServer failed"); - goto fail3; - } - - // set require client certificate - if (SSL_OptionSet(o->ssl_prfd, SSL_REQUEST_CERTIFICATE, PR_TRUE) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_OptionSet(SSL_REQUEST_CERTIFICATE) failed"); - goto fail3; - } - if (SSL_OptionSet(o->ssl_prfd, SSL_REQUIRE_CERTIFICATE, PR_TRUE) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE) failed"); - goto fail3; - } - } else { - // set client certificate callback - if (SSL_GetClientAuthDataHook(o->ssl_prfd, (SSLGetClientAuthData)client_auth_data_callback, o) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail3; - } - } - - // set verify peer certificate hook - if (SSL_AuthCertificateHook(o->ssl_prfd, (SSLAuthCertificate)auth_certificate_callback, o) != SECSuccess) { - PeerLog(o, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail3; - } - - // init SSL connection - BSSLConnection_Init(&o->ssl_con, o->ssl_prfd, 0, pg, o, (BSSLConnection_handler)ssl_con_handler); - - // init SSL PacketStreamSender - PacketStreamSender_Init(&o->ssl_ps_sender, BSSLConnection_GetSendIf(&o->ssl_con), sizeof(struct packetproto_header) + SC_MAX_MSGLEN, pg); - - // init SSL copier - PacketCopier_Init(&o->ssl_copier, SC_MAX_MSGLEN, pg); - - // init SSL encoder - PacketProtoEncoder_Init(&o->ssl_encoder, PacketCopier_GetOutput(&o->ssl_copier), pg); - - // init SSL buffer - if (!SinglePacketBuffer_Init(&o->ssl_buffer, PacketProtoEncoder_GetOutput(&o->ssl_encoder), PacketStreamSender_GetInput(&o->ssl_ps_sender), pg)) { - PeerLog(o, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail4; - } - - // init receive interface - PacketPassInterface_Init(&o->ssl_recv_if, SC_MAX_MSGLEN, (PacketPassInterface_handler_send)ssl_recv_if_handler_send, o, pg); - - // init receive decoder - if (!PacketProtoDecoder_Init(&o->ssl_recv_decoder, BSSLConnection_GetRecvIf(&o->ssl_con), &o->ssl_recv_if, pg, o, (PacketProtoDecoder_handler_error)ssl_recv_decoder_handler_error)) { - PeerLog(o, BLOG_ERROR, "PacketProtoDecoder_Init failed"); - goto fail5; - } - - send_buf_output = PacketCopier_GetInput(&o->ssl_copier); - } - - // init send writer - BufferWriter_Init(&o->send_writer, SC_MAX_MSGLEN, pg); - - // init send buffer - if (!PacketBuffer_Init(&o->send_buf, BufferWriter_GetOutput(&o->send_writer), send_buf_output, PEERCHAT_SEND_BUF_SIZE, pg)) { - PeerLog(o, BLOG_ERROR, "PacketBuffer_Init failed"); - goto fail6; - } - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); - return 1; - -fail6: - BufferWriter_Free(&o->send_writer); - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - PacketProtoDecoder_Free(&o->ssl_recv_decoder); -fail5: - PacketPassInterface_Free(&o->ssl_recv_if); - SinglePacketBuffer_Free(&o->ssl_buffer); -fail4: - PacketProtoEncoder_Free(&o->ssl_encoder); - PacketCopier_Free(&o->ssl_copier); - PacketStreamSender_Free(&o->ssl_ps_sender); - BSSLConnection_Free(&o->ssl_con); -fail3: - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) -fail2: - StreamPacketSender_Free(&o->ssl_sp_sender); - SimpleStreamBuffer_Free(&o->ssl_recv_buf); - } -fail1: - BPending_Free(&o->recv_job); - PacketProtoEncoder_Free(&o->pp_encoder); - SCOutmsgEncoder_Free(&o->sc_encoder); - PacketCopier_Free(&o->copier); - return 0; -} - -void PeerChat_Free (PeerChat *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // stop using any buffers before they get freed - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - BSSLConnection_ReleaseBuffers(&o->ssl_con); - } - - PacketBuffer_Free(&o->send_buf); - BufferWriter_Free(&o->send_writer); - if (o->ssl_mode != PEERCHAT_SSL_NONE) { - PacketProtoDecoder_Free(&o->ssl_recv_decoder); - PacketPassInterface_Free(&o->ssl_recv_if); - SinglePacketBuffer_Free(&o->ssl_buffer); - PacketProtoEncoder_Free(&o->ssl_encoder); - PacketCopier_Free(&o->ssl_copier); - PacketStreamSender_Free(&o->ssl_ps_sender); - BSSLConnection_Free(&o->ssl_con); - ASSERT_FORCE(PR_Close(o->ssl_prfd) == PR_SUCCESS) - StreamPacketSender_Free(&o->ssl_sp_sender); - SimpleStreamBuffer_Free(&o->ssl_recv_buf); - } - BPending_Free(&o->recv_job); - PacketProtoEncoder_Free(&o->pp_encoder); - SCOutmsgEncoder_Free(&o->sc_encoder); - PacketCopier_Free(&o->copier); -} - -PacketRecvInterface * PeerChat_GetSendOutput (PeerChat *o) -{ - DebugObject_Access(&o->d_obj); - - return PacketProtoEncoder_GetOutput(&o->pp_encoder); -} - -void PeerChat_InputReceived (PeerChat *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(o->recv_data_len == -1) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // remember data - o->recv_data = data; - o->recv_data_len = data_len; - - // set received job - BPending_Set(&o->recv_job); -} - -int PeerChat_StartMessage (PeerChat *o, uint8_t **data) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - - return BufferWriter_StartPacket(&o->send_writer, data); -} - -void PeerChat_EndMessage (PeerChat *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - DebugError_AssertNoError(&o->d_err); - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - BufferWriter_EndPacket(&o->send_writer, data_len); -} diff --git a/v2rayng/badvpn/client/PeerChat.h b/v2rayng/badvpn/client/PeerChat.h deleted file mode 100644 index 0b2387e7ea..0000000000 --- a/v2rayng/badvpn/client/PeerChat.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file PeerChat.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_PEERCHAT_H -#define BADVPN_PEERCHAT_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PEERCHAT_SSL_NONE 0 -#define PEERCHAT_SSL_CLIENT 1 -#define PEERCHAT_SSL_SERVER 2 - -#define PEERCHAT_SSL_RECV_BUF_SIZE 4096 -#define PEERCHAT_SEND_BUF_SIZE 200 - -//#define PEERCHAT_SIMULATE_ERROR 40 - -typedef void (*PeerChat_handler_error) (void *user); -typedef void (*PeerChat_handler_message) (void *user, uint8_t *data, int data_len); - -typedef struct { - int ssl_mode; - CERTCertificate *ssl_cert; - SECKEYPrivateKey *ssl_key; - uint8_t *ssl_peer_cert; - int ssl_peer_cert_len; - void *user; - BLog_logfunc logfunc; - PeerChat_handler_error handler_error; - PeerChat_handler_message handler_message; - - // transport - PacketProtoEncoder pp_encoder; - SCOutmsgEncoder sc_encoder; - PacketCopier copier; - BPending recv_job; - uint8_t *recv_data; - int recv_data_len; - - // SSL transport - StreamPacketSender ssl_sp_sender; - SimpleStreamBuffer ssl_recv_buf; - - // SSL connection - PRFileDesc ssl_bottom_prfd; - PRFileDesc *ssl_prfd; - BSSLConnection ssl_con; - - // SSL higher layer - PacketStreamSender ssl_ps_sender; - SinglePacketBuffer ssl_buffer; - PacketProtoEncoder ssl_encoder; - PacketCopier ssl_copier; - PacketProtoDecoder ssl_recv_decoder; - PacketPassInterface ssl_recv_if; - - // higher layer send buffer - PacketBuffer send_buf; - BufferWriter send_writer; - - DebugError d_err; - DebugObject d_obj; -} PeerChat; - -int PeerChat_Init (PeerChat *o, peerid_t peer_id, int ssl_mode, int ssl_flags, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key, - uint8_t *ssl_peer_cert, int ssl_peer_cert_len, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, - BLog_logfunc logfunc, - PeerChat_handler_error handler_error, - PeerChat_handler_message handler_message) WARN_UNUSED; -void PeerChat_Free (PeerChat *o); -PacketRecvInterface * PeerChat_GetSendOutput (PeerChat *o); -void PeerChat_InputReceived (PeerChat *o, uint8_t *data, int data_len); -int PeerChat_StartMessage (PeerChat *o, uint8_t **data) WARN_UNUSED; -void PeerChat_EndMessage (PeerChat *o, int data_len); - -#endif diff --git a/v2rayng/badvpn/client/SCOutmsgEncoder.c b/v2rayng/badvpn/client/SCOutmsgEncoder.c deleted file mode 100644 index 83e8b27cd1..0000000000 --- a/v2rayng/badvpn/client/SCOutmsgEncoder.c +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file SCOutmsgEncoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -#include "SCOutmsgEncoder.h" - -static void output_handler_recv (SCOutmsgEncoder *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->output_packet) - ASSERT(data) - - // schedule receive - o->output_packet = data; - PacketRecvInterface_Receiver_Recv(o->input, o->output_packet + SCOUTMSG_OVERHEAD); -} - -static void input_handler_done (SCOutmsgEncoder *o, int in_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->output_packet) - - // write SC header - struct sc_header header; - header.type = htol8(SCID_OUTMSG); - memcpy(o->output_packet, &header, sizeof(header)); - - // write outmsg - struct sc_client_outmsg outmsg; - outmsg.clientid = htol16(o->peer_id); - memcpy(o->output_packet + sizeof(header), &outmsg, sizeof(outmsg)); - - // finish output packet - o->output_packet = NULL; - PacketRecvInterface_Done(&o->output, SCOUTMSG_OVERHEAD + in_len); -} - -void SCOutmsgEncoder_Init (SCOutmsgEncoder *o, peerid_t peer_id, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - SCOUTMSG_OVERHEAD) - - // init arguments - o->peer_id = peer_id; - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketRecvInterface_Init(&o->output, SCOUTMSG_OVERHEAD + PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no output packet - o->output_packet = NULL; - - DebugObject_Init(&o->d_obj); -} - -void SCOutmsgEncoder_Free (SCOutmsgEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * SCOutmsgEncoder_GetOutput (SCOutmsgEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/client/SCOutmsgEncoder.h b/v2rayng/badvpn/client/SCOutmsgEncoder.h deleted file mode 100644 index 05d4cb2706..0000000000 --- a/v2rayng/badvpn/client/SCOutmsgEncoder.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file SCOutmsgEncoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SCOUTMSGENCODER_H -#define BADVPN_SCOUTMSGENCODER_H - -#include -#include -#include - -#define SCOUTMSG_OVERHEAD (sizeof(struct sc_header) + sizeof(struct sc_client_outmsg)) - -/** - * A {@link PacketRecvInterface} layer which encodes SCProto outgoing messages. - */ -typedef struct { - peerid_t peer_id; - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *output_packet; - DebugObject d_obj; -} SCOutmsgEncoder; - -/** - * Initializes the object. - * - * @param o the object - * @param peer_id destination peer for messages - * @param input input interface. Its MTU muse be <= (INT_MAX - SCOUTMSG_OVERHEAD). - * @param pg pending group we live in - */ -void SCOutmsgEncoder_Init (SCOutmsgEncoder *o, peerid_t peer_id, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SCOutmsgEncoder_Free (SCOutmsgEncoder *o); - -/** - * Returns the output interface. - * The MTU of the interface will be (SCOUTMSG_OVERHEAD + input MTU). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SCOutmsgEncoder_GetOutput (SCOutmsgEncoder *o); - -#endif diff --git a/v2rayng/badvpn/client/SPProtoDecoder.c b/v2rayng/badvpn/client/SPProtoDecoder.c deleted file mode 100644 index 0855162cc0..0000000000 --- a/v2rayng/badvpn/client/SPProtoDecoder.c +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @file SPProtoDecoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "SPProtoDecoder.h" - -#include - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void decode_work_func (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->in_len <= o->input_mtu) - - uint8_t *in = o->in; - int in_len = o->in_len; - - o->tw_out_len = -1; - - uint8_t *plaintext; - int plaintext_len; - - // decrypt if needed - if (!SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - plaintext = in; - plaintext_len = in_len; - } else { - // input must be a multiple of blocks size - if (in_len % o->enc_block_size != 0) { - PeerLog(o, BLOG_WARNING, "packet size not a multiple of block size"); - return; - } - - // input must have an IV block - if (in_len < o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet does not have an IV"); - return; - } - - // check if we have encryption key - if (!o->have_encryption_key) { - PeerLog(o, BLOG_WARNING, "have no encryption key"); - return; - } - - // copy IV as BEncryption_Decrypt changes the IV - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - memcpy(iv, in, o->enc_block_size); - - // decrypt - uint8_t *ciphertext = in + o->enc_block_size; - int ciphertext_len = in_len - o->enc_block_size; - plaintext = o->buf; - BEncryption_Decrypt(&o->encryptor, ciphertext, plaintext, ciphertext_len, iv); - - // read padding - if (ciphertext_len < o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet does not have a padding block"); - return; - } - int i; - for (i = ciphertext_len - 1; i >= ciphertext_len - o->enc_block_size; i--) { - if (plaintext[i] == 1) { - break; - } - if (plaintext[i] != 0) { - PeerLog(o, BLOG_WARNING, "packet padding wrong (nonzero byte)"); - return; - } - } - if (i < ciphertext_len - o->enc_block_size) { - PeerLog(o, BLOG_WARNING, "packet padding wrong (all zeroes)"); - return; - } - plaintext_len = i; - } - - // check for header - if (plaintext_len < SPPROTO_HEADER_LEN(o->sp_params)) { - PeerLog(o, BLOG_WARNING, "packet has no header"); - return; - } - uint8_t *header = plaintext; - - // check data length - if (plaintext_len - SPPROTO_HEADER_LEN(o->sp_params) > o->output_mtu) { - PeerLog(o, BLOG_WARNING, "packet too long"); - return; - } - - // check OTP - if (SPPROTO_HAVE_OTP(o->sp_params)) { - // remember seed and OTP (can't check from here) - struct spproto_otpdata header_otpd; - memcpy(&header_otpd, header + SPPROTO_HEADER_OTPDATA_OFF(o->sp_params), sizeof(header_otpd)); - o->tw_out_seed_id = ltoh16(header_otpd.seed_id); - o->tw_out_otp = header_otpd.otp; - } - - // check hash - if (SPPROTO_HAVE_HASH(o->sp_params)) { - uint8_t *header_hash = header + SPPROTO_HEADER_HASH_OFF(o->sp_params); - // read hash - uint8_t hash[BHASH_MAX_SIZE]; - memcpy(hash, header_hash, o->hash_size); - // zero hash in packet - memset(header_hash, 0, o->hash_size); - // calculate hash - uint8_t hash_calc[BHASH_MAX_SIZE]; - BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash_calc); - // set hash field to its original value - memcpy(header_hash, hash, o->hash_size); - // compare hashes - if (memcmp(hash, hash_calc, o->hash_size)) { - PeerLog(o, BLOG_WARNING, "packet has wrong hash"); - return; - } - } - - // return packet - o->tw_out = plaintext + SPPROTO_HEADER_LEN(o->sp_params); - o->tw_out_len = plaintext_len - SPPROTO_HEADER_LEN(o->sp_params); -} - -static void decode_work_handler (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->tw_have) - DebugObject_Access(&o->d_obj); - - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // check OTP - if (SPPROTO_HAVE_OTP(o->sp_params) && o->tw_out_len >= 0) { - if (!OTPChecker_CheckOTP(&o->otpchecker, o->tw_out_seed_id, o->tw_out_otp)) { - PeerLog(o, BLOG_WARNING, "packet has wrong OTP"); - o->tw_out_len = -1; - } - } - - if (o->tw_out_len < 0) { - // cannot decode, finish input packet - PacketPassInterface_Done(&o->input); - o->in_len = -1; - } else { - // submit decoded packet to output - PacketPassInterface_Sender_Send(o->output, o->tw_out, o->tw_out_len); - } -} - -static void input_handler_send (SPProtoDecoder *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember input - o->in = data; - o->in_len = data_len; - - // start decoding - BThreadWork_Init(&o->tw, o->twd, (BThreadWork_handler_done)decode_work_handler, o, (BThreadWork_work_func)decode_work_func, o); - o->tw_have = 1; -} - -static void output_handler_done (SPProtoDecoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // finish input packet - PacketPassInterface_Done(&o->input); - o->in_len = -1; -} - -static void maybe_stop_work_and_ignore (SPProtoDecoder *o) -{ - ASSERT(!(o->tw_have) || o->in_len >= 0) - - if (o->tw_have) { - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // ignore packet, receive next one - PacketPassInterface_Done(&o->input); - o->in_len = -1; - } -} - -int SPProtoDecoder_Init (SPProtoDecoder *o, PacketPassInterface *output, struct spproto_security_params sp_params, int num_otp_seeds, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, BLog_logfunc logfunc) -{ - spproto_assert_security_params(sp_params); - ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketPassInterface_GetMTU(output)) >= 0) - ASSERT(!SPPROTO_HAVE_OTP(sp_params) || num_otp_seeds >= 2) - - // init arguments - o->output = output; - o->sp_params = sp_params; - o->twd = twd; - o->user = user; - o->logfunc = logfunc; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // remember output MTU - o->output_mtu = PacketPassInterface_GetMTU(o->output); - - // calculate hash size - if (SPPROTO_HAVE_HASH(o->sp_params)) { - o->hash_size = BHash_size(o->sp_params.hash_mode); - } - - // calculate encryption block and key sizes - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->enc_block_size = BEncryption_cipher_block_size(o->sp_params.encryption_mode); - o->enc_key_size = BEncryption_cipher_key_size(o->sp_params.encryption_mode); - } - - // calculate input MTU - o->input_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->output_mtu); - - // allocate plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - int buf_size = balign_up((SPPROTO_HEADER_LEN(o->sp_params) + o->output_mtu + 1), o->enc_block_size); - if (!(o->buf = (uint8_t *)malloc(buf_size))) { - goto fail0; - } - } - - // init input - PacketPassInterface_Init(&o->input, o->input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // init OTP checker - if (SPPROTO_HAVE_OTP(o->sp_params)) { - if (!OTPChecker_Init(&o->otpchecker, o->sp_params.otp_num, o->sp_params.otp_mode, num_otp_seeds, o->twd)) { - goto fail1; - } - } - - // have no encryption key - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->have_encryption_key = 0; - } - - // have no input packet - o->in_len = -1; - - // have no work - o->tw_have = 0; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketPassInterface_Free(&o->input); - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } -fail0: - return 0; -} - -void SPProtoDecoder_Free (SPProtoDecoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - } - - // free encryptor - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params) && o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // free OTP checker - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPChecker_Free(&o->otpchecker); - } - - // free input - PacketPassInterface_Free(&o->input); - - // free plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } -} - -PacketPassInterface * SPProtoDecoder_GetInput (SPProtoDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void SPProtoDecoder_SetEncryptionKey (SPProtoDecoder *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work_and_ignore(o); - - // free encryptor - if (o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // init encryptor - BEncryption_Init(&o->encryptor, BENCRYPTION_MODE_DECRYPT, o->sp_params.encryption_mode, encryption_key); - - // have encryption key - o->have_encryption_key = 1; -} - -void SPProtoDecoder_RemoveEncryptionKey (SPProtoDecoder *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work_and_ignore(o); - - if (o->have_encryption_key) { - // free encryptor - BEncryption_Free(&o->encryptor); - - // have no encryption key - o->have_encryption_key = 0; - } -} - -void SPProtoDecoder_AddOTPSeed (SPProtoDecoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - OTPChecker_AddSeed(&o->otpchecker, seed_id, key, iv); -} - -void SPProtoDecoder_RemoveOTPSeeds (SPProtoDecoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - OTPChecker_RemoveSeeds(&o->otpchecker); -} - -void SPProtoDecoder_SetHandlers (SPProtoDecoder *o, SPProtoDecoder_otp_handler otp_handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPChecker_SetHandlers(&o->otpchecker, otp_handler, user); - } -} diff --git a/v2rayng/badvpn/client/SPProtoDecoder.h b/v2rayng/badvpn/client/SPProtoDecoder.h deleted file mode 100644 index 3b5de713c0..0000000000 --- a/v2rayng/badvpn/client/SPProtoDecoder.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file SPProtoDecoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes packets according to SPProto. - */ - -#ifndef BADVPN_CLIENT_SPPROTODECODER_H -#define BADVPN_CLIENT_SPPROTODECODER_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -/** - * Handler called when OTP generation for a new seed is finished. - * - * @param user as in {@link SPProtoDecoder_Init} - */ -typedef void (*SPProtoDecoder_otp_handler) (void *user); - -/** - * Object which decodes packets according to SPProto. - * Input is with {@link PacketPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - PacketPassInterface *output; - struct spproto_security_params sp_params; - BThreadWorkDispatcher *twd; - void *user; - BLog_logfunc logfunc; - int output_mtu; - int hash_size; - int enc_block_size; - int enc_key_size; - int input_mtu; - uint8_t *buf; - PacketPassInterface input; - OTPChecker otpchecker; - int have_encryption_key; - BEncryption encryptor; - uint8_t *in; - int in_len; - int tw_have; - BThreadWork tw; - uint16_t tw_out_seed_id; - otp_t tw_out_otp; - uint8_t *tw_out; - int tw_out_len; - DebugObject d_obj; -} SPProtoDecoder; - -/** - * Initializes the object. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param output output interface. Its MTU must not be too large, i.e. this must hold: - * spproto_carrier_mtu_for_payload_mtu(sp_params, output MTU) >= 0 - * @param sp_params SPProto parameters - * @param encryption_key if using encryption, the encryption key - * @param num_otp_seeds if using OTPs, how many OTP seeds to keep for checking - * receiving packets. Must be >=2 if using OTPs. - * @param pg pending group - * @param twd thread work dispatcher - * @param user argument to handlers - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @return 1 on success, 0 on failure - */ -int SPProtoDecoder_Init (SPProtoDecoder *o, PacketPassInterface *output, struct spproto_security_params sp_params, int num_otp_seeds, BPendingGroup *pg, BThreadWorkDispatcher *twd, void *user, BLog_logfunc logfunc) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void SPProtoDecoder_Free (SPProtoDecoder *o); - -/** - * Returns the input interface. - * The MTU of the input interface will depend on the output MTU and security parameters, - * that is spproto_carrier_mtu_for_payload_mtu(sp_params, output MTU). - * - * @param o the object - * @return input interface - */ -PacketPassInterface * SPProtoDecoder_GetInput (SPProtoDecoder *o); - -/** - * Sets an encryption key for decrypting packets. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void SPProtoDecoder_SetEncryptionKey (SPProtoDecoder *o, uint8_t *encryption_key); - -/** - * Removes an encryption key if one is configured. - * Encryption must be enabled. - * - * @param o the object - */ -void SPProtoDecoder_RemoveEncryptionKey (SPProtoDecoder *o); - -/** - * Starts generating OTPs for a seed to check received packets against. - * OTPs for this seed will not be recognized until the {@link SPProtoDecoder_otp_handler} handler - * is called. - * If OTPs are still being generated for the previous seed, it will be forgotten. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void SPProtoDecoder_AddOTPSeed (SPProtoDecoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes all OTP seeds for checking received packets against. - * OTPs must be enabled. - * - * @param o the object - */ -void SPProtoDecoder_RemoveOTPSeeds (SPProtoDecoder *o); - -/** - * Sets handlers. - * - * @param o the object - * @param otp_handler handler called when OTP generation is finished - * @param user argument to handler - */ -void SPProtoDecoder_SetHandlers (SPProtoDecoder *o, SPProtoDecoder_otp_handler otp_handler, void *user); - -#endif diff --git a/v2rayng/badvpn/client/SPProtoEncoder.c b/v2rayng/badvpn/client/SPProtoEncoder.c deleted file mode 100644 index fbbab50aff..0000000000 --- a/v2rayng/badvpn/client/SPProtoEncoder.c +++ /dev/null @@ -1,436 +0,0 @@ -/** - * @file SPProtoEncoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "SPProtoEncoder.h" - -static int can_encode (SPProtoEncoder *o); -static void encode_packet (SPProtoEncoder *o); -static void encode_work_func (SPProtoEncoder *o); -static void encode_work_handler (SPProtoEncoder *o); -static void maybe_encode (SPProtoEncoder *o); -static void output_handler_recv (SPProtoEncoder *o, uint8_t *data); -static void input_handler_done (SPProtoEncoder *o, int data_len); -static void handler_job_hander (SPProtoEncoder *o); -static void otpgenerator_handler (SPProtoEncoder *o); -static void maybe_stop_work (SPProtoEncoder *o); - -static int can_encode (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - - return ( - (!SPPROTO_HAVE_OTP(o->sp_params) || OTPGenerator_GetPosition(&o->otpgen) < o->sp_params.otp_num) && - (!SPPROTO_HAVE_ENCRYPTION(o->sp_params) || o->have_encryption_key) - ); -} - -static void encode_packet (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - ASSERT(can_encode(o)) - - // generate OTP, remember seed ID - if (SPPROTO_HAVE_OTP(o->sp_params)) { - o->tw_seed_id = o->otpgen_seed_id; - o->tw_otp = OTPGenerator_GetOTP(&o->otpgen); - } - - // start work - BThreadWork_Init(&o->tw, o->twd, (BThreadWork_handler_done)encode_work_handler, o, (BThreadWork_work_func)encode_work_func, o); - o->tw_have = 1; - - // schedule OTP warning handler - if (SPPROTO_HAVE_OTP(o->sp_params) && OTPGenerator_GetPosition(&o->otpgen) == o->otp_warning_count) { - BPending_Set(&o->handler_job); - } -} - -static void encode_work_func (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(!SPPROTO_HAVE_ENCRYPTION(o->sp_params) || o->have_encryption_key) - - ASSERT(o->in_len <= o->input_mtu) - - // determine plaintext location - uint8_t *plaintext = (SPPROTO_HAVE_ENCRYPTION(o->sp_params) ? o->buf : o->out); - - // plaintext begins with header - uint8_t *header = plaintext; - - // plaintext is header + payload - int plaintext_len = SPPROTO_HEADER_LEN(o->sp_params) + o->in_len; - - // write OTP - if (SPPROTO_HAVE_OTP(o->sp_params)) { - struct spproto_otpdata header_otpd; - header_otpd.seed_id = htol16(o->tw_seed_id); - header_otpd.otp = o->tw_otp; - memcpy(header + SPPROTO_HEADER_OTPDATA_OFF(o->sp_params), &header_otpd, sizeof(header_otpd)); - } - - // write hash - if (SPPROTO_HAVE_HASH(o->sp_params)) { - uint8_t *header_hash = header + SPPROTO_HEADER_HASH_OFF(o->sp_params); - // zero hash field - memset(header_hash, 0, o->hash_size); - // calculate hash - uint8_t hash[BHASH_MAX_SIZE]; - BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash); - // set hash field - memcpy(header_hash, hash, o->hash_size); - } - - int out_len; - - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - // encrypting pad(header + payload) - int cyphertext_len = balign_up((plaintext_len + 1), o->enc_block_size); - - // write padding - plaintext[plaintext_len] = 1; - for (int i = plaintext_len + 1; i < cyphertext_len; i++) { - plaintext[i] = 0; - } - - // generate IV - BRandom_randomize(o->out, o->enc_block_size); - - // copy IV because BEncryption_Encrypt changes the IV - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - memcpy(iv, o->out, o->enc_block_size); - - // encrypt - BEncryption_Encrypt(&o->encryptor, plaintext, o->out + o->enc_block_size, cyphertext_len, iv); - out_len = o->enc_block_size + cyphertext_len; - } else { - out_len = plaintext_len; - } - - // remember length - o->tw_out_len = out_len; -} - -static void encode_work_handler (SPProtoEncoder *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->out_have) - ASSERT(o->tw_have) - - // free work - BThreadWork_Free(&o->tw); - o->tw_have = 0; - - // finish packet - o->in_len = -1; - o->out_have = 0; - PacketRecvInterface_Done(&o->output, o->tw_out_len); -} - -static void maybe_encode (SPProtoEncoder *o) -{ - if (o->in_len >= 0 && o->out_have && !o->tw_have && can_encode(o)) { - encode_packet(o); - } -} - -static void output_handler_recv (SPProtoEncoder *o, uint8_t *data) -{ - ASSERT(o->in_len == -1) - ASSERT(!o->out_have) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_have = 1; - o->out = data; - - // determine plaintext location - uint8_t *plaintext = (SPPROTO_HAVE_ENCRYPTION(o->sp_params) ? o->buf : o->out); - - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, plaintext + SPPROTO_HEADER_LEN(o->sp_params)); -} - -static void input_handler_done (SPProtoEncoder *o, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - ASSERT(o->out_have) - ASSERT(!o->tw_have) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - - // encode if possible - if (can_encode(o)) { - encode_packet(o); - } -} - -static void handler_job_hander (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - if (o->handler) { - o->handler(o->user); - return; - } -} - -static void otpgenerator_handler (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // remember seed ID - o->otpgen_seed_id = o->otpgen_pending_seed_id; - - // possibly continue I/O - maybe_encode(o); -} - -static void maybe_stop_work (SPProtoEncoder *o) -{ - // stop existing work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - o->tw_have = 0; - } -} - -int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, BPendingGroup *pg, BThreadWorkDispatcher *twd) -{ - spproto_assert_security_params(sp_params); - ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketRecvInterface_GetMTU(input)) >= 0) - if (SPPROTO_HAVE_OTP(sp_params)) { - ASSERT(otp_warning_count > 0) - ASSERT(otp_warning_count <= sp_params.otp_num) - } - - // init arguments - o->input = input; - o->sp_params = sp_params; - o->otp_warning_count = otp_warning_count; - o->twd = twd; - - // set no handlers - o->handler = NULL; - - // calculate hash size - if (SPPROTO_HAVE_HASH(o->sp_params)) { - o->hash_size = BHash_size(o->sp_params.hash_mode); - } - - // calculate encryption block and key sizes - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->enc_block_size = BEncryption_cipher_block_size(o->sp_params.encryption_mode); - o->enc_key_size = BEncryption_cipher_key_size(o->sp_params.encryption_mode); - } - - // init otp generator - if (SPPROTO_HAVE_OTP(o->sp_params)) { - if (!OTPGenerator_Init(&o->otpgen, o->sp_params.otp_num, o->sp_params.otp_mode, o->twd, (OTPGenerator_handler)otpgenerator_handler, o)) { - goto fail0; - } - } - - // have no encryption key - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - o->have_encryption_key = 0; - } - - // remember input MTU - o->input_mtu = PacketRecvInterface_GetMTU(o->input); - - // calculate output MTU - o->output_mtu = spproto_carrier_mtu_for_payload_mtu(o->sp_params, o->input_mtu); - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // have no input in buffer - o->in_len = -1; - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output available - o->out_have = 0; - - // allocate plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - int buf_size = balign_up((SPPROTO_HEADER_LEN(o->sp_params) + o->input_mtu + 1), o->enc_block_size); - if (!(o->buf = (uint8_t *)malloc(buf_size))) { - goto fail1; - } - } - - // init handler job - BPending_Init(&o->handler_job, pg, (BPending_handler)handler_job_hander, o); - - // have no work - o->tw_have = 0; - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketRecvInterface_Free(&o->output); - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPGenerator_Free(&o->otpgen); - } -fail0: - return 0; -} - -void SPProtoEncoder_Free (SPProtoEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free work - if (o->tw_have) { - BThreadWork_Free(&o->tw); - } - - // free handler job - BPending_Free(&o->handler_job); - - // free plaintext buffer - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) { - free(o->buf); - } - - // free output - PacketRecvInterface_Free(&o->output); - - // free encryptor - if (SPPROTO_HAVE_ENCRYPTION(o->sp_params) && o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // free otp generator - if (SPPROTO_HAVE_OTP(o->sp_params)) { - OTPGenerator_Free(&o->otpgen); - } -} - -PacketRecvInterface * SPProtoEncoder_GetOutput (SPProtoEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void SPProtoEncoder_SetEncryptionKey (SPProtoEncoder *o, uint8_t *encryption_key) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work(o); - - // free encryptor - if (o->have_encryption_key) { - BEncryption_Free(&o->encryptor); - } - - // init encryptor - BEncryption_Init(&o->encryptor, BENCRYPTION_MODE_ENCRYPT, o->sp_params.encryption_mode, encryption_key); - - // have encryption key - o->have_encryption_key = 1; - - // possibly continue I/O - maybe_encode(o); -} - -void SPProtoEncoder_RemoveEncryptionKey (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // stop existing work - maybe_stop_work(o); - - if (o->have_encryption_key) { - // free encryptor - BEncryption_Free(&o->encryptor); - - // have no encryption key - o->have_encryption_key = 0; - } -} - -void SPProtoEncoder_SetOTPSeed (SPProtoEncoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // give seed to OTP generator - OTPGenerator_SetSeed(&o->otpgen, key, iv); - - // remember seed ID - o->otpgen_pending_seed_id = seed_id; -} - -void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o) -{ - ASSERT(SPPROTO_HAVE_OTP(o->sp_params)) - DebugObject_Access(&o->d_obj); - - // reset OTP generator - OTPGenerator_Reset(&o->otpgen); -} - -void SPProtoEncoder_SetHandlers (SPProtoEncoder *o, SPProtoEncoder_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->user = user; -} diff --git a/v2rayng/badvpn/client/SPProtoEncoder.h b/v2rayng/badvpn/client/SPProtoEncoder.h deleted file mode 100644 index 874f391a6d..0000000000 --- a/v2rayng/badvpn/client/SPProtoEncoder.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file SPProtoEncoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets according to SPProto. - */ - -#ifndef BADVPN_CLIENT_SPPROTOENCODER_H -#define BADVPN_CLIENT_SPPROTOENCODER_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -/** - * Event context handler called when the remaining number of - * OTPs equals the warning number after having encoded a packet. - * - * @param user as in {@link SPProtoEncoder_Init} - */ -typedef void (*SPProtoEncoder_handler) (void *user); - -/** - * Object which encodes packets according to SPProto. - * - * Input is with {@link PacketRecvInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - PacketRecvInterface *input; - struct spproto_security_params sp_params; - int otp_warning_count; - SPProtoEncoder_handler handler; - BThreadWorkDispatcher *twd; - void *user; - int hash_size; - int enc_block_size; - int enc_key_size; - OTPGenerator otpgen; - uint16_t otpgen_seed_id; - uint16_t otpgen_pending_seed_id; - int have_encryption_key; - BEncryption encryptor; - int input_mtu; - int output_mtu; - int in_len; - PacketRecvInterface output; - int out_have; - uint8_t *out; - uint8_t *buf; - BPending handler_job; - int tw_have; - BThreadWork tw; - uint16_t tw_seed_id; - otp_t tw_otp; - int tw_out_len; - DebugObject d_obj; -} SPProtoEncoder; - -/** - * Initializes the object. - * The object is initialized in blocked state. - * {@link BSecurity_GlobalInitThreadSafe} must have been done if - * {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1. - * - * @param o the object - * @param input input interface. Its MTU must not be too large, i.e. this must hold: - * spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU) >= 0 - * @param sp_params SPProto security parameters - * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler. - * In this case, must be >0 and <=sp_params.otp_num. - * @param pg pending group - * @param twd thread work dispatcher - * @return 1 on success, 0 on failure - */ -int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, BPendingGroup *pg, BThreadWorkDispatcher *twd) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void SPProtoEncoder_Free (SPProtoEncoder *o); - -/** - * Returns the output interface. - * The MTU of the output interface will depend on the input MTU and security parameters, - * that is spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU). - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SPProtoEncoder_GetOutput (SPProtoEncoder *o); - -/** - * Sets an encryption key to use. - * Encryption must be enabled. - * - * @param o the object - * @param encryption_key key to use - */ -void SPProtoEncoder_SetEncryptionKey (SPProtoEncoder *o, uint8_t *encryption_key); - -/** - * Removes an encryption key if one is configured. - * Encryption must be enabled. - * - * @param o the object - */ -void SPProtoEncoder_RemoveEncryptionKey (SPProtoEncoder *o); - -/** - * Sets an OTP seed to use. - * OTPs must be enabled. - * - * @param o the object - * @param seed_id seed identifier - * @param key OTP encryption key - * @param iv OTP initialization vector - */ -void SPProtoEncoder_SetOTPSeed (SPProtoEncoder *o, uint16_t seed_id, uint8_t *key, uint8_t *iv); - -/** - * Removes the OTP seed if one is configured. - * OTPs must be enabled. - * - * @param o the object - */ -void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o); - -/** - * Sets handlers. - * - * @param o the object - * @param handler OTP warning handler - * @param user value to pass to handler - */ -void SPProtoEncoder_SetHandlers (SPProtoEncoder *o, SPProtoEncoder_handler handler, void *user); - -#endif diff --git a/v2rayng/badvpn/client/SimpleStreamBuffer.c b/v2rayng/badvpn/client/SimpleStreamBuffer.c deleted file mode 100644 index 74448cb856..0000000000 --- a/v2rayng/badvpn/client/SimpleStreamBuffer.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file SimpleStreamBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -#include "SimpleStreamBuffer.h" - -static void try_output (SimpleStreamBuffer *o) -{ - ASSERT(o->output_data_len > 0) - - // calculate number of bytes to output - int bytes = bmin_int(o->output_data_len, o->buf_used); - if (bytes == 0) { - return; - } - - // copy bytes to output - memcpy(o->output_data, o->buf, bytes); - - // shift buffer - memmove(o->buf, o->buf + bytes, o->buf_used - bytes); - o->buf_used -= bytes; - - // forget data - o->output_data_len = -1; - - // done - StreamRecvInterface_Done(&o->output, bytes); -} - -static void output_handler_recv (SimpleStreamBuffer *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->output_data_len == -1) - ASSERT(data) - ASSERT(data_len > 0) - - // remember data - o->output_data = data; - o->output_data_len = data_len; - - try_output(o); -} - -int SimpleStreamBuffer_Init (SimpleStreamBuffer *o, int buf_size, BPendingGroup *pg) -{ - ASSERT(buf_size > 0) - - // init arguments - o->buf_size = buf_size; - - // init output - StreamRecvInterface_Init(&o->output, (StreamRecvInterface_handler_recv)output_handler_recv, o, pg); - - // allocate buffer - if (!(o->buf = (uint8_t *)BAlloc(buf_size))) { - goto fail1; - } - - // init buffer state - o->buf_used = 0; - - // set no output data - o->output_data_len = -1; - - DebugObject_Init(&o->d_obj); - return 1; - -fail1: - StreamRecvInterface_Free(&o->output); - return 0; -} - -void SimpleStreamBuffer_Free (SimpleStreamBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - BFree(o->buf); - - // free output - StreamRecvInterface_Free(&o->output); -} - -StreamRecvInterface * SimpleStreamBuffer_GetOutput (SimpleStreamBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -int SimpleStreamBuffer_Write (SimpleStreamBuffer *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len >= 0) - - if (data_len > o->buf_size - o->buf_used) { - return 0; - } - - // copy to buffer - memcpy(o->buf + o->buf_used, data, data_len); - - // update buffer state - o->buf_used += data_len; - - // continue outputting - if (o->output_data_len > 0) { - try_output(o); - } - - return 1; -} diff --git a/v2rayng/badvpn/client/SimpleStreamBuffer.h b/v2rayng/badvpn/client/SimpleStreamBuffer.h deleted file mode 100644 index 31a55f7300..0000000000 --- a/v2rayng/badvpn/client/SimpleStreamBuffer.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file SimpleStreamBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SIMPLESTREAMBUFFER_H -#define BADVPN_SIMPLESTREAMBUFFER_H - -#include -#include -#include - -typedef struct { - int buf_size; - StreamRecvInterface output; - uint8_t *buf; - int buf_used; - uint8_t *output_data; - int output_data_len; - DebugObject d_obj; -} SimpleStreamBuffer; - -int SimpleStreamBuffer_Init (SimpleStreamBuffer *o, int buf_size, BPendingGroup *pg) WARN_UNUSED; -void SimpleStreamBuffer_Free (SimpleStreamBuffer *o); -StreamRecvInterface * SimpleStreamBuffer_GetOutput (SimpleStreamBuffer *o); -int SimpleStreamBuffer_Write (SimpleStreamBuffer *o, uint8_t *data, int data_len) WARN_UNUSED; - -#endif diff --git a/v2rayng/badvpn/client/SinglePacketSource.c b/v2rayng/badvpn/client/SinglePacketSource.c deleted file mode 100644 index 1c6a573a2d..0000000000 --- a/v2rayng/badvpn/client/SinglePacketSource.c +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file SinglePacketSource.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "SinglePacketSource.h" - -static void output_handler_recv (SinglePacketSource *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - // if we already sent one packet, stop - if (o->sent) { - return; - } - - // set sent - o->sent = 1; - - // write packet - memcpy(data, o->packet, o->packet_len); - - // done - PacketRecvInterface_Done(&o->output, o->packet_len); -} - -void SinglePacketSource_Init (SinglePacketSource *o, uint8_t *packet, int packet_len, BPendingGroup *pg) -{ - ASSERT(packet_len >= 0) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - - // set not sent - o->sent = 0; - - // init output - PacketRecvInterface_Init(&o->output, o->packet_len, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void SinglePacketSource_Free (SinglePacketSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * SinglePacketSource_GetOutput (SinglePacketSource *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/client/SinglePacketSource.h b/v2rayng/badvpn/client/SinglePacketSource.h deleted file mode 100644 index 85ca426651..0000000000 --- a/v2rayng/badvpn/client/SinglePacketSource.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file SinglePacketSource.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLEPACKETSOURCE_H -#define BADVPN_SINGLEPACKETSOURCE_H - -#include -#include - -/** - * An object which provides a single packet through {@link PacketRecvInterface}. - */ -typedef struct { - uint8_t *packet; - int packet_len; - int sent; - PacketRecvInterface output; - DebugObject d_obj; -} SinglePacketSource; - -/** - * Initializes the object. - * - * @param o the object - * @param packet packet to provide to the output. Must stay available until the packet is provided. - * @param packet_len length of packet. Must be >=0. - * @param pg pending group we live in - */ -void SinglePacketSource_Init (SinglePacketSource *o, uint8_t *packet, int packet_len, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SinglePacketSource_Free (SinglePacketSource *o); - -/** - * Returns the output interface. - * The MTU of the interface will be packet_len. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * SinglePacketSource_GetOutput (SinglePacketSource *o); - -#endif diff --git a/v2rayng/badvpn/client/StreamPeerIO.c b/v2rayng/badvpn/client/StreamPeerIO.c deleted file mode 100644 index 0b70588ec1..0000000000 --- a/v2rayng/badvpn/client/StreamPeerIO.c +++ /dev/null @@ -1,712 +0,0 @@ -/** - * @file StreamPeerIO.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include -#include - -#include - -#include - -#define MODE_NONE 0 -#define MODE_CONNECT 1 -#define MODE_LISTEN 2 - -#define CONNECT_STATE_CONNECTING 0 -#define CONNECT_STATE_HANDSHAKE 1 -#define CONNECT_STATE_SENDING 2 -#define CONNECT_STATE_SENT 3 -#define CONNECT_STATE_FINISHED 4 - -#define LISTEN_STATE_LISTENER 0 -#define LISTEN_STATE_GOTCLIENT 1 -#define LISTEN_STATE_FINISHED 2 - -#define PeerLog(_o, ...) BLog_LogViaFunc((_o)->logfunc, (_o)->user, BLOG_CURRENT_CHANNEL, __VA_ARGS__) - -static void decoder_handler_error (StreamPeerIO *pio); -static void connector_handler (StreamPeerIO *pio, int is_error); -static void connection_handler (StreamPeerIO *pio, int event); -static void connect_sslcon_handler (StreamPeerIO *pio, int event); -static void pwsender_handler (StreamPeerIO *pio); -static void listener_handler_client (StreamPeerIO *pio, sslsocket *sock); -static int init_io (StreamPeerIO *pio, sslsocket *sock); -static void free_io (StreamPeerIO *pio); -static void sslcon_handler (StreamPeerIO *pio, int event); -static SECStatus client_auth_certificate_callback (StreamPeerIO *pio, PRFileDesc *fd, PRBool checkSig, PRBool isServer); -static SECStatus client_client_auth_data_callback (StreamPeerIO *pio, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey); -static int compare_certificate (StreamPeerIO *pio, CERTCertificate *cert); -static void reset_state (StreamPeerIO *pio); -static void reset_and_report_error (StreamPeerIO *pio); - -void decoder_handler_error (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - - PeerLog(pio, BLOG_ERROR, "decoder error"); - - reset_and_report_error(pio); - return; -} - -void connector_handler (StreamPeerIO *pio, int is_error) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_CONNECTING) - - // check connection result - if (is_error) { - PeerLog(pio, BLOG_NOTICE, "connection failed"); - goto fail0; - } - - // init connection - if (!BConnection_Init(&pio->connect.sock.con, BConnection_source_connector(&pio->connect.connector), pio->reactor, pio, (BConnection_handler)connection_handler)) { - PeerLog(pio, BLOG_ERROR, "BConnection_Init failed"); - goto fail0; - } - - if (pio->ssl) { - // init connection interfaces - BConnection_SendAsync_Init(&pio->connect.sock.con); - BConnection_RecvAsync_Init(&pio->connect.sock.con); - - // create bottom NSPR file descriptor - if (!BSSLConnection_MakeBackend(&pio->connect.sock.bottom_prfd, BConnection_SendAsync_GetIf(&pio->connect.sock.con), BConnection_RecvAsync_GetIf(&pio->connect.sock.con), pio->twd, pio->ssl_flags)) { - PeerLog(pio, BLOG_ERROR, "BSSLConnection_MakeBackend failed"); - goto fail1; - } - - // create SSL file descriptor from the bottom NSPR file descriptor - if (!(pio->connect.sock.ssl_prfd = SSL_ImportFD(NULL, &pio->connect.sock.bottom_prfd))) { - ASSERT_FORCE(PR_Close(&pio->connect.sock.bottom_prfd) == PR_SUCCESS) - goto fail1; - } - - // set client mode - if (SSL_ResetHandshake(pio->connect.sock.ssl_prfd, PR_FALSE) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_ResetHandshake failed"); - goto fail2; - } - - // set verify peer certificate hook - if (SSL_AuthCertificateHook(pio->connect.sock.ssl_prfd, (SSLAuthCertificate)client_auth_certificate_callback, pio) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail2; - } - - // set client certificate callback - if (SSL_GetClientAuthDataHook(pio->connect.sock.ssl_prfd, (SSLGetClientAuthData)client_client_auth_data_callback, pio) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail2; - } - - // init BSSLConnection - BSSLConnection_Init(&pio->connect.sslcon, pio->connect.sock.ssl_prfd, 1, BReactor_PendingGroup(pio->reactor), pio, (BSSLConnection_handler)connect_sslcon_handler); - - // change state - pio->connect.state = CONNECT_STATE_HANDSHAKE; - } else { - // init connection send interface - BConnection_SendAsync_Init(&pio->connect.sock.con); - - // init password sender - SingleStreamSender_Init(&pio->connect.pwsender, (uint8_t *)&pio->connect.password, sizeof(pio->connect.password), BConnection_SendAsync_GetIf(&pio->connect.sock.con), BReactor_PendingGroup(pio->reactor), pio, (SingleStreamSender_handler)pwsender_handler); - - // change state - pio->connect.state = CONNECT_STATE_SENDING; - } - - return; - - if (pio->ssl) { -fail2: - ASSERT_FORCE(PR_Close(pio->connect.sock.ssl_prfd) == PR_SUCCESS) -fail1: - BConnection_RecvAsync_Free(&pio->connect.sock.con); - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - BConnection_Free(&pio->connect.sock.con); -fail0: - reset_and_report_error(pio); - return; -} - -void connection_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT || pio->mode == MODE_LISTEN) - ASSERT(!(pio->mode == MODE_CONNECT) || pio->connect.state >= CONNECT_STATE_HANDSHAKE) - ASSERT(!(pio->mode == MODE_LISTEN) || pio->listen.state >= LISTEN_STATE_FINISHED) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - PeerLog(pio, BLOG_NOTICE, "connection closed"); - } else { - PeerLog(pio, BLOG_NOTICE, "connection error"); - } - - reset_and_report_error(pio); - return; -} - -void connect_sslcon_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE || pio->connect.state == CONNECT_STATE_SENDING) - ASSERT(event == BSSLCONNECTION_EVENT_UP || event == BSSLCONNECTION_EVENT_ERROR) - - if (event == BSSLCONNECTION_EVENT_ERROR) { - PeerLog(pio, BLOG_NOTICE, "SSL error"); - - reset_and_report_error(pio); - return; - } - - // handshake complete - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - - // remove client certificate callback - if (SSL_GetClientAuthDataHook(pio->connect.sock.ssl_prfd, NULL, NULL) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_GetClientAuthDataHook failed"); - goto fail0; - } - - // remove verify peer certificate callback - if (SSL_AuthCertificateHook(pio->connect.sock.ssl_prfd, NULL, NULL) != SECSuccess) { - PeerLog(pio, BLOG_ERROR, "SSL_AuthCertificateHook failed"); - goto fail0; - } - - // init password sender - SingleStreamSender_Init(&pio->connect.pwsender, (uint8_t *)&pio->connect.password, sizeof(pio->connect.password), BSSLConnection_GetSendIf(&pio->connect.sslcon), BReactor_PendingGroup(pio->reactor), pio, (SingleStreamSender_handler)pwsender_handler); - - // change state - pio->connect.state = CONNECT_STATE_SENDING; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -void pwsender_handler (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_SENDING) - - // stop using any buffers before they get freed - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->connect.sslcon); - } - - // free password sender - SingleStreamSender_Free(&pio->connect.pwsender); - - if (pio->ssl) { - // free BSSLConnection (we used the send interface) - BSSLConnection_Free(&pio->connect.sslcon); - } else { - // init connection send interface - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - - // change state - pio->connect.state = CONNECT_STATE_SENT; - - // setup i/o - if (!init_io(pio, &pio->connect.sock)) { - goto fail0; - } - - // change state - pio->connect.state = CONNECT_STATE_FINISHED; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -void listener_handler_client (StreamPeerIO *pio, sslsocket *sock) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->mode == MODE_LISTEN) - ASSERT(pio->listen.state == LISTEN_STATE_LISTENER) - - // remember socket - pio->listen.sock = sock; - - // set connection handler - BConnection_SetHandlers(&pio->listen.sock->con, pio, (BConnection_handler)connection_handler); - - // change state - pio->listen.state = LISTEN_STATE_GOTCLIENT; - - // check ceritficate - if (pio->ssl) { - CERTCertificate *peer_cert = SSL_PeerCertificate(pio->listen.sock->ssl_prfd); - if (!peer_cert) { - PeerLog(pio, BLOG_ERROR, "SSL_PeerCertificate failed"); - goto fail0; - } - - // compare certificate to the one provided by the server - if (!compare_certificate(pio, peer_cert)) { - CERT_DestroyCertificate(peer_cert); - goto fail0; - } - - CERT_DestroyCertificate(peer_cert); - } - - // setup i/o - if (!init_io(pio, pio->listen.sock)) { - goto fail0; - } - - // change state - pio->listen.state = LISTEN_STATE_FINISHED; - - return; - -fail0: - reset_and_report_error(pio); - return; -} - -int init_io (StreamPeerIO *pio, sslsocket *sock) -{ - ASSERT(!pio->sock) - - // limit socket send buffer, else our scheduling is pointless - if (pio->sock_sndbuf > 0) { - if (!BConnection_SetSendBuffer(&sock->con, pio->sock_sndbuf)) { - PeerLog(pio, BLOG_WARNING, "BConnection_SetSendBuffer failed"); - } - } - - if (pio->ssl) { - // init BSSLConnection - BSSLConnection_Init(&pio->sslcon, sock->ssl_prfd, 0, BReactor_PendingGroup(pio->reactor), pio, (BSSLConnection_handler)sslcon_handler); - } else { - // init connection interfaces - BConnection_SendAsync_Init(&sock->con); - BConnection_RecvAsync_Init(&sock->con); - } - - StreamPassInterface *send_if = (pio->ssl ? BSSLConnection_GetSendIf(&pio->sslcon) : BConnection_SendAsync_GetIf(&sock->con)); - StreamRecvInterface *recv_if = (pio->ssl ? BSSLConnection_GetRecvIf(&pio->sslcon) : BConnection_RecvAsync_GetIf(&sock->con)); - - // init receiving - StreamRecvConnector_ConnectInput(&pio->input_connector, recv_if); - - // init sending - PacketStreamSender_Init(&pio->output_pss, send_if, PACKETPROTO_ENCLEN(pio->payload_mtu), BReactor_PendingGroup(pio->reactor)); - PacketPassConnector_ConnectOutput(&pio->output_connector, PacketStreamSender_GetInput(&pio->output_pss)); - - pio->sock = sock; - - return 1; -} - -void free_io (StreamPeerIO *pio) -{ - ASSERT(pio->sock) - - // stop using any buffers before they get freed - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->sslcon); - } - - // reset decoder - PacketProtoDecoder_Reset(&pio->input_decoder); - - // free sending - PacketPassConnector_DisconnectOutput(&pio->output_connector); - PacketStreamSender_Free(&pio->output_pss); - - // free receiving - StreamRecvConnector_DisconnectInput(&pio->input_connector); - - if (pio->ssl) { - // free BSSLConnection - BSSLConnection_Free(&pio->sslcon); - } else { - // free connection interfaces - BConnection_RecvAsync_Free(&pio->sock->con); - BConnection_SendAsync_Free(&pio->sock->con); - } - - pio->sock = NULL; -} - -void sslcon_handler (StreamPeerIO *pio, int event) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT || pio->mode == MODE_LISTEN) - ASSERT(!(pio->mode == MODE_CONNECT) || pio->connect.state == CONNECT_STATE_FINISHED) - ASSERT(!(pio->mode == MODE_LISTEN) || pio->listen.state == LISTEN_STATE_FINISHED) - ASSERT(event == BSSLCONNECTION_EVENT_ERROR) - - PeerLog(pio, BLOG_NOTICE, "SSL error"); - - reset_and_report_error(pio); - return; -} - -SECStatus client_auth_certificate_callback (StreamPeerIO *pio, PRFileDesc *fd, PRBool checkSig, PRBool isServer) -{ - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - DebugObject_Access(&pio->d_obj); - - // This callback is used to bypass checking the server's domain name, as peers - // don't have domain names. We byte-compare the certificate to the one reported - // by the server anyway. - - SECStatus ret = SECFailure; - - CERTCertificate *server_cert = SSL_PeerCertificate(pio->connect.sock.ssl_prfd); - if (!server_cert) { - PeerLog(pio, BLOG_ERROR, "SSL_PeerCertificate failed"); - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail1; - } - - if (CERT_VerifyCertNow(CERT_GetDefaultCertDB(), server_cert, PR_TRUE, certUsageSSLServer, SSL_RevealPinArg(pio->connect.sock.ssl_prfd)) != SECSuccess) { - goto fail2; - } - - // compare to certificate provided by the server - if (!compare_certificate(pio, server_cert)) { - PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); - goto fail2; - } - - ret = SECSuccess; - -fail2: - CERT_DestroyCertificate(server_cert); -fail1: - return ret; -} - -SECStatus client_client_auth_data_callback (StreamPeerIO *pio, PRFileDesc *fd, CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey) -{ - ASSERT(pio->ssl) - ASSERT(pio->mode == MODE_CONNECT) - ASSERT(pio->connect.state == CONNECT_STATE_HANDSHAKE) - DebugObject_Access(&pio->d_obj); - - CERTCertificate *cert = CERT_DupCertificate(pio->connect.ssl_cert); - if (!cert) { - PeerLog(pio, BLOG_ERROR, "CERT_DupCertificate failed"); - goto fail0; - } - - SECKEYPrivateKey *key = SECKEY_CopyPrivateKey(pio->connect.ssl_key); - if (!key) { - PeerLog(pio, BLOG_ERROR, "SECKEY_CopyPrivateKey failed"); - goto fail1; - } - - *pRetCert = cert; - *pRetKey = key; - return SECSuccess; - -fail1: - CERT_DestroyCertificate(cert); -fail0: - return SECFailure; -} - -int compare_certificate (StreamPeerIO *pio, CERTCertificate *cert) -{ - ASSERT(pio->ssl) - - SECItem der = cert->derCert; - if (der.len != pio->ssl_peer_cert_len || memcmp(der.data, pio->ssl_peer_cert, der.len)) { - PeerLog(pio, BLOG_NOTICE, "Client certificate doesn't match"); - return 0; - } - - return 1; -} - -void reset_state (StreamPeerIO *pio) -{ - // free resources - switch (pio->mode) { - case MODE_NONE: - break; - case MODE_LISTEN: - switch (pio->listen.state) { - case LISTEN_STATE_FINISHED: - free_io(pio); - case LISTEN_STATE_GOTCLIENT: - if (pio->ssl) { - ASSERT_FORCE(PR_Close(pio->listen.sock->ssl_prfd) == PR_SUCCESS) - BConnection_RecvAsync_Free(&pio->listen.sock->con); - BConnection_SendAsync_Free(&pio->listen.sock->con); - } - BConnection_Free(&pio->listen.sock->con); - free(pio->listen.sock); - case LISTEN_STATE_LISTENER: - if (pio->listen.state == LISTEN_STATE_LISTENER) { - PasswordListener_RemoveEntry(pio->listen.listener, &pio->listen.pwentry); - } - break; - default: - ASSERT(0); - } - break; - case MODE_CONNECT: - switch (pio->connect.state) { - case CONNECT_STATE_FINISHED: - free_io(pio); - case CONNECT_STATE_SENT: - case CONNECT_STATE_SENDING: - if (pio->connect.state == CONNECT_STATE_SENDING) { - if (pio->ssl) { - BSSLConnection_ReleaseBuffers(&pio->connect.sslcon); - } - SingleStreamSender_Free(&pio->connect.pwsender); - if (!pio->ssl) { - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - } - case CONNECT_STATE_HANDSHAKE: - if (pio->ssl) { - if (pio->connect.state == CONNECT_STATE_HANDSHAKE || pio->connect.state == CONNECT_STATE_SENDING) { - BSSLConnection_Free(&pio->connect.sslcon); - } - ASSERT_FORCE(PR_Close(pio->connect.sock.ssl_prfd) == PR_SUCCESS) - BConnection_RecvAsync_Free(&pio->connect.sock.con); - BConnection_SendAsync_Free(&pio->connect.sock.con); - } - BConnection_Free(&pio->connect.sock.con); - case CONNECT_STATE_CONNECTING: - BConnector_Free(&pio->connect.connector); - break; - default: - ASSERT(0); - } - break; - default: - ASSERT(0); - } - - // set mode none - pio->mode = MODE_NONE; - - ASSERT(!pio->sock) -} - -void reset_and_report_error (StreamPeerIO *pio) -{ - reset_state(pio); - - pio->handler_error(pio->user); - return; -} - -int StreamPeerIO_Init ( - StreamPeerIO *pio, - BReactor *reactor, - BThreadWorkDispatcher *twd, - int ssl, - int ssl_flags, - uint8_t *ssl_peer_cert, - int ssl_peer_cert_len, - int payload_mtu, - int sock_sndbuf, - PacketPassInterface *user_recv_if, - BLog_logfunc logfunc, - StreamPeerIO_handler_error handler_error, - void *user -) -{ - ASSERT(ssl == 0 || ssl == 1) - ASSERT(payload_mtu >= 0) - ASSERT(PacketPassInterface_GetMTU(user_recv_if) >= payload_mtu) - ASSERT(handler_error) - - // init arguments - pio->reactor = reactor; - pio->twd = twd; - pio->ssl = ssl; - if (pio->ssl) { - pio->ssl_flags = ssl_flags; - pio->ssl_peer_cert = ssl_peer_cert; - pio->ssl_peer_cert_len = ssl_peer_cert_len; - } - pio->payload_mtu = payload_mtu; - pio->sock_sndbuf = sock_sndbuf; - pio->logfunc = logfunc; - pio->handler_error = handler_error; - pio->user = user; - - // check payload MTU - if (pio->payload_mtu > PACKETPROTO_MAXPAYLOAD) { - PeerLog(pio, BLOG_ERROR, "payload MTU is too large"); - goto fail0; - } - - // init receiveing objects - StreamRecvConnector_Init(&pio->input_connector, BReactor_PendingGroup(pio->reactor)); - if (!PacketProtoDecoder_Init(&pio->input_decoder, StreamRecvConnector_GetOutput(&pio->input_connector), user_recv_if, BReactor_PendingGroup(pio->reactor), pio, - (PacketProtoDecoder_handler_error)decoder_handler_error - )) { - PeerLog(pio, BLOG_ERROR, "FlowErrorDomain_Init failed"); - goto fail1; - } - - // init sending objects - PacketCopier_Init(&pio->output_user_copier, pio->payload_mtu, BReactor_PendingGroup(pio->reactor)); - PacketProtoEncoder_Init(&pio->output_user_ppe, PacketCopier_GetOutput(&pio->output_user_copier), BReactor_PendingGroup(pio->reactor)); - PacketPassConnector_Init(&pio->output_connector, PACKETPROTO_ENCLEN(pio->payload_mtu), BReactor_PendingGroup(pio->reactor)); - if (!SinglePacketBuffer_Init(&pio->output_user_spb, PacketProtoEncoder_GetOutput(&pio->output_user_ppe), PacketPassConnector_GetInput(&pio->output_connector), BReactor_PendingGroup(pio->reactor))) { - PeerLog(pio, BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // set mode none - pio->mode = MODE_NONE; - - // set no socket - pio->sock = NULL; - - DebugObject_Init(&pio->d_obj); - return 1; - -fail2: - PacketPassConnector_Free(&pio->output_connector); - PacketProtoEncoder_Free(&pio->output_user_ppe); - PacketCopier_Free(&pio->output_user_copier); - PacketProtoDecoder_Free(&pio->input_decoder); -fail1: - StreamRecvConnector_Free(&pio->input_connector); -fail0: - return 0; -} - -void StreamPeerIO_Free (StreamPeerIO *pio) -{ - DebugObject_Free(&pio->d_obj); - - // reset state - reset_state(pio); - - // free sending objects - SinglePacketBuffer_Free(&pio->output_user_spb); - PacketPassConnector_Free(&pio->output_connector); - PacketProtoEncoder_Free(&pio->output_user_ppe); - PacketCopier_Free(&pio->output_user_copier); - - // free receiveing objects - PacketProtoDecoder_Free(&pio->input_decoder); - StreamRecvConnector_Free(&pio->input_connector); -} - -PacketPassInterface * StreamPeerIO_GetSendInput (StreamPeerIO *pio) -{ - DebugObject_Access(&pio->d_obj); - - return PacketCopier_GetInput(&pio->output_user_copier); -} - -int StreamPeerIO_Connect (StreamPeerIO *pio, BAddr addr, uint64_t password, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key) -{ - DebugObject_Access(&pio->d_obj); - - // reset state - reset_state(pio); - - // check address - if (!BConnection_AddressSupported(addr)) { - PeerLog(pio, BLOG_ERROR, "BConnection_AddressSupported failed"); - goto fail0; - } - - // init connector - if (!BConnector_Init(&pio->connect.connector, addr, pio->reactor, pio, (BConnector_handler)connector_handler)) { - PeerLog(pio, BLOG_ERROR, "BConnector_Init failed"); - goto fail0; - } - - // remember data - if (pio->ssl) { - pio->connect.ssl_cert = ssl_cert; - pio->connect.ssl_key = ssl_key; - } - pio->connect.password = htol64(password); - - // set state - pio->mode = MODE_CONNECT; - pio->connect.state = CONNECT_STATE_CONNECTING; - - return 1; - -fail0: - return 0; -} - -void StreamPeerIO_Listen (StreamPeerIO *pio, PasswordListener *listener, uint64_t *password) -{ - DebugObject_Access(&pio->d_obj); - ASSERT(listener->ssl == pio->ssl) - - // reset state - reset_state(pio); - - // add PasswordListener entry - uint64_t newpass = PasswordListener_AddEntry(listener, &pio->listen.pwentry, (PasswordListener_handler_client)listener_handler_client, pio); - - // remember data - pio->listen.listener = listener; - - // set state - pio->mode = MODE_LISTEN; - pio->listen.state = LISTEN_STATE_LISTENER; - - *password = newpass; -} diff --git a/v2rayng/badvpn/client/StreamPeerIO.h b/v2rayng/badvpn/client/StreamPeerIO.h deleted file mode 100644 index b622f662c6..0000000000 --- a/v2rayng/badvpn/client/StreamPeerIO.h +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @file StreamPeerIO.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object used for communicating with a peer over TCP. - */ - -#ifndef BADVPN_CLIENT_STREAMPEERIO_H -#define BADVPN_CLIENT_STREAMPEERIO_H - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * Callback function invoked when an error occurs with the peer connection. - * The object has entered default state. - * May be called from within a sending Send call. - * - * @param user value given to {@link StreamPeerIO_Init}. - */ -typedef void (*StreamPeerIO_handler_error) (void *user); - -/** - * Object used for communicating with a peer over TCP. - * The object has a logical state which can be one of the following: - * - default state - * - listening state - * - connecting state - */ -typedef struct { - // common arguments - BReactor *reactor; - BThreadWorkDispatcher *twd; - int ssl; - int ssl_flags; - uint8_t *ssl_peer_cert; - int ssl_peer_cert_len; - int payload_mtu; - int sock_sndbuf; - BLog_logfunc logfunc; - StreamPeerIO_handler_error handler_error; - void *user; - - // persistent I/O modules - - // base sending objects - PacketCopier output_user_copier; - PacketProtoEncoder output_user_ppe; - SinglePacketBuffer output_user_spb; - PacketPassConnector output_connector; - - // receiving objects - StreamRecvConnector input_connector; - PacketProtoDecoder input_decoder; - - // connection side - int mode; - - union { - // listening data - struct { - int state; - PasswordListener *listener; - PasswordListener_pwentry pwentry; - sslsocket *sock; - } listen; - // connecting data - struct { - int state; - CERTCertificate *ssl_cert; - SECKEYPrivateKey *ssl_key; - BConnector connector; - sslsocket sock; - BSSLConnection sslcon; - uint64_t password; - SingleStreamSender pwsender; - } connect; - }; - - // socket data - sslsocket *sock; - BSSLConnection sslcon; - - // sending objects - PacketStreamSender output_pss; - - DebugObject d_obj; -} StreamPeerIO; - -/** - * Initializes the object. - * The object is initialized in default state. - * {@link BLog_Init} must have been done. - * {@link BNetwork_GlobalInit} must have been done. - * {@link BSSLConnection_GlobalInit} must have been done if using SSL. - * - * @param pio the object - * @param reactor reactor we live in - * @param twd thread work dispatcher. May be NULL if ssl_flags does not request performing SSL - * operations in threads. - * @param ssl if nonzero, SSL will be used for peer connection - * @param ssl_flags flags passed down to {@link BSSLConnection_MakeBackend}. May be used to - * request performing SSL operations in threads. - * @param ssl_peer_cert if using SSL, the certificate we expect the peer to have - * @param ssl_peer_cert_len if using SSL, the length of the certificate - * @param payload_mtu maximum packet size as seen from the user. Must be >=0. - * @param sock_sndbuf socket SO_SNDBUF option. Specify <=0 to not set it. - * @param user_recv_if interface to use for submitting received packets. Its MTU - * must be >=payload_mtu. - * @param logfunc function which prepends the log prefix using {@link BLog_Append} - * @param handler_error handler function invoked when a connection error occurs - * @param user value to pass to handler functions - * @return 1 on success, 0 on failure - */ -int StreamPeerIO_Init ( - StreamPeerIO *pio, - BReactor *reactor, - BThreadWorkDispatcher *twd, - int ssl, - int ssl_flags, - uint8_t *ssl_peer_cert, - int ssl_peer_cert_len, - int payload_mtu, - int sock_sndbuf, - PacketPassInterface *user_recv_if, - BLog_logfunc logfunc, - StreamPeerIO_handler_error handler_error, - void *user -) WARN_UNUSED; - -/** - * Frees the object. - * - * @param pio the object - */ -void StreamPeerIO_Free (StreamPeerIO *pio); - -/** - * Returns the interface for sending packets to the peer. - * The OTP warning handler may be called from within Send calls - * to the interface. - * - * @param pio the object - * @return interface for sending packets to the peer - */ -PacketPassInterface * StreamPeerIO_GetSendInput (StreamPeerIO *pio); - -/** - * Starts an attempt to connect to the peer. - * On success, the object enters connecting state. - * On failure, the object enters default state. - * - * @param pio the object - * @param addr address to connect to - * @param password identification code to send to the peer - * @param ssl_cert if using SSL, the client certificate to use. This object does not - * take ownership of the certificate; it must remain valid until - * the object is reset. - * @param ssl_key if using SSL, the private key to use. This object does not take - * ownership of the key; it must remain valid until the object is reset. - * @return 1 on success, 0 on failure - */ -int StreamPeerIO_Connect (StreamPeerIO *pio, BAddr addr, uint64_t password, CERTCertificate *ssl_cert, SECKEYPrivateKey *ssl_key) WARN_UNUSED; - -/** - * Starts an attempt to accept a connection from the peer. - * The object enters listening state. - * - * @param pio the object - * @param listener {@link PasswordListener} object to use for accepting a connection. - * The listener must have SSL enabled if and only if this object has - * SSL enabled. The listener must be available until the object is - * reset or {@link StreamPeerIO_handler_up} is called. - * @param password will return the identification code the peer should send when connecting - */ -void StreamPeerIO_Listen (StreamPeerIO *pio, PasswordListener *listener, uint64_t *password); - -#endif diff --git a/v2rayng/badvpn/client/badvpn-client.8 b/v2rayng/badvpn/client/badvpn-client.8 deleted file mode 100644 index 4f41203d95..0000000000 --- a/v2rayng/badvpn/client/badvpn-client.8 +++ /dev/null @@ -1,316 +0,0 @@ -.TH badvpn-client 8 "14 July 2011" -.SH NAME -badvpn-client \- VPN node daemon for the BadVPN peer-to-peer VPN system -.SH SYNOPSIS -.B badvpn-client -.RS -.RB "[" --help "]" -.br -.RB "[" --version "]" -.br -.RB "[" --logger " ]" -.br -(logger=syslog? -.br -.RS -.br -.RB "[" --syslog-facility " ]" -.br -.RB "[" --syslog-ident " ]" -.br -.RE -) -.br -.RB "[" --loglevel " <0-5/none/error/warning/notice/info/debug>]" -.br -.RB "[" --channel-loglevel " <0-5/none/error/warning/notice/info/debug>] ..." -.br -.RB "[" --threads " ]" -.br -.RB "[" --ssl " " --nssdb " " --client-cert-name " ]" -.br -.RB "[" --server-name " ]" -.br -.BR --server-addr " " -.br -.RB "[" --tapdev " ]" -.br -.RB "[" --scope " ] ..." -.br -[ -.br -.RS -.BR --bind-addr " " -.br -.RB "(transport-mode=udp? " --num-ports " )" -.br -.RB "[" --ext-addr " ] ..." -.br -.RE -] ... -.br -.BR --transport-mode " " -.br -(transport-mode=udp? -.br -.RS -.BR --encryption-mode " " -.br -.BR --hash-mode " " -.br -.RB "[" --otp " ]" -.br -.RB "[" --fragmentation-latency " ]" -.br -.RE -) -.br -(transport-mode=tcp? -.br -.RS -.RB "(ssl? [" --peer-ssl "])" -.br -.RB "[" --peer-tcp-socket-sndbuf " ]" -.br -.RE -) -.br -.RB "[" --send-buffer-size " ]" -.br -.RB "[" --send-buffer-relay-size " ]" -.br -.RB "[" --max-macs " ]" -.br -.RB "[" --max-groups " ]" -.br -.RB "[" --igmp-group-membership-interval " ]" -.br -.RB "[" --igmp-last-member-query-time " ]" -.br -.RB "[" --allow-peer-talk-without-ssl "]" -.br -.RE -.SH INTRODUCTION -.P -This page documents the BadVPN client, a daemon for a node in a BadVPN VPN network. -For a general description of BadVPN, see -.BR badvpn (7). -.SH DESCRIPTION -.P -The BadVPN client is a daemon that runs on a VPN node. It opens the TAP device, connects to -the server, then keeps running while attempting to establish data connection to peers and -tranferring data between the TAP device and the peers. Once it initializes, the program only -terminates if it loses connection to the server, or if a signal is received. -.SH OPTIONS -.P -The BadVPN client is configured entirely from command line. -.TP -.BR --help -Print version and command line syntax and exit. -.TP -.BR --version -Print version and exit. -.TP -.BR --logger " " -Select where to log messages. Default is stdout. Syslog is not available on Windows. -.TP -.BR --syslog-facility " " -When logging to syslog, set the logging facility. The facility name must be in lower case. -.TP -.BR --syslog-ident " " -When logging to syslog, set the ident. -.TP -.BR --loglevel " <0-5/none/error/warning/notice/info/debug>" -Set the default logging level. -.TP -.BR --channel-loglevel " <0-5/none/error/warning/notice/info/debug>" -Set the logging level for a specific logging channel. -.TP -.BR --threads " " -Hint for the number of additional threads to use for potentionally long computations (such as -encryption and OTP generation). If zero (0) (default), additional threads will be disabled and all -computations will be done in the event loop. If negative (<0), a guess will be made, possibly -based on the number of CPUs. If positive (>0), the given number of threads will be used. -.TP -.BR --ssl -Use TLS. Requires --nssdb and --server-cert-name. -.TP -.BR --nssdb " " -When using TLS, the NSS database to use. Probably something like sql:/some/folder. -.TP -.BR --client-cert-name " " -When using TLS, the name of the certificate to use. The certificate must be readily accessible. -.TP -.BR --server-name " " -Set the name of the server used for validating the server's certificate. The server name defaults -to the the name in the server address (or a numeric address). -.TP -.BR --server-addr " " -Set the address for the server to listen on. See below for address format. -.TP -.BR --tapdev " " -Set the TAP device to use. See below on how to configure the device. A TAP device is a virtual card -in the operating system, but rather than receiving from and sending frames to a piece of hardware, -a program (this one) opens it to read from and write frames into. If the VPN network is set up correctly, -the TAP devices on the VPN nodes will act as if they were all connected into a network switch. -.TP -.BR --scope " " -Add an address scope allowed for connecting to peers. May be specified multiple times to add multiple -scopes. The order of the scopes is irrelevant. Note that it must actually be possible to connect -to addresses in the given scope; when another peer binds for us to connect to, we choose the first -external address whose scope we recognize, and do not attempt further external addresses, even if -establishing the connection fails. -.TP -.BR --bind-addr " " -Add an address to allow binding on. See below for address format. When attempting to bind in order -for some peer to connect to us, the addresses will be tried in the order they are specified. If UDP -data transport is being used, a --num-ports option must follow to specify how many continuous ports -to allow binding to. For the address to be useful, one or more --ext-addr options must follow. -Note that when two peers need to establish a data connection, it is arbitrary which one will attempt -to bind first. -.TP -.BR --num-ports " " -When using UDP transport, set the number of continuous ports for a previously specified bind address. -Must follow a previous --bind-addr option. -.TP -.BR --ext-addr " " -Add an external address for a previously specified bind address. Must follow a previous --bind-addr -option. May be specified multiple times to add multiple external addresses. See below for address -format. Additionally, the IP address part can be {server_reported} to use the IPv4 address as the -server sees us. The external addresses are tried by the connecting peer in the order they are specified. -Note that the connecting peer only attempts to connect to the first address whose scope it recognizes -and does not try other addresses. This means that all addresses must work for be able to communicate. -.TP -.BR --transport-mode " " -Sets the transport protocol for data connections. UDP is recommended and works best for most networks. -TCP can be used instead if the underlying network has high packet loss which your virtual network -cannot tolerate. Must match on all peers. -.TP -.BR --encryption-mode " " -When using UDP transport, sets the encryption mode. None means no encryption, other options mean -a specific cipher. Note that encryption is only useful if clients use TLS to connect to the server. -The encryption mode must match on all peers. -.TP -.BR --hash-mode " " -When using UDP transport, sets the hashing mode. None means no hashes, other options mean a specific -type of hash. Note that hashing is only useful if encryption is used as well. The hash mode must -match on all peers. -.TP -.BR --otp " " -When using UDP transport, enables one-time passwords. The first argument specifies a block cipher -used to generate passwords from a seed. The second argument specifies how many passwords are -generated from a single seed. The third argument specifies after how many passwords used up for -sending packets an attempt is made to negotiate a new seed with the other peer. num must be >0, -and num-warn must be >0 and <=num. The difference (num - num-warn) should be large enough to allow -a new seed to be negotiated before the sender runs out of passwords. Negotiating a seed involves -the sending peer sending it to the receiving peer via the server and the receiving peer confirming -it via the server. Note that one-time passwords are only useful if clients use TLS to connect to the -server. The OTP option must match on all peers, except for num-warn. -.TP -.BR --fragmentation-latency " " -When using UDP transport, sets the maximum latency to sacrifice in order to pack frames into data -packets more efficiently. If it is >=0, a timer of that many milliseconds is used to wait for further -frames to put into an incomplete packet since the first chunk of the packet was written. If it is -<0, packets are sent out immediately. Defaults to 0, which is the recommended setting. -.TP -.BR --peer-ssl -When using TCP transport, enables TLS for data connections. Requires using TLS for server connection. -For this to work, the peers must trust each others' cerificates, and the cerificates must grant the -TLS server usage context. This option must match on all peers. -.TP -.BR --peer-tcp-socket-sndbuf " " -Sets the value of the SO_SNDBUF socket option for peer TCP sockets (zero to not set). Lower values -will improve fairness when data from multiple sources (local and relaying) is being sent to a -given peer, but may result in lower bandwidth if the network's bandwidth-delay product is too big. -.TP -.BR --send-buffer-size " " -Sets the minimum size of the peers' send buffers for sending frames originating from this system, in -number of packets. -.TP -.BR --send-buffer-relay-size " " -Sets the minimum size of the peers' send buffers for relaying frames from other peers, in number of -packets. -.TP -.BR --max-macs " " -Sets the maximum number of MAC addresses to remember for a peer. When the number is exceeded, the least -recently used slot will be reused. -.TP -.BR --max-groups " " -Sets the maximum number of IGMP group memberships to remember for a peer. When the number is exceeded, -the least recently used slot will be reused. -.TP -.BR --igmp-group-membership-interval " " -Sets the Group Membership Interval parameter for IGMP snooping, in milliseconds. -.TP -.BR --igmp-last-member-query-time " " -Sets the Last Member Query Time parameter for IGMP snooping, in milliseconds. -.TP -.BR --allow-peer-talk-without-ssl -When SSL is enabled, the clients not only connect to the server using SSL, but also exchange messages through -the server through another layer of SSL. This protects the messages from attacks on the server. Older versions -of BadVPN (<1.999.109), however, do not support this. This option allows older and newer clients to -interoperate by not using SSL if the other peer does not support it. It does however negate the security -benefits of using SSL, since the (potentionally compromised) server can then order peers not to use SSL. -.SH "EXIT CODE" -.P -If initialization fails, exits with code 1. Otherwise runs until termination is requested or server connection -is broken and exits with code 1. -.SH "ADDRESS FORMAT" -.P -Addresses have the form ipaddr:port, where ipaddr is either an IPv4 address (name or numeric), or an -IPv6 address enclosed in brackets [] (name or numeric again). -.SH "TAP DEVICE CONFIGURATION" -.P -To use this program, you first have to configure a TAP network device that will act as an endpoint for -the virtual network. The configuration depends on your operating system. -.P -Note that the client program does not configure the TAP device in any way; it only reads and writes -frames from/to it. You are responsible for configuring it (e.g. putting it up and setting its IP address). -.P -.B Linux -.P -You need to enable the kernel configuration option CONFIG_TUN. If you enabled it as a module, you may -have to load it (`modprobe tun`) before you can create the device. -.P -Then you should create a persistent TAP device for the VPN client program to open. This can be done with -either the -.B tunctl -or the -.B openvpn -program. The device will be associated with a user account that will have permission to use it, which should -be the same user as the client program will run as (not root!). To create the device with tunctl, use `tunctl -u -t tapN`, -and to create it with openvpn, use `openvpn --mktun --user --dev tapN`, where N is a number that identifies the -TAP device. -.P -Once the TAP device is created, pass `--tapdev tapN` to the client program to make it use this device. Note that the -device will not be preserved across a shutdown of the system; consult your OS documentaton if you want to automate -the creation or configuration of the device. -.P -.B Windows -.P -Windows does not come with a TAP driver. The client program uses the TAP-Win32 driver, which is part of OpenVPN. -You need to install the OpenVPN open source (!) version, and in the installer enable at least the -`TAP Virtual Ethernet Adapter` and `Add Shortcuts to Start Menu` options. -You can get the installer at -.br -. -.P -The OpenVPN installer automatically creates one TAP device on your system when it's run for the first time. -To create another device, use `Programs -> OpenVPN -> Utilities -> Add a new TAP virtual ethernet adapter`. -You may have to install OpenVPN once again to make this shortcut appear. -.P -Once you have a TAP device, you can configure it like a physical network card. You can recognize TAP devices -by their `Device Name` field. -.P -To use the device, pass `--tapdev ":"` to the client program, where is the name of -the TAP driver (tap0901 for OpenVPN 2.1 and 2.2) (case sensitive), and is the (human) name of the TAP -network interface (e.g. `Local Area Connection 2`). -.SH "EXAMPLES" -.P -For examples of using BadVPN, see -.BR badvpn (7). -.SH "SEE ALSO" -.BR badvpn-server (8), -.BR badvpn (7) -.SH AUTHORS -Ambroz Bizjak diff --git a/v2rayng/badvpn/client/client.c b/v2rayng/badvpn/client/client.c deleted file mode 100644 index 2729d6b84a..0000000000 --- a/v2rayng/badvpn/client/client.c +++ /dev/null @@ -1,2997 +0,0 @@ -/** - * @file client.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BADVPN_USE_WINAPI -#include -#endif - -#include - -#include - -#define TRANSPORT_MODE_UDP 0 -#define TRANSPORT_MODE_TCP 1 - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -// command-line options -struct ext_addr_option { - char *addr; - char *scope; -}; -struct bind_addr_option { - char *addr; - int num_ports; - int num_ext_addrs; - struct ext_addr_option ext_addrs[MAX_EXT_ADDRS]; -}; -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - int threads; - int use_threads_for_ssl_handshake; - int use_threads_for_ssl_data; - int ssl; - char *nssdb; - char *client_cert_name; - char *server_name; - char *server_addr; - char *tapdev; - int num_scopes; - char *scopes[MAX_SCOPES]; - int num_bind_addrs; - struct bind_addr_option bind_addrs[MAX_BIND_ADDRS]; - int transport_mode; - int encryption_mode; - int hash_mode; - int otp_mode; - int otp_num; - int otp_num_warn; - int fragmentation_latency; - int peer_ssl; - int peer_tcp_socket_sndbuf; - int send_buffer_size; - int send_buffer_relay_size; - int max_macs; - int max_groups; - int igmp_group_membership_interval; - int igmp_last_member_query_time; - int allow_peer_talk_without_ssl; - int max_peers; -} options; - -// bind addresses -struct ext_addr { - int server_reported_port; - BAddr addr; // if server_reported_port>=0, defined only after hello received - char scope[64]; -}; -struct bind_addr { - BAddr addr; - int num_ports; - int num_ext_addrs; - struct ext_addr ext_addrs[MAX_EXT_ADDRS]; -}; -int num_bind_addrs; -struct bind_addr bind_addrs[MAX_BIND_ADDRS]; - -// TCP listeners -PasswordListener listeners[MAX_BIND_ADDRS]; - -// SPProto parameters (UDP only) -struct spproto_security_params sp_params; - -// server address we connect to -BAddr server_addr; - -// server name to use for SSL -char server_name[256]; - -// reactor -BReactor ss; - -// thread work dispatcher -BThreadWorkDispatcher twd; - -// client certificate if using SSL -CERTCertificate *client_cert; - -// client private key if using SSL -SECKEYPrivateKey *client_key; - -// device -BTap device; -int device_mtu; - -// DataProtoSource for device input (reading) -DataProtoSource device_dpsource; - -// DPReceiveDevice for device output (writing) -DPReceiveDevice device_output_dprd; - -// data communication MTU -int data_mtu; - -// peers list -LinkedList1 peers; -int num_peers; - -// frame decider -FrameDecider frame_decider; - -// peers that can be user as relays -LinkedList1 relays; - -// peers than need a relay -LinkedList1 waiting_relay_peers; - -// server connection -ServerConnection server; - -// my ID, defined only after server_ready -peerid_t my_id; - -// fair queue for sending peer messages to the server -PacketPassFairQueue server_queue; - -// whether server is ready -int server_ready; - -// dying server flow -struct server_flow *dying_server_flow; - -// stops event processing, causing the program to exit -static void terminate (void); - -// prints program name and version to standard output -static void print_help (const char *name); - -// prints program name and version to standard output -static void print_version (void); - -// parses the command line -static int parse_arguments (int argc, char *argv[]); - -// processes certain command line options -static int process_arguments (void); - -static int ssl_flags (void); - -// handler for program termination request -static void signal_handler (void *unused); - -// adds a new peer -static void peer_add (peerid_t id, int flags, const uint8_t *cert, int cert_len); - -// removes a peer -static void peer_remove (struct peer_data *peer, int exiting); - -// appends the peer log prefix to the logger -static void peer_logfunc (struct peer_data *peer); - -// passes a message to the logger, prepending it info about the peer -static void peer_log (struct peer_data *peer, int level, const char *fmt, ...); - -// see if we are the master relative to this peer -static int peer_am_master (struct peer_data *peer); - -// frees PeerChat, disconnecting it from the server flow -static void peer_free_chat (struct peer_data *peer); - -// initializes the link -static int peer_init_link (struct peer_data *peer); - -// frees link resources -static void peer_free_link (struct peer_data *peer); - -// frees link, relaying, waiting relaying -static void peer_cleanup_connections (struct peer_data *peer); - -// registers the peer as a relay provider -static void peer_enable_relay_provider (struct peer_data *peer); - -// unregisters the peer as a relay provider -static void peer_disable_relay_provider (struct peer_data *peer); - -// install relaying for a peer -static void peer_install_relaying (struct peer_data *peer, struct peer_data *relay); - -// uninstall relaying for a peer -static void peer_free_relaying (struct peer_data *peer); - -// handle a peer that needs a relay -static void peer_need_relay (struct peer_data *peer); - -// inserts the peer into the need relay list -static void peer_register_need_relay (struct peer_data *peer); - -// removes the peer from the need relay list -static void peer_unregister_need_relay (struct peer_data *peer); - -// handle a link setup failure -static void peer_reset (struct peer_data *peer); - -// fees chat and sends resetpeer -static void peer_resetpeer (struct peer_data *peer); - -// chat handlers -static void peer_chat_handler_error (struct peer_data *peer); -static void peer_chat_handler_message (struct peer_data *peer, uint8_t *data, int data_len); - -// handlers for different message types -static void peer_msg_youconnect (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_cannotconnect (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_cannotbind (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_seed (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_confirmseed (struct peer_data *peer, uint8_t *data, int data_len); -static void peer_msg_youretry (struct peer_data *peer, uint8_t *data, int data_len); - -// handler from DatagramPeerIO when we should generate a new OTP send seed -static void peer_udp_pio_handler_seed_warning (struct peer_data *peer); - -// handler from DatagramPeerIO when a new OTP seed can be recognized once it was provided to it -static void peer_udp_pio_handler_seed_ready (struct peer_data *peer); - -// handler from DatagramPeerIO when an error occurs on the connection -static void peer_udp_pio_handler_error (struct peer_data *peer); - -// handler from StreamPeerIO when an error occurs on the connection -static void peer_tcp_pio_handler_error (struct peer_data *peer); - -// peer retry timer handler. The timer is used only on the master side, -// wither when we detect an error, or the peer reports an error. -static void peer_reset_timer_handler (struct peer_data *peer); - -// start binding, according to the protocol -static void peer_start_binding (struct peer_data *peer); - -// tries binding on one address, according to the protocol -static void peer_bind (struct peer_data *peer); - -static void peer_bind_one_address (struct peer_data *peer, int addr_index, int *cont); - -static void peer_connect (struct peer_data *peer, BAddr addr, uint8_t *encryption_key, uint64_t password); - -static int peer_start_msg (struct peer_data *peer, void **data, int type, int len); - -static void peer_end_msg (struct peer_data *peer); - -// sends a message with no payload to the peer -static void peer_send_simple (struct peer_data *peer, int msgid); - -static void peer_send_conectinfo (struct peer_data *peer, int addr_index, int port_adjust, uint8_t *enckey, uint64_t pass); - -static void peer_send_confirmseed (struct peer_data *peer, uint16_t seed_id); - -// handler for peer DataProto up state changes -static void peer_dataproto_handler (struct peer_data *peer, int up); - -// looks for a peer with the given ID -static struct peer_data * find_peer_by_id (peerid_t id); - -// device error handler -static void device_error_handler (void *unused); - -// DataProtoSource handler for packets from the device -static void device_dpsource_handler (void *unused, const uint8_t *frame, int frame_len); - -// assign relays to clients waiting for them -static void assign_relays (void); - -// checks if the given address scope is known (i.e. we can connect to an address in it) -static char * address_scope_known (uint8_t *name, int name_len); - -// handlers for server messages -static void server_handler_error (void *user); -static void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip); -static void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len); -static void server_handler_endclient (void *user, peerid_t peer_id); -static void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len); - -// jobs -static void peer_job_send_seed (struct peer_data *peer); -static void peer_job_init (struct peer_data *peer); - -// server flows -static struct server_flow * server_flow_init (void); -static void server_flow_free (struct server_flow *flow); -static void server_flow_die (struct server_flow *flow); -static void server_flow_qflow_handler_busy (struct server_flow *flow); -static void server_flow_connect (struct server_flow *flow, PacketRecvInterface *input); -static void server_flow_disconnect (struct server_flow *flow); - -int main (int argc, char *argv[]) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - if (options.ssl) { - // init NSPR - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - // register local NSPR file types - if (!DummyPRFileDesc_GlobalInit()) { - BLog(BLOG_ERROR, "DummyPRFileDesc_GlobalInit failed"); - goto fail01; - } - if (!BSSLConnection_GlobalInit()) { - BLog(BLOG_ERROR, "BSSLConnection_GlobalInit failed"); - goto fail01; - } - - // init NSS - if (NSS_Init(options.nssdb) != SECSuccess) { - BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError()); - goto fail01; - } - - // set cipher policy - if (NSS_SetDomesticPolicy() != SECSuccess) { - BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // init server cache - if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError()); - goto fail02; - } - - // open server certificate and private key - if (!open_nss_cert_and_key(options.client_cert_name, &client_cert, &client_key)) { - BLog(BLOG_ERROR, "Cannot open certificate and key"); - goto fail03; - } - } - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // init time - BTime_Init(); - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // init thread work dispatcher - if (!BThreadWorkDispatcher_Init(&twd, &ss, options.threads)) { - BLog(BLOG_ERROR, "BThreadWorkDispatcher_Init failed"); - goto fail3; - } - - // init BSecurity - if (BThreadWorkDispatcher_UsingThreads(&twd)) { - if (!BSecurity_GlobalInitThreadSafe()) { - BLog(BLOG_ERROR, "BSecurity_GlobalInitThreadSafe failed"); - goto fail4; - } - } - - // init listeners - int num_listeners = 0; - if (options.transport_mode == TRANSPORT_MODE_TCP) { - while (num_listeners < num_bind_addrs) { - struct bind_addr *addr = &bind_addrs[num_listeners]; - if (!PasswordListener_Init(&listeners[num_listeners], &ss, &twd, addr->addr, TCP_MAX_PASSWORD_LISTENER_CLIENTS, options.peer_ssl, ssl_flags(), client_cert, client_key)) { - BLog(BLOG_ERROR, "PasswordListener_Init failed"); - goto fail8; - } - num_listeners++; - } - } - - // init device - if (!BTap_Init(&device, &ss, options.tapdev, device_error_handler, NULL, 0)) { - BLog(BLOG_ERROR, "BTap_Init failed"); - goto fail8; - } - - // remember device MTU - device_mtu = BTap_GetMTU(&device); - - BLog(BLOG_INFO, "device MTU is %d", device_mtu); - - // calculate data MTU - if (device_mtu > INT_MAX - DATAPROTO_MAX_OVERHEAD) { - BLog(BLOG_ERROR, "Device MTU is too large"); - goto fail9; - } - data_mtu = DATAPROTO_MAX_OVERHEAD + device_mtu; - - // init device input - if (!DataProtoSource_Init(&device_dpsource, BTap_GetOutput(&device), device_dpsource_handler, NULL, &ss)) { - BLog(BLOG_ERROR, "DataProtoSource_Init failed"); - goto fail9; - } - - // init device output - if (!DPReceiveDevice_Init(&device_output_dprd, device_mtu, (DPReceiveDevice_output_func)BTap_Send, &device, &ss, options.send_buffer_relay_size, PEER_RELAY_FLOW_INACTIVITY_TIME)) { - BLog(BLOG_ERROR, "DPReceiveDevice_Init failed"); - goto fail10; - } - - // init peers list - LinkedList1_Init(&peers); - num_peers = 0; - - // init frame decider - FrameDecider_Init(&frame_decider, options.max_macs, options.max_groups, options.igmp_group_membership_interval, options.igmp_last_member_query_time, &ss); - - // init relays list - LinkedList1_Init(&relays); - - // init need relay list - LinkedList1_Init(&waiting_relay_peers); - - // start connecting to server - if (!ServerConnection_Init(&server, &ss, &twd, server_addr, SC_KEEPALIVE_INTERVAL, SERVER_BUFFER_MIN_PACKETS, options.ssl, ssl_flags(), client_cert, client_key, server_name, NULL, - server_handler_error, server_handler_ready, server_handler_newclient, server_handler_endclient, server_handler_message - )) { - BLog(BLOG_ERROR, "ServerConnection_Init failed"); - goto fail11; - } - - // set server not ready - server_ready = 0; - - // set no dying flow - dying_server_flow = NULL; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - if (server_ready) { - // allow freeing server queue flows - PacketPassFairQueue_PrepareFree(&server_queue); - - // make ServerConnection stop using buffers from peers before they are freed - ServerConnection_ReleaseBuffers(&server); - } - - // free peers - LinkedList1Node *node; - while (node = LinkedList1_GetFirst(&peers)) { - struct peer_data *peer = UPPER_OBJECT(node, struct peer_data, list_node); - peer_remove(peer, 1); - } - - // free dying server flow - if (dying_server_flow) { - server_flow_free(dying_server_flow); - } - - if (server_ready) { - PacketPassFairQueue_Free(&server_queue); - } - ServerConnection_Free(&server); -fail11: - FrameDecider_Free(&frame_decider); - DPReceiveDevice_Free(&device_output_dprd); -fail10: - DataProtoSource_Free(&device_dpsource); -fail9: - BTap_Free(&device); -fail8: - if (options.transport_mode == TRANSPORT_MODE_TCP) { - while (num_listeners-- > 0) { - PasswordListener_Free(&listeners[num_listeners]); - } - } - if (BThreadWorkDispatcher_UsingThreads(&twd)) { - BSecurity_GlobalFreeThreadSafe(); - } -fail4: - // NOTE: BThreadWorkDispatcher must be freed before NSPR and stuff - BThreadWorkDispatcher_Free(&twd); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&ss); -fail1: - if (options.ssl) { - CERT_DestroyCertificate(client_cert); - SECKEY_DestroyPrivateKey(client_key); -fail03: - ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess) -fail02: - SSL_ClearSessionCache(); - ASSERT_FORCE(NSS_Shutdown() == SECSuccess) -fail01: - ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS) - PL_ArenaFinish(); - } - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish objects - DebugObjectGlobal_Finish(); - return 1; -} - -void terminate (void) -{ - BLog(BLOG_NOTICE, "tearing down"); - - // exit event loop - BReactor_Quit(&ss, 0); -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility ]\n" - " [--syslog-ident ]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--threads ]\n" - " [--use-threads-for-ssl-handshake]\n" - " [--use-threads-for-ssl-data]\n" - " [--ssl --nssdb --client-cert-name ]\n" - " [--server-name ]\n" - " --server-addr \n" - " [--tapdev ]\n" - " [--scope ] ...\n" - " [\n" - " --bind-addr \n" - " (transport-mode=udp? --num-ports )\n" - " [--ext-addr ] ...\n" - " ] ...\n" - " --transport-mode \n" - " (transport-mode=udp?\n" - " --encryption-mode \n" - " --hash-mode \n" - " [--otp ]\n" - " [--fragmentation-latency ]\n" - " )\n" - " (transport-mode=tcp?\n" - " (ssl? [--peer-ssl])\n" - " [--peer-tcp-socket-sndbuf ]\n" - " )\n" - " [--send-buffer-size ]\n" - " [--send-buffer-relay-size ]\n" - " [--max-macs ]\n" - " [--max-groups ]\n" - " [--igmp-group-membership-interval ]\n" - " [--igmp-last-member-query-time ]\n" - " [--allow-peer-talk-without-ssl]\n" - " [--max-peers ]\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.threads = 0; - options.use_threads_for_ssl_handshake = 0; - options.use_threads_for_ssl_data = 0; - options.ssl = 0; - options.nssdb = NULL; - options.client_cert_name = NULL; - options.server_name = NULL; - options.server_addr = NULL; - options.tapdev = NULL; - options.num_scopes = 0; - options.num_bind_addrs = 0; - options.transport_mode = -1; - options.encryption_mode = -1; - options.hash_mode = -1; - options.otp_mode = SPPROTO_OTP_MODE_NONE; - options.fragmentation_latency = PEER_DEFAULT_UDP_FRAGMENTATION_LATENCY; - options.peer_ssl = 0; - options.peer_tcp_socket_sndbuf = -1; - options.send_buffer_size = PEER_DEFAULT_SEND_BUFFER_SIZE; - options.send_buffer_relay_size = PEER_DEFAULT_SEND_BUFFER_RELAY_SIZE; - options.max_macs = PEER_DEFAULT_MAX_MACS; - options.max_groups = PEER_DEFAULT_MAX_GROUPS; - options.igmp_group_membership_interval = DEFAULT_IGMP_GROUP_MEMBERSHIP_INTERVAL; - options.igmp_last_member_query_time = DEFAULT_IGMP_LAST_MEMBER_QUERY_TIME; - options.allow_peer_talk_without_ssl = 0; - options.max_peers = DEFAULT_MAX_PEERS; - - int have_fragmentation_latency = 0; - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--threads")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.threads = atoi(argv[i + 1]); - i++; - } - else if (!strcmp(arg, "--use-threads-for-ssl-handshake")) { - options.use_threads_for_ssl_handshake = 1; - } - else if (!strcmp(arg, "--use-threads-for-ssl-data")) { - options.use_threads_for_ssl_data = 1; - } - else if (!strcmp(arg, "--ssl")) { - options.ssl = 1; - } - else if (!strcmp(arg, "--nssdb")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.nssdb = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--client-cert-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.client_cert_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--tapdev")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.tapdev = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--scope")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_scopes == MAX_SCOPES) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.scopes[options.num_scopes] = argv[i + 1]; - options.num_scopes++; - i++; - } - else if (!strcmp(arg, "--bind-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_bind_addrs == MAX_BIND_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs]; - addr->addr = argv[i + 1]; - addr->num_ports = -1; - addr->num_ext_addrs = 0; - options.num_bind_addrs++; - i++; - } - else if (!strcmp(arg, "--num-ports")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_bind_addrs == 0) { - fprintf(stderr, "%s: must folow --bind-addr\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs - 1]; - if ((addr->num_ports = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--ext-addr")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - if (options.num_bind_addrs == 0) { - fprintf(stderr, "%s: must folow --bind-addr\n", arg); - return 0; - } - struct bind_addr_option *addr = &options.bind_addrs[options.num_bind_addrs - 1]; - if (addr->num_ext_addrs == MAX_EXT_ADDRS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - struct ext_addr_option *eaddr = &addr->ext_addrs[addr->num_ext_addrs]; - eaddr->addr = argv[i + 1]; - eaddr->scope = argv[i + 2]; - addr->num_ext_addrs++; - i += 2; - } - else if (!strcmp(arg, "--transport-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "udp")) { - options.transport_mode = TRANSPORT_MODE_UDP; - } - else if (!strcmp(arg2, "tcp")) { - options.transport_mode = TRANSPORT_MODE_TCP; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--encryption-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "none")) { - options.encryption_mode = SPPROTO_ENCRYPTION_MODE_NONE; - } - else if (!strcmp(arg2, "blowfish")) { - options.encryption_mode = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(arg2, "aes")) { - options.encryption_mode = BENCRYPTION_CIPHER_AES; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--hash-mode")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "none")) { - options.hash_mode = SPPROTO_HASH_MODE_NONE; - } - else if (!strcmp(arg2, "md5")) { - options.hash_mode = BHASH_TYPE_MD5; - } - else if (!strcmp(arg2, "sha1")) { - options.hash_mode = BHASH_TYPE_SHA1; - } - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--otp")) { - if (3 >= argc - i) { - fprintf(stderr, "%s: requires three arguments\n", arg); - return 0; - } - char *otp_mode = argv[i + 1]; - char *otp_num = argv[i + 2]; - char *otp_num_warn = argv[i + 3]; - if (!strcmp(otp_mode, "blowfish")) { - options.otp_mode = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(otp_mode, "aes")) { - options.otp_mode = BENCRYPTION_CIPHER_AES; - } - else { - fprintf(stderr, "%s: wrong mode\n", arg); - return 0; - } - if ((options.otp_num = atoi(otp_num)) <= 0) { - fprintf(stderr, "%s: wrong num\n", arg); - return 0; - } - options.otp_num_warn = atoi(otp_num_warn); - if (options.otp_num_warn <= 0 || options.otp_num_warn > options.otp_num) { - fprintf(stderr, "%s: wrong num warn\n", arg); - return 0; - } - i += 3; - } - else if (!strcmp(arg, "--fragmentation-latency")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.fragmentation_latency = atoi(argv[i + 1]); - have_fragmentation_latency = 1; - i++; - } - else if (!strcmp(arg, "--peer-ssl")) { - options.peer_ssl = 1; - } - else if (!strcmp(arg, "--peer-tcp-socket-sndbuf")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.peer_tcp_socket_sndbuf = atoi(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--send-buffer-size")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.send_buffer_size = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--send-buffer-relay-size")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.send_buffer_relay_size = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-macs")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_macs = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-groups")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_groups = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--igmp-group-membership-interval")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.igmp_group_membership_interval = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--igmp-last-member-query-time")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.igmp_last_member_query_time = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-peers")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_peers = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--allow-peer-talk-without-ssl")) { - options.allow_peer_talk_without_ssl = 1; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (options.ssl != !!options.nssdb) { - fprintf(stderr, "False: --ssl <=> --nssdb\n"); - return 0; - } - - if (options.ssl != !!options.client_cert_name) { - fprintf(stderr, "False: --ssl <=> --client-cert-name\n"); - return 0; - } - - if (!options.server_addr) { - fprintf(stderr, "False: --server-addr\n"); - return 0; - } - - if (options.transport_mode < 0) { - fprintf(stderr, "False: --transport-mode\n"); - return 0; - } - - if ((options.transport_mode == TRANSPORT_MODE_UDP) != (options.encryption_mode >= 0)) { - fprintf(stderr, "False: UDP <=> --encryption-mode\n"); - return 0; - } - - if ((options.transport_mode == TRANSPORT_MODE_UDP) != (options.hash_mode >= 0)) { - fprintf(stderr, "False: UDP <=> --hash-mode\n"); - return 0; - } - - if (!(!(options.otp_mode != SPPROTO_OTP_MODE_NONE) || (options.transport_mode == TRANSPORT_MODE_UDP))) { - fprintf(stderr, "False: --otp => UDP\n"); - return 0; - } - - if (!(!have_fragmentation_latency || (options.transport_mode == TRANSPORT_MODE_UDP))) { - fprintf(stderr, "False: --fragmentation-latency => UDP\n"); - return 0; - } - - if (!(!options.peer_ssl || (options.ssl && options.transport_mode == TRANSPORT_MODE_TCP))) { - fprintf(stderr, "False: --peer-ssl => (--ssl && TCP)\n"); - return 0; - } - - if (!(!(options.peer_tcp_socket_sndbuf >= 0) || options.transport_mode == TRANSPORT_MODE_TCP)) { - fprintf(stderr, "False: --peer-tcp-socket-sndbuf => TCP\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve server address - ASSERT(options.server_addr) - if (!BAddr_Parse(&server_addr, options.server_addr, server_name, sizeof(server_name))) { - BLog(BLOG_ERROR, "server addr: BAddr_Parse failed"); - return 0; - } - - // override server name if requested - if (options.server_name) { - if (strlen(options.server_name) >= sizeof(server_name)) { - BLog(BLOG_ERROR, "server name: too long"); - return 0; - } - strcpy(server_name, options.server_name); - } - - // resolve bind addresses and external addresses - num_bind_addrs = 0; - for (int i = 0; i < options.num_bind_addrs; i++) { - struct bind_addr_option *addr = &options.bind_addrs[i]; - struct bind_addr *out = &bind_addrs[num_bind_addrs]; - - // read addr - if (!BAddr_Parse(&out->addr, addr->addr, NULL, 0)) { - BLog(BLOG_ERROR, "bind addr: BAddr_Parse failed"); - return 0; - } - - // read num ports - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (addr->num_ports < 0) { - BLog(BLOG_ERROR, "bind addr: num ports missing"); - return 0; - } - out->num_ports = addr->num_ports; - } - else if (addr->num_ports >= 0) { - BLog(BLOG_ERROR, "bind addr: num ports given, but not using UDP"); - return 0; - } - - // read ext addrs - out->num_ext_addrs = 0; - for (int j = 0; j < addr->num_ext_addrs; j++) { - struct ext_addr_option *eaddr = &addr->ext_addrs[j]; - struct ext_addr *eout = &out->ext_addrs[out->num_ext_addrs]; - - // read addr - if (string_begins_with(eaddr->addr, "{server_reported}:")) { - char *colon = strstr(eaddr->addr, ":"); - if ((eout->server_reported_port = atoi(colon + 1)) < 0) { - BLog(BLOG_ERROR, "ext addr: wrong port"); - return 0; - } - } else { - eout->server_reported_port = -1; - if (!BAddr_Parse(&eout->addr, eaddr->addr, NULL, 0)) { - BLog(BLOG_ERROR, "ext addr: BAddr_Parse failed"); - return 0; - } - if (!addr_supported(eout->addr)) { - BLog(BLOG_ERROR, "ext addr: addr_supported failed"); - return 0; - } - } - - // read scope - if (strlen(eaddr->scope) >= sizeof(eout->scope)) { - BLog(BLOG_ERROR, "ext addr: too long"); - return 0; - } - strcpy(eout->scope, eaddr->scope); - - out->num_ext_addrs++; - } - - num_bind_addrs++; - } - - // initialize SPProto parameters - if (options.transport_mode == TRANSPORT_MODE_UDP) { - sp_params.encryption_mode = options.encryption_mode; - sp_params.hash_mode = options.hash_mode; - sp_params.otp_mode = options.otp_mode; - if (options.otp_mode > 0) { - sp_params.otp_num = options.otp_num; - } - } - - return 1; -} - -int ssl_flags (void) -{ - int flags = 0; - if (options.use_threads_for_ssl_handshake) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_HANDSHAKE; - } - if (options.use_threads_for_ssl_data) { - flags |= BSSLCONNECTION_FLAG_THREADWORK_IO; - } - return flags; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - terminate(); -} - -void peer_add (peerid_t id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - ASSERT(num_peers < options.max_peers) - ASSERT(!find_peer_by_id(id)) - ASSERT(id != my_id) - ASSERT(cert_len >= 0) - ASSERT(cert_len <= SCID_NEWCLIENT_MAX_CERT_LEN) - - // allocate structure - struct peer_data *peer = (struct peer_data *)malloc(sizeof(*peer)); - if (!peer) { - BLog(BLOG_ERROR, "peer %d: failed to allocate memory", (int)id); - goto fail0; - } - - // remember id - peer->id = id; - - // remember flags - peer->flags = flags; - - // set no common name - peer->common_name = NULL; - - if (options.ssl) { - // remember certificate - memcpy(peer->cert, cert, cert_len); - peer->cert_len = cert_len; - - // make sure that CERT_DecodeCertFromPackage will interpretet the input as raw DER and not base64, - // in which case following workaroud wouldn't help - if (!(cert_len > 0 && (cert[0] & 0x1f) == 0x10)) { - peer_log(peer, BLOG_ERROR, "certificate does not look like DER"); - goto fail1; - } - - // copy the certificate and append it a good load of zero bytes, - // hopefully preventing the crappy CERT_DecodeCertFromPackage from crashing - // by reading past the of its input - uint8_t *certbuf = (uint8_t *)malloc(cert_len + 100); - if (!certbuf) { - peer_log(peer, BLOG_ERROR, "malloc failed"); - goto fail1; - } - memcpy(certbuf, cert, cert_len); - memset(certbuf + cert_len, 0, 100); - - // decode certificate, so we can extract the common name - CERTCertificate *nsscert = CERT_DecodeCertFromPackage((char *)certbuf, cert_len); - if (!nsscert) { - peer_log(peer, BLOG_ERROR, "CERT_DecodeCertFromPackage failed (%d)", PORT_GetError()); - free(certbuf); - goto fail1; - } - - free(certbuf); - - // remember common name - if (!(peer->common_name = CERT_GetCommonName(&nsscert->subject))) { - peer_log(peer, BLOG_ERROR, "CERT_GetCommonName failed"); - CERT_DestroyCertificate(nsscert); - goto fail1; - } - - CERT_DestroyCertificate(nsscert); - } - - // init and set init job (must be before initing server flow so we can send) - BPending_Init(&peer->job_init, BReactor_PendingGroup(&ss), (BPending_handler)peer_job_init, peer); - BPending_Set(&peer->job_init); - - // init server flow - if (!(peer->server_flow = server_flow_init())) { - peer_log(peer, BLOG_ERROR, "server_flow_init failed"); - goto fail2; - } - - if ((peer->flags & SCID_NEWCLIENT_FLAG_SSL) && !options.ssl) { - peer_log(peer, BLOG_ERROR, "peer requires talking with SSL, but we're not using SSL!?"); - goto fail3; - } - - if (options.ssl && !(peer->flags & SCID_NEWCLIENT_FLAG_SSL) && !options.allow_peer_talk_without_ssl) { - peer_log(peer, BLOG_ERROR, "peer requires talking without SSL, but we don't allow that"); - goto fail3; - } - - // choose chat SSL mode - int chat_ssl_mode = PEERCHAT_SSL_NONE; - if ((peer->flags & SCID_NEWCLIENT_FLAG_SSL)) { - chat_ssl_mode = (peer_am_master(peer) ? PEERCHAT_SSL_SERVER : PEERCHAT_SSL_CLIENT); - } - - // init chat - if (!PeerChat_Init(&peer->chat, peer->id, chat_ssl_mode, ssl_flags(), client_cert, client_key, peer->cert, peer->cert_len, BReactor_PendingGroup(&ss), &twd, peer, - (BLog_logfunc)peer_logfunc, - (PeerChat_handler_error)peer_chat_handler_error, - (PeerChat_handler_message)peer_chat_handler_message - )) { - peer_log(peer, BLOG_ERROR, "PeerChat_Init failed"); - goto fail3; - } - - // set no message - peer->chat_send_msg_len = -1; - - // connect server flow to chat - server_flow_connect(peer->server_flow, PeerChat_GetSendOutput(&peer->chat)); - - // set have chat - peer->have_chat = 1; - - // set have no resetpeer - peer->have_resetpeer = 0; - - // init local flow - if (!DataProtoFlow_Init(&peer->local_dpflow, &device_dpsource, my_id, peer->id, options.send_buffer_size, -1, NULL, NULL)) { - peer_log(peer, BLOG_ERROR, "DataProtoFlow_Init failed"); - goto fail4; - } - - // init frame decider peer - if (!FrameDeciderPeer_Init(&peer->decider_peer, &frame_decider, peer, (BLog_logfunc)peer_logfunc)) { - peer_log(peer, BLOG_ERROR, "FrameDeciderPeer_Init failed"); - goto fail5; - } - - // init receive peer - DPReceivePeer_Init(&peer->receive_peer, &device_output_dprd, peer->id, &peer->decider_peer, !!(peer->flags & SCID_NEWCLIENT_FLAG_RELAY_CLIENT)); - - // have no link - peer->have_link = 0; - - // have no relaying - peer->relaying_peer = NULL; - - // not waiting for relay - peer->waiting_relay = 0; - - // init reset timer - BTimer_Init(&peer->reset_timer, PEER_RETRY_TIME, (BTimer_handler)peer_reset_timer_handler, peer); - - // is not relay server - peer->is_relay = 0; - - // init binding - peer->binding = 0; - - // add to peers list - LinkedList1_Append(&peers, &peer->list_node); - num_peers++; - - switch (chat_ssl_mode) { - case PEERCHAT_SSL_NONE: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in plaintext mode"); - break; - case PEERCHAT_SSL_CLIENT: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in SSL client mode"); - break; - case PEERCHAT_SSL_SERVER: - peer_log(peer, BLOG_INFO, "initialized; talking to peer in SSL server mode"); - break; - } - - return; - -fail5: - DataProtoFlow_Free(&peer->local_dpflow); -fail4: - server_flow_disconnect(peer->server_flow); - PeerChat_Free(&peer->chat); -fail3: - server_flow_free(peer->server_flow); -fail2: - BPending_Free(&peer->job_init); - if (peer->common_name) { - PORT_Free(peer->common_name); - } -fail1: - free(peer); -fail0: - return; -} - -void peer_remove (struct peer_data *peer, int exiting) -{ - peer_log(peer, BLOG_INFO, "removing"); - - // cleanup connections - peer_cleanup_connections(peer); - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - ASSERT(!peer->is_relay) - - // remove from peers list - LinkedList1_Remove(&peers, &peer->list_node); - num_peers--; - - // free reset timer - BReactor_RemoveTimer(&ss, &peer->reset_timer); - - // free receive peer - DPReceivePeer_Free(&peer->receive_peer); - - // free frame decider - FrameDeciderPeer_Free(&peer->decider_peer); - - // free local flow - DataProtoFlow_Free(&peer->local_dpflow); - - // free chat - if (peer->have_chat) { - peer_free_chat(peer); - } - - // free resetpeer - if (peer->have_resetpeer) { - // disconnect resetpeer source from server flow - server_flow_disconnect(peer->server_flow); - - // free resetpeer source - SinglePacketSource_Free(&peer->resetpeer_source); - } - - // free/die server flow - if (exiting || !PacketPassFairQueueFlow_IsBusy(&peer->server_flow->qflow)) { - server_flow_free(peer->server_flow); - } else { - server_flow_die(peer->server_flow); - } - - // free jobs - BPending_Free(&peer->job_init); - - // free common name - if (peer->common_name) { - PORT_Free(peer->common_name); - } - - // free peer structure - free(peer); -} - -void peer_logfunc (struct peer_data *peer) -{ - BLog_Append("peer %d", (int)peer->id); - if (peer->common_name) { - BLog_Append(" (%s)", peer->common_name); - } - BLog_Append(": "); -} - -void peer_log (struct peer_data *peer, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)peer_logfunc, peer, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -int peer_am_master (struct peer_data *peer) -{ - return (my_id > peer->id); -} - -void peer_free_chat (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - - // disconnect chat from server flow - server_flow_disconnect(peer->server_flow); - - // free chat - PeerChat_Free(&peer->chat); - - // set have no chat - peer->have_chat = 0; -} - -int peer_init_link (struct peer_data *peer) -{ - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - ASSERT(!peer->is_relay) - - // init receive receiver - DPReceiveReceiver_Init(&peer->receive_receiver, &peer->receive_peer); - PacketPassInterface *recv_if = DPReceiveReceiver_GetInput(&peer->receive_receiver); - - // init transport-specific link objects - PacketPassInterface *link_if; - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // init DatagramPeerIO - if (!DatagramPeerIO_Init( - &peer->pio.udp.pio, &ss, data_mtu, CLIENT_UDP_MTU, sp_params, - options.fragmentation_latency, PEER_UDP_ASSEMBLER_NUM_FRAMES, recv_if, - options.otp_num_warn, &twd, peer, - (BLog_logfunc)peer_logfunc, - (DatagramPeerIO_handler_error)peer_udp_pio_handler_error, - (DatagramPeerIO_handler_otp_warning)peer_udp_pio_handler_seed_warning, - (DatagramPeerIO_handler_otp_ready)peer_udp_pio_handler_seed_ready - )) { - peer_log(peer, BLOG_ERROR, "DatagramPeerIO_Init failed"); - goto fail1; - } - - if (SPPROTO_HAVE_OTP(sp_params)) { - // init send seed state - peer->pio.udp.sendseed_nextid = 0; - peer->pio.udp.sendseed_sent = 0; - - // init send seed job - BPending_Init(&peer->pio.udp.job_send_seed, BReactor_PendingGroup(&ss), (BPending_handler)peer_job_send_seed, peer); - } - - link_if = DatagramPeerIO_GetSendInput(&peer->pio.udp.pio); - } else { - // init StreamPeerIO - if (!StreamPeerIO_Init( - &peer->pio.tcp.pio, &ss, &twd, options.peer_ssl, ssl_flags(), - (options.peer_ssl ? peer->cert : NULL), - (options.peer_ssl ? peer->cert_len : -1), - data_mtu, - (options.peer_tcp_socket_sndbuf >= 0 ? options.peer_tcp_socket_sndbuf : PEER_DEFAULT_TCP_SOCKET_SNDBUF), - recv_if, - (BLog_logfunc)peer_logfunc, - (StreamPeerIO_handler_error)peer_tcp_pio_handler_error, peer - )) { - peer_log(peer, BLOG_ERROR, "StreamPeerIO_Init failed"); - goto fail1; - } - - link_if = StreamPeerIO_GetSendInput(&peer->pio.tcp.pio); - } - - // init sending - if (!DataProtoSink_Init(&peer->send_dp, &ss, link_if, PEER_KEEPALIVE_INTERVAL, PEER_KEEPALIVE_RECEIVE_TIMER, (DataProtoSink_handler)peer_dataproto_handler, peer)) { - peer_log(peer, BLOG_ERROR, "DataProto_Init failed"); - goto fail2; - } - - // attach local flow to our DataProtoSink - DataProtoFlow_Attach(&peer->local_dpflow, &peer->send_dp); - - // attach receive peer to our DataProtoSink - DPReceivePeer_AttachSink(&peer->receive_peer, &peer->send_dp); - - // set have link - peer->have_link = 1; - - return 1; - -fail2: - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Free(&peer->pio.udp.job_send_seed); - } - DatagramPeerIO_Free(&peer->pio.udp.pio); - } else { - StreamPeerIO_Free(&peer->pio.tcp.pio); - } -fail1: - DPReceiveReceiver_Free(&peer->receive_receiver); - return 0; -} - -void peer_free_link (struct peer_data *peer) -{ - ASSERT(peer->have_link) - ASSERT(!peer->is_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // detach receive peer from our DataProtoSink - DPReceivePeer_DetachSink(&peer->receive_peer); - - // detach local flow from our DataProtoSink - DataProtoFlow_Detach(&peer->local_dpflow); - - // free sending - DataProtoSink_Free(&peer->send_dp); - - // free transport-specific link objects - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Free(&peer->pio.udp.job_send_seed); - } - DatagramPeerIO_Free(&peer->pio.udp.pio); - } else { - StreamPeerIO_Free(&peer->pio.tcp.pio); - } - - // free receive receiver - DPReceiveReceiver_Free(&peer->receive_receiver); - - // set have no link - peer->have_link = 0; -} - -void peer_cleanup_connections (struct peer_data *peer) -{ - if (peer->have_link) { - if (peer->is_relay) { - peer_disable_relay_provider(peer); - } - peer_free_link(peer); - } - else if (peer->relaying_peer) { - peer_free_relaying(peer); - } - else if (peer->waiting_relay) { - peer_unregister_need_relay(peer); - } - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - ASSERT(!peer->is_relay) -} - -void peer_enable_relay_provider (struct peer_data *peer) -{ - ASSERT(peer->have_link) - ASSERT(!peer->is_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // add to relays list - LinkedList1_Append(&relays, &peer->relay_list_node); - - // init users list - LinkedList1_Init(&peer->relay_users); - - // set is relay - peer->is_relay = 1; - - // assign relays - assign_relays(); -} - -void peer_disable_relay_provider (struct peer_data *peer) -{ - ASSERT(peer->is_relay) - - ASSERT(peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->waiting_relay) - - // disconnect relay users - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&peer->relay_users)) { - struct peer_data *relay_user = UPPER_OBJECT(list_node, struct peer_data, relaying_list_node); - ASSERT(relay_user->relaying_peer == peer) - - // disconnect relay user - peer_free_relaying(relay_user); - - // add it to need relay list - peer_register_need_relay(relay_user); - } - - // remove from relays list - LinkedList1_Remove(&relays, &peer->relay_list_node); - - // set is not relay - peer->is_relay = 0; - - // assign relays - assign_relays(); -} - -void peer_install_relaying (struct peer_data *peer, struct peer_data *relay) -{ - ASSERT(!peer->relaying_peer) - ASSERT(!peer->have_link) - ASSERT(!peer->waiting_relay) - ASSERT(relay->is_relay) - - ASSERT(!peer->is_relay) - ASSERT(relay->have_link) - - peer_log(peer, BLOG_INFO, "installing relaying through %d", (int)relay->id); - - // add to relay's users list - LinkedList1_Append(&relay->relay_users, &peer->relaying_list_node); - - // attach local flow to relay - DataProtoFlow_Attach(&peer->local_dpflow, &relay->send_dp); - - // set relaying - peer->relaying_peer = relay; -} - -void peer_free_relaying (struct peer_data *peer) -{ - ASSERT(peer->relaying_peer) - - ASSERT(!peer->have_link) - ASSERT(!peer->waiting_relay) - - struct peer_data *relay = peer->relaying_peer; - ASSERT(relay->is_relay) - ASSERT(relay->have_link) - - peer_log(peer, BLOG_INFO, "uninstalling relaying through %d", (int)relay->id); - - // detach local flow from relay - DataProtoFlow_Detach(&peer->local_dpflow); - - // remove from relay's users list - LinkedList1_Remove(&relay->relay_users, &peer->relaying_list_node); - - // set not relaying - peer->relaying_peer = NULL; -} - -void peer_need_relay (struct peer_data *peer) -{ - ASSERT(!peer->is_relay) - - if (peer->waiting_relay) { - // already waiting for relay, do nothing - return; - } - - if (peer->have_link) { - peer_free_link(peer); - } - else if (peer->relaying_peer) { - peer_free_relaying(peer); - } - - // register the peer as needing a relay - peer_register_need_relay(peer); - - // assign relays - assign_relays(); -} - -void peer_register_need_relay (struct peer_data *peer) -{ - ASSERT(!peer->waiting_relay) - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - - ASSERT(!peer->is_relay) - - // add to need relay list - LinkedList1_Append(&waiting_relay_peers, &peer->waiting_relay_list_node); - - // set waiting relay - peer->waiting_relay = 1; -} - -void peer_unregister_need_relay (struct peer_data *peer) -{ - ASSERT(peer->waiting_relay) - - ASSERT(!peer->have_link) - ASSERT(!peer->relaying_peer) - ASSERT(!peer->is_relay) - - // remove from need relay list - LinkedList1_Remove(&waiting_relay_peers, &peer->waiting_relay_list_node); - - // set not waiting relay - peer->waiting_relay = 0; -} - -void peer_reset (struct peer_data *peer) -{ - peer_log(peer, BLOG_NOTICE, "resetting"); - - // cleanup connections - peer_cleanup_connections(peer); - - if (peer_am_master(peer)) { - // if we're the master, schedule retry - BReactor_SetTimer(&ss, &peer->reset_timer); - } else { - // if we're the slave, report to master - peer_send_simple(peer, MSGID_YOURETRY); - } -} - -void peer_resetpeer (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - ASSERT(!peer->have_resetpeer) - - // free chat - peer_free_chat(peer); - - // build resetpeer packet - struct packetproto_header pp_header; - struct sc_header sc_header; - struct sc_client_resetpeer sc_resetpeer; - pp_header.len = htol16(sizeof(struct sc_header) + sizeof(struct sc_client_resetpeer)); - sc_header.type = htol8(SCID_RESETPEER); - sc_resetpeer.clientid = htol16(peer->id); - memcpy(peer->resetpeer_packet, &pp_header, sizeof(pp_header)); - memcpy(peer->resetpeer_packet + sizeof(pp_header), &sc_header, sizeof(sc_header)); - memcpy(peer->resetpeer_packet + sizeof(pp_header) + sizeof(sc_header), &sc_resetpeer, sizeof(sc_resetpeer)); - - // init resetpeer sourse - SinglePacketSource_Init(&peer->resetpeer_source, peer->resetpeer_packet, sizeof(peer->resetpeer_packet), BReactor_PendingGroup(&ss)); - - // connect server flow to resetpeer source - server_flow_connect(peer->server_flow, SinglePacketSource_GetOutput(&peer->resetpeer_source)); - - // set have resetpeer - peer->have_resetpeer = 1; -} - -void peer_chat_handler_error (struct peer_data *peer) -{ - ASSERT(peer->have_chat) - ASSERT(!peer->have_resetpeer) - - peer_log(peer, BLOG_ERROR, "chat error, sending resetpeer"); - - peer_resetpeer(peer); -} - -void peer_chat_handler_message (struct peer_data *peer, uint8_t *data, int data_len) -{ - ASSERT(peer->have_chat) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // parse message - msgParser parser; - if (!msgParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_NOTICE, "msg: failed to parse"); - return; - } - - // read message - uint16_t type = 0; // to remove warning - ASSERT_EXECUTE(msgParser_Gettype(&parser, &type)) - uint8_t *payload = NULL; // to remove warning - int payload_len = 0; // to remove warning - ASSERT_EXECUTE(msgParser_Getpayload(&parser, &payload, &payload_len)) - - // dispatch according to message type - switch (type) { - case MSGID_YOUCONNECT: - peer_msg_youconnect(peer, payload, payload_len); - return; - case MSGID_CANNOTCONNECT: - peer_msg_cannotconnect(peer, payload, payload_len); - return; - case MSGID_CANNOTBIND: - peer_msg_cannotbind(peer, payload, payload_len); - return; - case MSGID_YOURETRY: - peer_msg_youretry(peer, payload, payload_len); - return; - case MSGID_SEED: - peer_msg_seed(peer, payload, payload_len); - return; - case MSGID_CONFIRMSEED: - peer_msg_confirmseed(peer, payload, payload_len); - return; - default: - BLog(BLOG_NOTICE, "msg: unknown type"); - return; - } -} - -void peer_msg_youconnect (struct peer_data *peer, uint8_t *data, int data_len) -{ - // init parser - msg_youconnectParser parser; - if (!msg_youconnectParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to parse"); - return; - } - - // try addresses - BAddr addr; - while (1) { - // get address message - uint8_t *addrmsg_data; - int addrmsg_len; - if (!msg_youconnectParser_Getaddr(&parser, &addrmsg_data, &addrmsg_len)) { - peer_log(peer, BLOG_NOTICE, "msg_youconnect: no usable addresses"); - peer_send_simple(peer, MSGID_CANNOTCONNECT); - return; - } - - // parse address message - msg_youconnect_addrParser aparser; - if (!msg_youconnect_addrParser_Init(&aparser, addrmsg_data, addrmsg_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to parse address message"); - return; - } - - // check if the address scope is known - uint8_t *name_data = NULL; // to remove warning - int name_len = 0; // to remove warning - ASSERT_EXECUTE(msg_youconnect_addrParser_Getname(&aparser, &name_data, &name_len)) - char *name; - if (!(name = address_scope_known(name_data, name_len))) { - continue; - } - - // read address - uint8_t *addr_data = NULL; // to remove warning - int addr_len = 0; // to remove warning - ASSERT_EXECUTE(msg_youconnect_addrParser_Getaddr(&aparser, &addr_data, &addr_len)) - if (!addr_read(addr_data, addr_len, &addr)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: failed to read address"); - continue; - } - - peer_log(peer, BLOG_NOTICE, "msg_youconnect: using address in scope '%s'", name); - break; - } - - // discard further addresses - msg_youconnectParser_Forwardaddr(&parser); - - uint8_t *key = NULL; - uint64_t password = 0; - - // read additonal parameters - if (options.transport_mode == TRANSPORT_MODE_UDP) { - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - int key_len; - if (!msg_youconnectParser_Getkey(&parser, &key, &key_len)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: no key"); - return; - } - if (key_len != BEncryption_cipher_key_size(sp_params.encryption_mode)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: wrong key size"); - return; - } - } - } else { - if (!msg_youconnectParser_Getpassword(&parser, &password)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: no password"); - return; - } - } - - if (!msg_youconnectParser_GotEverything(&parser)) { - peer_log(peer, BLOG_WARNING, "msg_youconnect: stray data"); - return; - } - - peer_log(peer, BLOG_INFO, "connecting"); - - peer_connect(peer, addr, key, password); -} - -void peer_msg_cannotconnect (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_cannotconnect: invalid length"); - return; - } - - if (!peer->binding) { - peer_log(peer, BLOG_WARNING, "msg_cannotconnect: not binding"); - return; - } - - peer_log(peer, BLOG_INFO, "peer could not connect"); - - // continue trying bind addresses - peer_bind(peer); - return; -} - -void peer_msg_cannotbind (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_cannotbind: invalid length"); - return; - } - - peer_log(peer, BLOG_INFO, "peer cannot bind"); - - if (!peer_am_master(peer)) { - peer_start_binding(peer); - } else { - if (!peer->is_relay) { - peer_need_relay(peer); - } - } -} - -void peer_msg_seed (struct peer_data *peer, uint8_t *data, int data_len) -{ - msg_seedParser parser; - if (!msg_seedParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_seed: failed to parse"); - return; - } - - // read message - uint16_t seed_id = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getseed_id(&parser, &seed_id)) - uint8_t *key = NULL; // to remove warning - int key_len = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getkey(&parser, &key, &key_len)) - uint8_t *iv = NULL; // to remove warning - int iv_len = 0; // to remove warning - ASSERT_EXECUTE(msg_seedParser_Getiv(&parser, &iv, &iv_len)) - - if (options.transport_mode != TRANSPORT_MODE_UDP) { - peer_log(peer, BLOG_WARNING, "msg_seed: not in UDP mode"); - return; - } - - if (!SPPROTO_HAVE_OTP(sp_params)) { - peer_log(peer, BLOG_WARNING, "msg_seed: OTPs disabled"); - return; - } - - if (key_len != BEncryption_cipher_key_size(sp_params.otp_mode)) { - peer_log(peer, BLOG_WARNING, "msg_seed: wrong key length"); - return; - } - - if (iv_len != BEncryption_cipher_block_size(sp_params.otp_mode)) { - peer_log(peer, BLOG_WARNING, "msg_seed: wrong IV length"); - return; - } - - if (!peer->have_link) { - peer_log(peer, BLOG_WARNING, "msg_seed: have no link"); - return; - } - - peer_log(peer, BLOG_DEBUG, "received OTP receive seed"); - - // add receive seed - DatagramPeerIO_AddOTPRecvSeed(&peer->pio.udp.pio, seed_id, key, iv); - - // remember seed ID so we can confirm it from peer_udp_pio_handler_seed_ready - peer->pio.udp.pending_recvseed_id = seed_id; -} - -void peer_msg_confirmseed (struct peer_data *peer, uint8_t *data, int data_len) -{ - msg_confirmseedParser parser; - if (!msg_confirmseedParser_Init(&parser, data, data_len)) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: failed to parse"); - return; - } - - // read message - uint16_t seed_id = 0; // to remove warning - ASSERT_EXECUTE(msg_confirmseedParser_Getseed_id(&parser, &seed_id)) - - if (options.transport_mode != TRANSPORT_MODE_UDP) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: not in UDP mode"); - return; - } - - if (!SPPROTO_HAVE_OTP(sp_params)) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: OTPs disabled"); - return; - } - - if (!peer->have_link) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: have no link"); - return; - } - - if (!peer->pio.udp.sendseed_sent) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: no seed has been sent"); - return; - } - - if (seed_id != peer->pio.udp.sendseed_sent_id) { - peer_log(peer, BLOG_WARNING, "msg_confirmseed: invalid seed: expecting %d, received %d", (int)peer->pio.udp.sendseed_sent_id, (int)seed_id); - return; - } - - peer_log(peer, BLOG_DEBUG, "OTP send seed confirmed"); - - // no longer waiting for confirmation - peer->pio.udp.sendseed_sent = 0; - - // start using the seed - DatagramPeerIO_SetOTPSendSeed(&peer->pio.udp.pio, peer->pio.udp.sendseed_sent_id, peer->pio.udp.sendseed_sent_key, peer->pio.udp.sendseed_sent_iv); -} - -void peer_msg_youretry (struct peer_data *peer, uint8_t *data, int data_len) -{ - if (data_len != 0) { - peer_log(peer, BLOG_WARNING, "msg_youretry: invalid length"); - return; - } - - if (!peer_am_master(peer)) { - peer_log(peer, BLOG_WARNING, "msg_youretry: we are not master"); - return; - } - - peer_log(peer, BLOG_NOTICE, "requests reset"); - - peer_reset(peer); -} - -void peer_udp_pio_handler_seed_warning (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - - // generate and send a new seed - if (!peer->pio.udp.sendseed_sent) { - BPending_Set(&peer->pio.udp.job_send_seed); - } -} - -void peer_udp_pio_handler_seed_ready (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - - // send confirmation - peer_send_confirmseed(peer, peer->pio.udp.pending_recvseed_id); -} - -void peer_udp_pio_handler_error (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(peer->have_link) - - peer_log(peer, BLOG_NOTICE, "UDP connection failed"); - - peer_reset(peer); - return; -} - -void peer_tcp_pio_handler_error (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_TCP) - ASSERT(peer->have_link) - - peer_log(peer, BLOG_NOTICE, "TCP connection failed"); - - peer_reset(peer); - return; -} - -void peer_reset_timer_handler (struct peer_data *peer) -{ - ASSERT(peer_am_master(peer)) - - BLog(BLOG_NOTICE, "retry timer expired"); - - // start setup process - peer_start_binding(peer); -} - -void peer_start_binding (struct peer_data *peer) -{ - peer->binding = 1; - peer->binding_addrpos = 0; - - peer_bind(peer); -} - -void peer_bind (struct peer_data *peer) -{ - ASSERT(peer->binding) - ASSERT(peer->binding_addrpos >= 0) - ASSERT(peer->binding_addrpos <= num_bind_addrs) - - while (peer->binding_addrpos < num_bind_addrs) { - // if there are no external addresses, skip bind address - if (bind_addrs[peer->binding_addrpos].num_ext_addrs == 0) { - peer->binding_addrpos++; - continue; - } - - // try to bind - int cont; - peer_bind_one_address(peer, peer->binding_addrpos, &cont); - - // increment address counter - peer->binding_addrpos++; - - if (!cont) { - return; - } - } - - peer_log(peer, BLOG_NOTICE, "no more addresses to bind to"); - - // no longer binding - peer->binding = 0; - - // tell the peer we failed to bind - peer_send_simple(peer, MSGID_CANNOTBIND); - - // if we are the slave, setup relaying - if (!peer_am_master(peer)) { - if (!peer->is_relay) { - peer_need_relay(peer); - } - } -} - -void peer_bind_one_address (struct peer_data *peer, int addr_index, int *cont) -{ - ASSERT(addr_index >= 0) - ASSERT(addr_index < num_bind_addrs) - ASSERT(bind_addrs[addr_index].num_ext_addrs > 0) - - // get a fresh link - peer_cleanup_connections(peer); - if (!peer_init_link(peer)) { - peer_log(peer, BLOG_ERROR, "cannot get link"); - *cont = 0; - peer_reset(peer); - return; - } - - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // get addr - struct bind_addr *addr = &bind_addrs[addr_index]; - - // try binding to all ports in the range - int port_add; - for (port_add = 0; port_add < addr->num_ports; port_add++) { - BAddr tryaddr = addr->addr; - BAddr_SetPort(&tryaddr, hton16(ntoh16(BAddr_GetPort(&tryaddr)) + port_add)); - if (DatagramPeerIO_Bind(&peer->pio.udp.pio, tryaddr)) { - break; - } - } - if (port_add == addr->num_ports) { - BLog(BLOG_NOTICE, "failed to bind to any port"); - *cont = 1; - return; - } - - uint8_t key[BENCRYPTION_MAX_KEY_SIZE]; - - // generate and set encryption key - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - BRandom_randomize(key, BEncryption_cipher_key_size(sp_params.encryption_mode)); - DatagramPeerIO_SetEncryptionKey(&peer->pio.udp.pio, key); - } - - // schedule sending OTP seed - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Set(&peer->pio.udp.job_send_seed); - } - - // send connectinfo - peer_send_conectinfo(peer, addr_index, port_add, key, 0); - } else { - // order StreamPeerIO to listen - uint64_t pass; - StreamPeerIO_Listen(&peer->pio.tcp.pio, &listeners[addr_index], &pass); - - // send connectinfo - peer_send_conectinfo(peer, addr_index, 0, NULL, pass); - } - - peer_log(peer, BLOG_NOTICE, "bound to address number %d", addr_index); - - *cont = 0; -} - -void peer_connect (struct peer_data *peer, BAddr addr, uint8_t* encryption_key, uint64_t password) -{ - // get a fresh link - peer_cleanup_connections(peer); - if (!peer_init_link(peer)) { - peer_log(peer, BLOG_ERROR, "cannot get link"); - peer_reset(peer); - return; - } - - if (options.transport_mode == TRANSPORT_MODE_UDP) { - // order DatagramPeerIO to connect - if (!DatagramPeerIO_Connect(&peer->pio.udp.pio, addr)) { - peer_log(peer, BLOG_NOTICE, "DatagramPeerIO_Connect failed"); - peer_reset(peer); - return; - } - - // set encryption key - if (SPPROTO_HAVE_ENCRYPTION(sp_params)) { - DatagramPeerIO_SetEncryptionKey(&peer->pio.udp.pio, encryption_key); - } - - // generate and send a send seed - if (SPPROTO_HAVE_OTP(sp_params)) { - BPending_Set(&peer->pio.udp.job_send_seed); - } - } else { - // order StreamPeerIO to connect - if (!StreamPeerIO_Connect(&peer->pio.tcp.pio, addr, password, client_cert, client_key)) { - peer_log(peer, BLOG_NOTICE, "StreamPeerIO_Connect failed"); - peer_reset(peer); - return; - } - } -} - -static int peer_start_msg (struct peer_data *peer, void **data, int type, int len) -{ - ASSERT(len >= 0) - ASSERT(len <= MSG_MAX_PAYLOAD) - ASSERT(!(len > 0) || data) - ASSERT(peer->chat_send_msg_len == -1) - - // make sure we have chat - if (!peer->have_chat) { - peer_log(peer, BLOG_ERROR, "cannot send message, chat is down"); - return 0; - } - -#ifdef SIMULATE_PEER_OUT_OF_BUFFER - uint8_t x; - BRandom_randomize(&x, sizeof(x)); - if (x < SIMULATE_PEER_OUT_OF_BUFFER) { - peer_log(peer, BLOG_ERROR, "simulating out of buffer, sending resetpeer"); - peer_resetpeer(peer); - return 0; - } -#endif - - // obtain buffer location - uint8_t *packet; - if (!PeerChat_StartMessage(&peer->chat, &packet)) { - peer_log(peer, BLOG_ERROR, "cannot send message, out of buffer, sending resetpeer"); - peer_resetpeer(peer); - return 0; - } - - // write fields - msgWriter writer; - msgWriter_Init(&writer, packet); - msgWriter_Addtype(&writer, type); - uint8_t *payload_dst = msgWriter_Addpayload(&writer, len); - msgWriter_Finish(&writer); - - // set have message - peer->chat_send_msg_len = len; - - if (data) { - *data = payload_dst; - } - return 1; -} - -static void peer_end_msg (struct peer_data *peer) -{ - ASSERT(peer->chat_send_msg_len >= 0) - ASSERT(peer->have_chat) - - // submit packet to buffer - PeerChat_EndMessage(&peer->chat, msg_SIZEtype + msg_SIZEpayload(peer->chat_send_msg_len)); - - // set no message - peer->chat_send_msg_len = -1; -} - -void peer_send_simple (struct peer_data *peer, int msgid) -{ - if (!peer_start_msg(peer, NULL, msgid, 0)) { - return; - } - peer_end_msg(peer); -} - -void peer_send_conectinfo (struct peer_data *peer, int addr_index, int port_adjust, uint8_t *enckey, uint64_t pass) -{ - ASSERT(addr_index >= 0) - ASSERT(addr_index < num_bind_addrs) - ASSERT(bind_addrs[addr_index].num_ext_addrs > 0) - - // get address - struct bind_addr *bind_addr = &bind_addrs[addr_index]; - - // remember encryption key size - int key_size = 0; // to remove warning - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - key_size = BEncryption_cipher_key_size(sp_params.encryption_mode); - } - - // calculate message length .. - int msg_len = 0; - - // addresses - for (int i = 0; i < bind_addr->num_ext_addrs; i++) { - int addrmsg_len = - msg_youconnect_addr_SIZEname(strlen(bind_addr->ext_addrs[i].scope)) + - msg_youconnect_addr_SIZEaddr(addr_size(bind_addr->ext_addrs[i].addr)); - msg_len += msg_youconnect_SIZEaddr(addrmsg_len); - } - - // encryption key - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - msg_len += msg_youconnect_SIZEkey(key_size); - } - - // password - if (options.transport_mode == TRANSPORT_MODE_TCP) { - msg_len += msg_youconnect_SIZEpassword; - } - - // check if it's too big (because of the addresses) - if (msg_len > MSG_MAX_PAYLOAD) { - BLog(BLOG_ERROR, "cannot send too big youconnect message"); - return; - } - - // start message - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_YOUCONNECT, msg_len)) { - return; - } - - // init writer - msg_youconnectWriter writer; - msg_youconnectWriter_Init(&writer, msg); - - // write addresses - for (int i = 0; i < bind_addr->num_ext_addrs; i++) { - int name_len = strlen(bind_addr->ext_addrs[i].scope); - int addr_len = addr_size(bind_addr->ext_addrs[i].addr); - - // get a pointer for writing the address - int addrmsg_len = - msg_youconnect_addr_SIZEname(name_len) + - msg_youconnect_addr_SIZEaddr(addr_len); - uint8_t *addrmsg_dst = msg_youconnectWriter_Addaddr(&writer, addrmsg_len); - - // init address writer - msg_youconnect_addrWriter awriter; - msg_youconnect_addrWriter_Init(&awriter, addrmsg_dst); - - // write scope - uint8_t *name_dst = msg_youconnect_addrWriter_Addname(&awriter, name_len); - memcpy(name_dst, bind_addr->ext_addrs[i].scope, name_len); - - // write address with adjusted port - BAddr addr = bind_addr->ext_addrs[i].addr; - BAddr_SetPort(&addr, hton16(ntoh16(BAddr_GetPort(&addr)) + port_adjust)); - uint8_t *addr_dst = msg_youconnect_addrWriter_Addaddr(&awriter, addr_len); - addr_write(addr_dst, addr); - - // finish address writer - msg_youconnect_addrWriter_Finish(&awriter); - } - - // write encryption key - if (options.transport_mode == TRANSPORT_MODE_UDP && SPPROTO_HAVE_ENCRYPTION(sp_params)) { - uint8_t *key_dst = msg_youconnectWriter_Addkey(&writer, key_size); - memcpy(key_dst, enckey, key_size); - } - - // write password - if (options.transport_mode == TRANSPORT_MODE_TCP) { - msg_youconnectWriter_Addpassword(&writer, pass); - } - - // finish writer - msg_youconnectWriter_Finish(&writer); - - // end message - peer_end_msg(peer); -} - -void peer_send_confirmseed (struct peer_data *peer, uint16_t seed_id) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - - // send confirmation - int msg_len = msg_confirmseed_SIZEseed_id; - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_CONFIRMSEED, msg_len)) { - return; - } - msg_confirmseedWriter writer; - msg_confirmseedWriter_Init(&writer, msg); - msg_confirmseedWriter_Addseed_id(&writer, seed_id); - msg_confirmseedWriter_Finish(&writer); - peer_end_msg(peer); -} - -void peer_dataproto_handler (struct peer_data *peer, int up) -{ - ASSERT(peer->have_link) - - if (up) { - peer_log(peer, BLOG_INFO, "up"); - - // if it can be a relay provided, enable it - if ((peer->flags & SCID_NEWCLIENT_FLAG_RELAY_SERVER) && !peer->is_relay) { - peer_enable_relay_provider(peer); - } - } else { - peer_log(peer, BLOG_INFO, "down"); - - // if it is a relay provider, disable it - if (peer->is_relay) { - peer_disable_relay_provider(peer); - } - } -} - -struct peer_data * find_peer_by_id (peerid_t id) -{ - for (LinkedList1Node *node = LinkedList1_GetFirst(&peers); node; node = LinkedList1Node_Next(node)) { - struct peer_data *peer = UPPER_OBJECT(node, struct peer_data, list_node); - if (peer->id == id) { - return peer; - } - } - - return NULL; -} - -void device_error_handler (void *unused) -{ - BLog(BLOG_ERROR, "device error"); - - terminate(); -} - -void device_dpsource_handler (void *unused, const uint8_t *frame, int frame_len) -{ - ASSERT(frame_len >= 0) - ASSERT(frame_len <= device_mtu) - - // give frame to decider - FrameDecider_AnalyzeAndDecide(&frame_decider, frame, frame_len); - - // forward frame to peers - FrameDeciderPeer *decider_peer = FrameDecider_NextDestination(&frame_decider); - while (decider_peer) { - FrameDeciderPeer *next = FrameDecider_NextDestination(&frame_decider); - struct peer_data *peer = UPPER_OBJECT(decider_peer, struct peer_data, decider_peer); - DataProtoFlow_Route(&peer->local_dpflow, !!next); - decider_peer = next; - } -} - -void assign_relays (void) -{ - LinkedList1Node *list_node; - while (list_node = LinkedList1_GetFirst(&waiting_relay_peers)) { - struct peer_data *peer = UPPER_OBJECT(list_node, struct peer_data, waiting_relay_list_node); - ASSERT(peer->waiting_relay) - - ASSERT(!peer->relaying_peer) - ASSERT(!peer->have_link) - - // get a relay - LinkedList1Node *list_node2 = LinkedList1_GetFirst(&relays); - if (!list_node2) { - BLog(BLOG_NOTICE, "no relays"); - return; - } - struct peer_data *relay = UPPER_OBJECT(list_node2, struct peer_data, relay_list_node); - ASSERT(relay->is_relay) - - // no longer waiting for relay - peer_unregister_need_relay(peer); - - // install the relay - peer_install_relaying(peer, relay); - } -} - -char * address_scope_known (uint8_t *name, int name_len) -{ - ASSERT(name_len >= 0) - - for (int i = 0; i < options.num_scopes; i++) { - if (name_len == strlen(options.scopes[i]) && !memcmp(name, options.scopes[i], name_len)) { - return options.scopes[i]; - } - } - - return NULL; -} - -void server_handler_error (void *user) -{ - BLog(BLOG_ERROR, "server connection failed, exiting"); - - terminate(); -} - -void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip) -{ - ASSERT(!server_ready) - - // remember our ID - my_id = param_my_id; - - // store server reported addresses - for (int i = 0; i < num_bind_addrs; i++) { - struct bind_addr *addr = &bind_addrs[i]; - for (int j = 0; j < addr->num_ext_addrs; j++) { - struct ext_addr *eaddr = &addr->ext_addrs[j]; - if (eaddr->server_reported_port >= 0) { - if (ext_ip == 0) { - BLog(BLOG_ERROR, "server did not provide our address"); - terminate(); - return; - } - BAddr_InitIPv4(&eaddr->addr, ext_ip, hton16(eaddr->server_reported_port)); - char str[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&eaddr->addr, str); - BLog(BLOG_INFO, "external address (%d,%d): server reported %s", i, j, str); - } - } - } - - // give receive device the ID - DPReceiveDevice_SetPeerID(&device_output_dprd, my_id); - - // init server queue - if (!PacketPassFairQueue_Init(&server_queue, ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss), 0, 1)) { - BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed"); - terminate(); - return; - } - - // set server ready - server_ready = 1; - - BLog(BLOG_INFO, "server: ready, my ID is %d", (int)my_id); -} - -void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - ASSERT(cert_len >= 0) - ASSERT(cert_len <= SCID_NEWCLIENT_MAX_CERT_LEN) - - // check if the peer already exists - if (find_peer_by_id(peer_id)) { - BLog(BLOG_WARNING, "server: newclient: peer already known"); - return; - } - - // make sure it's not the same ID as us - if (peer_id == my_id) { - BLog(BLOG_WARNING, "server: newclient: peer has our ID"); - return; - } - - // check if there is spece for the peer - if (num_peers >= options.max_peers) { - BLog(BLOG_WARNING, "server: newclient: no space for new peer (maximum number reached)"); - return; - } - - if (!options.ssl && cert_len > 0) { - BLog(BLOG_WARNING, "server: newclient: certificate supplied, but not using TLS"); - return; - } - - peer_add(peer_id, flags, cert, cert_len); -} - -void server_handler_endclient (void *user, peerid_t peer_id) -{ - ASSERT(server_ready) - - // find peer - struct peer_data *peer = find_peer_by_id(peer_id); - if (!peer) { - BLog(BLOG_WARNING, "server: endclient: peer %d not known", (int)peer_id); - return; - } - - // remove peer - peer_remove(peer, 0); -} - -void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len) -{ - ASSERT(server_ready) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - // find peer - struct peer_data *peer = find_peer_by_id(peer_id); - if (!peer) { - BLog(BLOG_WARNING, "server: message: peer not known"); - return; - } - - // make sure we have chat - if (!peer->have_chat) { - peer_log(peer, BLOG_ERROR, "cannot process message, chat is down"); - return; - } - - // pass message to chat - PeerChat_InputReceived(&peer->chat, data, data_len); -} - -void peer_job_send_seed (struct peer_data *peer) -{ - ASSERT(options.transport_mode == TRANSPORT_MODE_UDP) - ASSERT(SPPROTO_HAVE_OTP(sp_params)) - ASSERT(peer->have_link) - ASSERT(!peer->pio.udp.sendseed_sent) - - peer_log(peer, BLOG_DEBUG, "sending OTP send seed"); - - int key_len = BEncryption_cipher_key_size(sp_params.otp_mode); - int iv_len = BEncryption_cipher_block_size(sp_params.otp_mode); - - // generate seed - peer->pio.udp.sendseed_sent_id = peer->pio.udp.sendseed_nextid; - BRandom_randomize(peer->pio.udp.sendseed_sent_key, key_len); - BRandom_randomize(peer->pio.udp.sendseed_sent_iv, iv_len); - - // set as sent, increment next seed ID - peer->pio.udp.sendseed_sent = 1; - peer->pio.udp.sendseed_nextid++; - - // send seed to the peer - int msg_len = msg_seed_SIZEseed_id + msg_seed_SIZEkey(key_len) + msg_seed_SIZEiv(iv_len); - if (msg_len > MSG_MAX_PAYLOAD) { - peer_log(peer, BLOG_ERROR, "OTP send seed message too big"); - return; - } - uint8_t *msg; - if (!peer_start_msg(peer, (void **)&msg, MSGID_SEED, msg_len)) { - return; - } - msg_seedWriter writer; - msg_seedWriter_Init(&writer, msg); - msg_seedWriter_Addseed_id(&writer, peer->pio.udp.sendseed_sent_id); - uint8_t *key_dst = msg_seedWriter_Addkey(&writer, key_len); - memcpy(key_dst, peer->pio.udp.sendseed_sent_key, key_len); - uint8_t *iv_dst = msg_seedWriter_Addiv(&writer, iv_len); - memcpy(iv_dst, peer->pio.udp.sendseed_sent_iv, iv_len); - msg_seedWriter_Finish(&writer); - peer_end_msg(peer); -} - -void peer_job_init (struct peer_data *peer) -{ - // start setup process - if (peer_am_master(peer)) { - peer_start_binding(peer); - } -} - -struct server_flow * server_flow_init (void) -{ - ASSERT(server_ready) - - // allocate structure - struct server_flow *flow = (struct server_flow *)malloc(sizeof(*flow)); - if (!flow) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // init queue flow - PacketPassFairQueueFlow_Init(&flow->qflow, &server_queue); - - // init connector - PacketRecvConnector_Init(&flow->connector, sizeof(struct packetproto_header) + SC_MAX_ENC, BReactor_PendingGroup(&ss)); - - // init encoder buffer - if (!SinglePacketBuffer_Init(&flow->encoder_buffer, PacketRecvConnector_GetOutput(&flow->connector), PacketPassFairQueueFlow_GetInput(&flow->qflow), BReactor_PendingGroup(&ss))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail1; - } - - // set not connected - flow->connected = 0; - - return flow; - -fail1: - PacketRecvConnector_Free(&flow->connector); - PacketPassFairQueueFlow_Free(&flow->qflow); - free(flow); -fail0: - return NULL; -} - -void server_flow_free (struct server_flow *flow) -{ - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - ASSERT(!flow->connected) - - // remove dying flow reference - if (flow == dying_server_flow) { - dying_server_flow = NULL; - } - - // free encoder buffer - SinglePacketBuffer_Free(&flow->encoder_buffer); - - // free connector - PacketRecvConnector_Free(&flow->connector); - - // free queue flow - PacketPassFairQueueFlow_Free(&flow->qflow); - - // free structure - free(flow); -} - -void server_flow_die (struct server_flow *flow) -{ - ASSERT(PacketPassFairQueueFlow_IsBusy(&flow->qflow)) - ASSERT(!flow->connected) - ASSERT(!dying_server_flow) - - // request notification when flow is done - PacketPassFairQueueFlow_SetBusyHandler(&flow->qflow, (PacketPassFairQueue_handler_busy)server_flow_qflow_handler_busy, flow); - - // set dying flow - dying_server_flow = flow; -} - -void server_flow_qflow_handler_busy (struct server_flow *flow) -{ - ASSERT(flow == dying_server_flow) - ASSERT(!flow->connected) - PacketPassFairQueueFlow_AssertFree(&flow->qflow); - - // finally free flow - server_flow_free(flow); -} - -void server_flow_connect (struct server_flow *flow, PacketRecvInterface *input) -{ - ASSERT(!flow->connected) - ASSERT(flow != dying_server_flow) - - // connect input - PacketRecvConnector_ConnectInput(&flow->connector, input); - - // set connected - flow->connected = 1; -} - -void server_flow_disconnect (struct server_flow *flow) -{ - ASSERT(flow->connected) - ASSERT(flow != dying_server_flow) - - // disconnect input - PacketRecvConnector_DisconnectInput(&flow->connector); - - // set not connected - flow->connected = 0; -} diff --git a/v2rayng/badvpn/client/client.h b/v2rayng/badvpn/client/client.h deleted file mode 100644 index 595ed59337..0000000000 --- a/v2rayng/badvpn/client/client.h +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @file client.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// NOTE: all time values are in milliseconds - -// name of the program -#define PROGRAM_NAME "client" - -// server output buffer size -#define SERVER_BUFFER_MIN_PACKETS 200 - -// maximum UDP payload size -#define CLIENT_UDP_MTU 1472 - -// maximum number of pending TCP PasswordListener clients -#define TCP_MAX_PASSWORD_LISTENER_CLIENTS 50 - -// maximum number of peers -#define DEFAULT_MAX_PEERS 256 -// maximum number of peer's MAC addresses to remember -#define PEER_DEFAULT_MAX_MACS 16 -// maximum number of multicast addresses per peer -#define PEER_DEFAULT_MAX_GROUPS 16 -// how long we wait for a packet to reach full size before sending it (see FragmentProtoDisassembler latency argument) -#define PEER_DEFAULT_UDP_FRAGMENTATION_LATENCY 0 -// value related to how much out-of-order input we tolerate (see FragmentProtoAssembler num_frames argument) -#define PEER_UDP_ASSEMBLER_NUM_FRAMES 4 -// socket send buffer (SO_SNDBUF) for peer TCP connections, <=0 to not set -#define PEER_DEFAULT_TCP_SOCKET_SNDBUF 1048576 -// keep-alive packet interval for p2p communication -#define PEER_KEEPALIVE_INTERVAL 10000 -// keep-alive receive timer for p2p communication (after how long to consider the link down) -#define PEER_KEEPALIVE_RECEIVE_TIMER 22000 -// size of frame send buffer, in number of frames -#define PEER_DEFAULT_SEND_BUFFER_SIZE 32 -// size of frame send buffer for relayed packets, in number of frames -#define PEER_DEFAULT_SEND_BUFFER_RELAY_SIZE 32 -// time after an unused relay flow is freed (-1 for never) -#define PEER_RELAY_FLOW_INACTIVITY_TIME 10000 -// retry time -#define PEER_RETRY_TIME 5000 - -// for how long a peer can send no Membership Reports for a group -// before the peer and group are disassociated -#define DEFAULT_IGMP_GROUP_MEMBERSHIP_INTERVAL 260000 -// how long to wait for joins after a Group Specific query has been -// forwarded to a peer before assuming there are no listeners at the peer -#define DEFAULT_IGMP_LAST_MEMBER_QUERY_TIME 2000 - -// maximum bind addresses -#define MAX_BIND_ADDRS 8 -// maximum external addresses per bind address -#define MAX_EXT_ADDRS 8 -// maximum scopes -#define MAX_SCOPES 8 - -//#define SIMULATE_PEER_OUT_OF_BUFFER 70 - -struct server_flow { - PacketPassFairQueueFlow qflow; - SinglePacketBuffer encoder_buffer; - PacketRecvConnector connector; - int connected; -}; - -struct peer_data { - // peer identifier - peerid_t id; - - // flags provided by the server - int flags; - - // certificate reported by the server, defined only if using SSL - uint8_t cert[SCID_NEWCLIENT_MAX_CERT_LEN]; - int cert_len; - char *common_name; - - // init job - BPending job_init; - - // server flow - struct server_flow *server_flow; - - // chat - int have_chat; - PeerChat chat; - int chat_send_msg_len; - - // resetpeer source (when chat fails) - int have_resetpeer; - uint8_t resetpeer_packet[sizeof(struct packetproto_header) + sizeof(struct sc_header) + sizeof(struct sc_client_resetpeer)]; - SinglePacketSource resetpeer_source; - - // local flow - DataProtoFlow local_dpflow; - - // frame decider peer - FrameDeciderPeer decider_peer; - - // receive peer - DPReceivePeer receive_peer; - - // flag if link objects are initialized - int have_link; - - // receive receiver - DPReceiveReceiver receive_receiver; - - // transport-specific link objects - union { - struct { - DatagramPeerIO pio; - uint16_t sendseed_nextid; - int sendseed_sent; - uint16_t sendseed_sent_id; - uint8_t sendseed_sent_key[BENCRYPTION_MAX_KEY_SIZE]; - uint8_t sendseed_sent_iv[BENCRYPTION_MAX_BLOCK_SIZE]; - uint16_t pending_recvseed_id; - BPending job_send_seed; - } udp; - struct { - StreamPeerIO pio; - } tcp; - } pio; - - // link sending - DataProtoSink send_dp; - - // relaying objects - struct peer_data *relaying_peer; // peer through which we are relaying, or NULL - LinkedList1Node relaying_list_node; // node in relay peer's relay_users - - // waiting for relay data - int waiting_relay; - LinkedList1Node waiting_relay_list_node; - - // retry timer - BTimer reset_timer; - - // relay server specific - int is_relay; - LinkedList1Node relay_list_node; - LinkedList1 relay_users; - - // binding state - int binding; - int binding_addrpos; - - // peers linked list node - LinkedList1Node list_node; -}; diff --git a/v2rayng/badvpn/cmake/modules/COPYING-CMAKE-SCRIPTS b/v2rayng/badvpn/cmake/modules/COPYING-CMAKE-SCRIPTS deleted file mode 100644 index 4b417765f3..0000000000 --- a/v2rayng/badvpn/cmake/modules/COPYING-CMAKE-SCRIPTS +++ /dev/null @@ -1,22 +0,0 @@ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v2rayng/badvpn/cmake/modules/FindGLIB2.cmake b/v2rayng/badvpn/cmake/modules/FindGLIB2.cmake deleted file mode 100644 index 09fd98d87a..0000000000 --- a/v2rayng/badvpn/cmake/modules/FindGLIB2.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# - Try to find the GLIB2 libraries -# Once done this will define -# -# GLIB2_FOUND - system has glib2 -# GLIB2_INCLUDE_DIR - the glib2 include directory -# GLIB2_LIBRARIES - glib2 library - -# Copyright (c) 2008 Laurent Montel, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES) - # Already in cache, be silent - set(GLIB2_FIND_QUIETLY TRUE) -endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES) - -find_package(PkgConfig) -pkg_check_modules(PC_LibGLIB2 QUIET glib-2.0) - -find_path(GLIB2_MAIN_INCLUDE_DIR - NAMES glib.h - HINTS ${PC_LibGLIB2_INCLUDEDIR} - PATH_SUFFIXES glib-2.0) - -find_library(GLIB2_LIBRARY - NAMES glib-2.0 - HINTS ${PC_LibGLIB2_LIBDIR} -) - -set(GLIB2_LIBRARIES ${GLIB2_LIBRARY}) - -# search the glibconfig.h include dir under the same root where the library is found -get_filename_component(glib2LibDir "${GLIB2_LIBRARIES}" PATH) - -find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h - PATH_SUFFIXES glib-2.0/include - HINTS ${PC_LibGLIB2_INCLUDEDIR} "${glib2LibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH}) - -set(GLIB2_INCLUDE_DIR "${GLIB2_MAIN_INCLUDE_DIR}") - -# not sure if this include dir is optional or required -# for now it is optional -if(GLIB2_INTERNAL_INCLUDE_DIR) - set(GLIB2_INCLUDE_DIR ${GLIB2_INCLUDE_DIR} "${GLIB2_INTERNAL_INCLUDE_DIR}") -endif(GLIB2_INTERNAL_INCLUDE_DIR) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR) - -mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES) diff --git a/v2rayng/badvpn/cmake/modules/FindLibraryWithDebug.cmake b/v2rayng/badvpn/cmake/modules/FindLibraryWithDebug.cmake deleted file mode 100644 index 58cd730862..0000000000 --- a/v2rayng/badvpn/cmake/modules/FindLibraryWithDebug.cmake +++ /dev/null @@ -1,113 +0,0 @@ -# -# FIND_LIBRARY_WITH_DEBUG -# -> enhanced FIND_LIBRARY to allow the search for an -# optional debug library with a WIN32_DEBUG_POSTFIX similar -# to CMAKE_DEBUG_POSTFIX when creating a shared lib -# it has to be the second and third argument - -# Copyright (c) 2007, Christian Ehrlicher, -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -MACRO(FIND_LIBRARY_WITH_DEBUG var_name win32_dbg_postfix_name dgb_postfix libname) - - IF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - - # no WIN32_DEBUG_POSTFIX -> simply pass all arguments to FIND_LIBRARY - FIND_LIBRARY(${var_name} - ${win32_dbg_postfix_name} - ${dgb_postfix} - ${libname} - ${ARGN} - ) - - ELSE(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - - IF(NOT WIN32) - # on non-win32 we don't need to take care about WIN32_DEBUG_POSTFIX - - FIND_LIBRARY(${var_name} ${libname} ${ARGN}) - - ELSE(NOT WIN32) - - # 1. get all possible libnames - SET(args ${ARGN}) - SET(newargs "") - SET(libnames_release "") - SET(libnames_debug "") - - LIST(LENGTH args listCount) - - IF("${libname}" STREQUAL "NAMES") - SET(append_rest 0) - LIST(APPEND args " ") - - FOREACH(i RANGE ${listCount}) - LIST(GET args ${i} val) - - IF(append_rest) - LIST(APPEND newargs ${val}) - ELSE(append_rest) - IF("${val}" STREQUAL "PATHS") - LIST(APPEND newargs ${val}) - SET(append_rest 1) - ELSE("${val}" STREQUAL "PATHS") - LIST(APPEND libnames_release "${val}") - LIST(APPEND libnames_debug "${val}${dgb_postfix}") - ENDIF("${val}" STREQUAL "PATHS") - ENDIF(append_rest) - - ENDFOREACH(i) - - ELSE("${libname}" STREQUAL "NAMES") - - # just one name - LIST(APPEND libnames_release "${libname}") - LIST(APPEND libnames_debug "${libname}${dgb_postfix}") - - SET(newargs ${args}) - - ENDIF("${libname}" STREQUAL "NAMES") - - # search the release lib - FIND_LIBRARY(${var_name}_RELEASE - NAMES ${libnames_release} - ${newargs} - ) - - # search the debug lib - FIND_LIBRARY(${var_name}_DEBUG - NAMES ${libnames_debug} - ${newargs} - ) - - IF(${var_name}_RELEASE AND ${var_name}_DEBUG) - - # both libs found - SET(${var_name} optimized ${${var_name}_RELEASE} - debug ${${var_name}_DEBUG}) - - ELSE(${var_name}_RELEASE AND ${var_name}_DEBUG) - - IF(${var_name}_RELEASE) - - # only release found - SET(${var_name} ${${var_name}_RELEASE}) - - ELSE(${var_name}_RELEASE) - - # only debug (or nothing) found - SET(${var_name} ${${var_name}_DEBUG}) - - ENDIF(${var_name}_RELEASE) - - ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG) - - MARK_AS_ADVANCED(${var_name}_RELEASE) - MARK_AS_ADVANCED(${var_name}_DEBUG) - - ENDIF(NOT WIN32) - - ENDIF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") - -ENDMACRO(FIND_LIBRARY_WITH_DEBUG) diff --git a/v2rayng/badvpn/cmake/modules/FindNSPR.cmake b/v2rayng/badvpn/cmake/modules/FindNSPR.cmake deleted file mode 100644 index 6e8fed9269..0000000000 --- a/v2rayng/badvpn/cmake/modules/FindNSPR.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Try to find the NSPR library -# Once done this will define -# -# NSPR_FOUND - system has the NSPR library -# NSPR_INCLUDE_DIRS - Include paths needed -# NSPR_LIBRARY_DIRS - Linker paths needed -# NSPR_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (NSPR_LIBRARIES) - set(NSPR_FIND_QUIETLY TRUE) -endif () - -set(NSPR_FOUND FALSE) - -if (WIN32) - find_path(NSPR_FIND_INCLUDE_DIR prerror.h) - - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_PLDS WIN32_DEBUG_POSTFIX d NAMES plds4 libplds4) - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_PLC WIN32_DEBUG_POSTFIX d NAMES plc4 libplc4) - FIND_LIBRARY_WITH_DEBUG(NSPR_FIND_LIBRARIES_NSPR WIN32_DEBUG_POSTFIX d NAMES nspr4 libnspr4) - - if (NSPR_FIND_INCLUDE_DIR AND NSPR_FIND_LIBRARIES_PLDS AND NSPR_FIND_LIBRARIES_PLC AND NSPR_FIND_LIBRARIES_NSPR) - set(NSPR_FOUND TRUE) - set(NSPR_INCLUDE_DIRS "${NSPR_FIND_INCLUDE_DIR}" CACHE STRING "NSPR include dirs") - set(NSPR_LIBRARY_DIRS "" CACHE STRING "NSPR library dirs") - set(NSPR_LIBRARIES "${NSPR_FIND_LIBRARIES_PLDS};${NSPR_FIND_LIBRARIES_PLC};${NSPR_FIND_LIBRARIES_NSPR}" CACHE STRING "NSPR libraries") - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(NSPR_PC nspr) - - if (NSPR_PC_FOUND) - set(NSPR_FOUND TRUE) - set(NSPR_INCLUDE_DIRS "${NSPR_PC_INCLUDE_DIRS}" CACHE STRING "NSPR include dirs") - set(NSPR_LIBRARY_DIRS "${NSPR_PC_LIBRARY_DIRS}" CACHE STRING "NSPR library dirs") - set(NSPR_LIBRARIES "${NSPR_PC_LIBRARIES}" CACHE STRING "NSPR libraries") - endif () -endif () - -if (NSPR_FOUND) - if (NOT NSPR_FIND_QUIETLY) - MESSAGE(STATUS "Found NSPR: ${NSPR_INCLUDE_DIRS} ${NSPR_LIBRARY_DIRS} ${NSPR_LIBRARIES}") - endif () -else () - if (NSPR_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find NSPR") - endif () -endif () - -mark_as_advanced(NSPR_INCLUDE_DIRS NSPR_LIBRARY_DIRS NSPR_LIBRARIES) diff --git a/v2rayng/badvpn/cmake/modules/FindNSS.cmake b/v2rayng/badvpn/cmake/modules/FindNSS.cmake deleted file mode 100644 index 85279104ee..0000000000 --- a/v2rayng/badvpn/cmake/modules/FindNSS.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Try to find the NSS library -# Once done this will define -# -# NSS_FOUND - system has the NSS library -# NSS_INCLUDE_DIRS - Include paths needed -# NSS_LIBRARY_DIRS - Linker paths needed -# NSS_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (NSS_LIBRARIES) - set(NSS_FIND_QUIETLY TRUE) -endif () - -set(NSS_FOUND FALSE) - -if (WIN32) - find_path(NSS_FIND_INCLUDE_DIR nss/nss.h) - - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_SSL WIN32_DEBUG_POSTFIX d NAMES ssl3) - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_SMIME WIN32_DEBUG_POSTFIX d NAMES smime3) - FIND_LIBRARY_WITH_DEBUG(NSS_FIND_LIBRARIES_NSS WIN32_DEBUG_POSTFIX d NAMES nss3) - - if (NSS_FIND_INCLUDE_DIR AND NSS_FIND_LIBRARIES_SSL AND NSS_FIND_LIBRARIES_SMIME AND NSS_FIND_LIBRARIES_NSS) - set(NSS_FOUND TRUE) - set(NSS_INCLUDE_DIRS "${NSS_FIND_INCLUDE_DIR}" CACHE STRING "NSS include dirs") - set(NSS_LIBRARY_DIRS "" CACHE STRING "NSS library dirs") - set(NSS_LIBRARIES "${NSS_FIND_LIBRARIES_SSL};${NSS_FIND_LIBRARIES_SMIME};${NSS_FIND_LIBRARIES_NSS}" CACHE STRING "NSS libraries") - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(NSS_PC nss) - - if (NSS_PC_FOUND) - set(NSS_FOUND TRUE) - set(NSS_INCLUDE_DIRS "${NSS_PC_INCLUDE_DIRS}" CACHE STRING "NSS include dirs") - set(NSS_LIBRARY_DIRS "${NSS_PC_LIBRARY_DIRS}" CACHE STRING "NSS library dirs") - set(NSS_LIBRARIES "${NSS_PC_LIBRARIES}" CACHE STRING "NSS libraries") - endif () -endif () - -if (NSS_FOUND) - if (NOT NSS_FIND_QUIETLY) - MESSAGE(STATUS "Found NSS: ${NSS_INCLUDE_DIRS} ${NSS_LIBRARY_DIRS} ${NSS_LIBRARIES}") - endif () -else () - if (NSS_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find NSS") - endif () -endif () - -mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARY_DIRS NSS_LIBRARIES) diff --git a/v2rayng/badvpn/cmake/modules/FindOpenSSL.cmake b/v2rayng/badvpn/cmake/modules/FindOpenSSL.cmake deleted file mode 100644 index 4434e95bc5..0000000000 --- a/v2rayng/badvpn/cmake/modules/FindOpenSSL.cmake +++ /dev/null @@ -1,72 +0,0 @@ -# - Try to find the OpenSSL library -# Once done this will define -# -# OpenSSL_FOUND - system has the OpenSSL library -# OpenSSL_INCLUDE_DIRS - Include paths needed -# OpenSSL_LIBRARY_DIRS - Linker paths needed -# OpenSSL_LIBRARIES - Libraries needed - -# Copyright (c) 2010, Ambroz Bizjak, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindLibraryWithDebug) - -if (OpenSSL_LIBRARIES) - set(OpenSSL_FIND_QUIETLY TRUE) -endif () - -set(OpenSSL_FOUND FALSE) - -if (WIN32) - find_path(OpenSSL_FIND_INCLUDE_DIR openssl/ssl.h) - - if (OpenSSL_FIND_INCLUDE_DIR) - # look for libraries built with GCC - find_library(OpenSSL_FIND_LIBRARIES_SSL NAMES ssl) - find_library(OpenSSL_FIND_LIBRARIES_CRYPTO NAMES crypto) - - if (OpenSSL_FIND_LIBRARIES_SSL AND OpenSSL_FIND_LIBRARIES_CRYPTO) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_LIBRARY_DIRS "" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_FIND_LIBRARIES_SSL};${OpenSSL_FIND_LIBRARIES_CRYPTO}" CACHE STRING "OpenSSL libraries") - else () - # look for libraries built with MSVC - FIND_LIBRARY_WITH_DEBUG(OpenSSL_FIND_LIBRARIES_SSL WIN32_DEBUG_POSTFIX d NAMES ssl ssleay ssleay32 libssleay32 ssleay32MD) - FIND_LIBRARY_WITH_DEBUG(OpenSSL_FIND_LIBRARIES_EAY WIN32_DEBUG_POSTFIX d NAMES eay libeay libeay32 libeay32MD) - - if (OpenSSL_FIND_LIBRARIES_SSL AND OpenSSL_FIND_LIBRARIES_EAY) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_LIBRARY_DIRS "" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_FIND_LIBRARIES_SSL};${OpenSSL_FIND_LIBRARIES_EAY}" CACHE STRING "OpenSSL libraries") - endif () - endif () - - if (OpenSSL_FOUND) - set(OpenSSL_INCLUDE_DIRS "${OpenSSL_FIND_INCLUDE_DIR}" CACHE STRING "OpenSSL include dirs") - endif () - endif () -else () - find_package(PkgConfig REQUIRED) - pkg_check_modules(OpenSSL_PC openssl) - - if (OpenSSL_PC_FOUND) - set(OpenSSL_FOUND TRUE) - set(OpenSSL_INCLUDE_DIRS "${OpenSSL_PC_INCLUDE_DIRS}" CACHE STRING "OpenSSL include dirs") - set(OpenSSL_LIBRARY_DIRS "${OpenSSL_PC_LIBRARY_DIRS}" CACHE STRING "OpenSSL library dirs") - set(OpenSSL_LIBRARIES "${OpenSSL_PC_LIBRARIES}" CACHE STRING "OpenSSL libraries") - endif () -endif () - -if (OpenSSL_FOUND) - if (NOT OpenSSL_FIND_QUIETLY) - MESSAGE(STATUS "Found OpenSSL: ${OpenSSL_INCLUDE_DIRS} ${OpenSSL_LIBRARY_DIRS} ${OpenSSL_LIBRARIES}") - endif () -else () - if (OpenSSL_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find OpenSSL") - endif () -endif () - -mark_as_advanced(OpenSSL_INCLUDE_DIRS OpenSSL_LIBRARY_DIRS OpenSSL_LIBRARIES) diff --git a/v2rayng/badvpn/compile-tun2socks.sh b/v2rayng/badvpn/compile-tun2socks.sh deleted file mode 100755 index e06f43bc07..0000000000 --- a/v2rayng/badvpn/compile-tun2socks.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash -# -# Compiles tun2socks for Linux. -# Intended as a convenience if you don't want to deal with CMake. - -# Input environment vars: -# SRCDIR - BadVPN source code -# OUTDIR - tun2socks binary output file directory -# CC - compiler -# CFLAGS - compiler compile flags -# LDFLAGS - compiler link flags -# ENDIAN - "little" or "big" -# KERNEL - "2.6" or "2.4", default "2.6" -# -# Puts object files and the executable in the working directory. -# - -if [[ -z $SRCDIR ]] || [[ ! -e $SRCDIR/CMakeLists.txt ]]; then - echo "SRCDIR is wrong" - exit 1 -fi - -if [[ ! -z $OUTDIR ]] && [[ ! -d $OUTDIR ]]; then - echo "OUTDIR is wrong" - exit 1 -fi - -if ! "${CC}" --version &>/dev/null; then - echo "CC is wrong" - exit 1 -fi - -if [[ $ENDIAN != "little" ]] && [[ $ENDIAN != "big" ]]; then - echo "ENDIAN is wrong" - exit 1 -fi - -if [[ -z $KERNEL ]]; then - KERNEL="2.6" -elif [[ $KERNEL != "2.6" ]] && [[ $KERNEL != "2.4" ]]; then - echo "KERNEL is wrong" - exit 1 -fi - -CFLAGS="${CFLAGS} -std=gnu99" -INCLUDES=( "-I${SRCDIR}" "-I${SRCDIR}/lwip/src/include/ipv4" "-I${SRCDIR}/lwip/src/include/ipv6" "-I${SRCDIR}/lwip/src/include" "-I${SRCDIR}/lwip/custom" ) -DEFS=( -DBADVPN_THREAD_SAFE=0 -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE ) - -[[ $KERNEL = "2.4" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_USE_SELFPIPE -DBADVPN_USE_POLL ) || DEFS=( "${DEFS[@]}" -DBADVPN_USE_SIGNALFD -DBADVPN_USE_EPOLL ) - -[[ $ENDIAN = "little" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_LITTLE_ENDIAN ) || DEFS=( "${DEFS[@]}" -DBADVPN_BIG_ENDIAN ) - -[[ -z $OUTDIR ]] && OUTDIR="." - -SOURCES=" -base/BLog_syslog.c -system/BReactor_badvpn.c -system/BSignal.c -system/BConnection_unix.c -system/BConnection_common.c -system/BTime.c -system/BUnixSignal.c -system/BNetwork.c -system/BDatagram_common.c -system/BDatagram_unix.c -flow/StreamRecvInterface.c -flow/PacketRecvInterface.c -flow/PacketPassInterface.c -flow/StreamPassInterface.c -flow/SinglePacketBuffer.c -flow/BufferWriter.c -flow/PacketBuffer.c -flow/PacketStreamSender.c -flow/PacketPassConnector.c -flow/PacketProtoFlow.c -flow/PacketPassFairQueue.c -flow/PacketProtoEncoder.c -flow/PacketProtoDecoder.c -socksclient/BSocksClient.c -tuntap/BTap.c -lwip/src/core/udp.c -lwip/src/core/memp.c -lwip/src/core/init.c -lwip/src/core/pbuf.c -lwip/src/core/tcp.c -lwip/src/core/tcp_out.c -lwip/src/core/sys.c -lwip/src/core/netif.c -lwip/src/core/def.c -lwip/src/core/mem.c -lwip/src/core/tcp_in.c -lwip/src/core/stats.c -lwip/src/core/ip.c -lwip/src/core/timeouts.c -lwip/src/core/inet_chksum.c -lwip/src/core/ipv4/icmp.c -lwip/src/core/ipv4/ip4.c -lwip/src/core/ipv4/ip4_addr.c -lwip/src/core/ipv4/ip4_frag.c -lwip/src/core/ipv6/ip6.c -lwip/src/core/ipv6/nd6.c -lwip/src/core/ipv6/icmp6.c -lwip/src/core/ipv6/ip6_addr.c -lwip/src/core/ipv6/ip6_frag.c -lwip/custom/sys.c -tun2socks/tun2socks.c -base/DebugObject.c -base/BLog.c -base/BPending.c -flowextra/PacketPassInactivityMonitor.c -tun2socks/SocksUdpGwClient.c -udpgw_client/UdpGwClient.c -socks_udp_client/SocksUdpClient.c -" - -set -e -set -x - -OBJS=() -for f in $SOURCES; do - obj=${f//\//_}.o - "${CC}" -c ${CFLAGS} "${INCLUDES[@]}" "${DEFS[@]}" "${SRCDIR}/${f}" -o "${obj}" - OBJS=( "${OBJS[@]}" "${obj}" ) -done - -"${CC}" ${LDFLAGS} "${OBJS[@]}" -o $OUTDIR/tun2socks -lrt -lpthread diff --git a/v2rayng/badvpn/compile-udpgw.sh b/v2rayng/badvpn/compile-udpgw.sh deleted file mode 100755 index 62156a0c08..0000000000 --- a/v2rayng/badvpn/compile-udpgw.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -# -# Compiles udpgw for Linux. -# Intended as a convenience if you don't want to deal with CMake. - -# Input environment vars: -# SRCDIR - BadVPN source code -# CC - compiler -# CFLAGS - compiler compile flags -# LDFLAGS - compiler link flags -# ENDIAN - "little" or "big" -# KERNEL - "2.6" or "2.4", default "2.6" -# -# Puts object files and the executable in the working directory. -# - -if [[ -z $SRCDIR ]] || [[ ! -e $SRCDIR/CMakeLists.txt ]]; then - echo "SRCDIR is wrong" - exit 1 -fi - -if ! "${CC}" --version &>/dev/null; then - echo "CC is wrong" - exit 1 -fi - -if [[ $ENDIAN != "little" ]] && [[ $ENDIAN != "big" ]]; then - echo "ENDIAN is wrong" - exit 1 -fi - -if [[ -z $KERNEL ]]; then - KERNEL="2.6" -elif [[ $KERNEL != "2.6" ]] && [[ $KERNEL != "2.4" ]]; then - echo "KERNEL is wrong" - exit 1 -fi - -CFLAGS="${CFLAGS} -std=gnu99" -INCLUDES=( "-I${SRCDIR}" ) -DEFS=( -DBADVPN_THREAD_SAFE=0 -DBADVPN_LINUX -DBADVPN_BREACTOR_BADVPN -D_GNU_SOURCE ) - -[[ $KERNEL = "2.4" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_USE_SELFPIPE -DBADVPN_USE_POLL ) || DEFS=( "${DEFS[@]}" -DBADVPN_USE_SIGNALFD -DBADVPN_USE_EPOLL ) - -[[ $ENDIAN = "little" ]] && DEFS=( "${DEFS[@]}" -DBADVPN_LITTLE_ENDIAN ) || DEFS=( "${DEFS[@]}" -DBADVPN_BIG_ENDIAN ) - -SOURCES=" -base/BLog_syslog.c -system/BReactor_badvpn.c -system/BSignal.c -system/BConnection_unix.c -system/BConnection_common.c -system/BDatagram_unix.c -system/BTime.c -system/BUnixSignal.c -system/BNetwork.c -flow/StreamRecvInterface.c -flow/PacketRecvInterface.c -flow/PacketPassInterface.c -flow/StreamPassInterface.c -flow/SinglePacketBuffer.c -flow/BufferWriter.c -flow/PacketBuffer.c -flow/PacketStreamSender.c -flow/PacketProtoFlow.c -flow/PacketPassFairQueue.c -flow/PacketProtoEncoder.c -flow/PacketProtoDecoder.c -base/DebugObject.c -base/BLog.c -base/BPending.c -udpgw/udpgw.c -" - -set -e -set -x - -OBJS=() -for f in $SOURCES; do - obj=$(basename "${f}").o - "${CC}" -c ${CFLAGS} "${INCLUDES[@]}" "${DEFS[@]}" "${SRCDIR}/${f}" -o "${obj}" - OBJS=( "${OBJS[@]}" "${obj}" ) -done - -"${CC}" ${LDFLAGS} "${OBJS[@]}" -o udpgw -lrt -lpthread diff --git a/v2rayng/badvpn/dhcpclient/BDHCPClient.c b/v2rayng/badvpn/dhcpclient/BDHCPClient.c deleted file mode 100644 index 70ee6adfe8..0000000000 --- a/v2rayng/badvpn/dhcpclient/BDHCPClient.c +++ /dev/null @@ -1,340 +0,0 @@ -/** - * @file BDHCPClient.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_OVERHEAD (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static const struct sock_filter dhcp_sock_filter[] = { - BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9), // A <- IP protocol - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPV4_PROTOCOL_UDP, 0, 3), // IP protocol = UDP ? - BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 22), // A <- UDP destination port - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_CLIENT_PORT, 0, 1), // UDP destination port = DHCP client ? - BPF_STMT(BPF_RET + BPF_K, 65535), // return all - BPF_STMT(BPF_RET + BPF_K, 0) // ignore -}; - -static void dgram_handler (BDHCPClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - - BLog(BLOG_ERROR, "packet socket error"); - - // report error - DEBUGERROR(&o->d_err, o->handler(o->user, BDHCPCLIENT_EVENT_ERROR)); - return; -} - -static void dhcp_handler (BDHCPClient *o, int event) -{ - DebugObject_Access(&o->d_obj); - - switch (event) { - case BDHCPCLIENTCORE_EVENT_UP: - ASSERT(!o->up) - o->up = 1; - o->handler(o->user, BDHCPCLIENT_EVENT_UP); - return; - - case BDHCPCLIENTCORE_EVENT_DOWN: - ASSERT(o->up) - o->up = 0; - o->handler(o->user, BDHCPCLIENT_EVENT_DOWN); - return; - - default: - ASSERT(0); - } -} - -static void dhcp_func_getsendermac (BDHCPClient *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - - BAddr remote_addr; - BIPAddr local_addr; - if (!BDatagram_GetLastReceiveAddrs(&o->dgram, &remote_addr, &local_addr)) { - BLog(BLOG_ERROR, "BDatagram_GetLastReceiveAddrs failed"); - goto fail; - } - - if (remote_addr.type != BADDR_TYPE_PACKET) { - BLog(BLOG_ERROR, "address type invalid"); - goto fail; - } - - if (remote_addr.packet.header_type != BADDR_PACKET_HEADER_TYPE_ETHERNET) { - BLog(BLOG_ERROR, "address header type invalid"); - goto fail; - } - - memcpy(out_mac, remote_addr.packet.phys_addr, 6); - return; - -fail: - memset(out_mac, 0, 6); -} - -int BDHCPClient_Init (BDHCPClient *o, const char *ifname, struct BDHCPClient_opts opts, BReactor *reactor, BRandom2 *random2, BDHCPClient_handler handler, void *user) -{ - // init arguments - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // get interface information - uint8_t if_mac[6]; - int if_mtu; - int if_index; - if (!badvpn_get_iface_info(ifname, if_mac, &if_mtu, &if_index)) { - BLog(BLOG_ERROR, "failed to get interface information"); - goto fail0; - } - - BLog(BLOG_INFO, "if_mac=%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8" if_mtu=%d if_index=%d", - if_mac[0], if_mac[1], if_mac[2], if_mac[3], if_mac[4], if_mac[5], if_mtu, if_index); - - if (if_mtu < IPUDP_OVERHEAD) { - BLog(BLOG_ERROR, "MTU is too small for UDP/IP !?!"); - goto fail0; - } - - int dhcp_mtu = if_mtu - IPUDP_OVERHEAD; - - // init dgram - if (!BDatagram_Init(&o->dgram, BADDR_TYPE_PACKET, o->reactor, o, (BDatagram_handler)dgram_handler)) { - BLog(BLOG_ERROR, "BDatagram_Init failed"); - goto fail0; - } - - // set socket filter - { - struct sock_filter filter[sizeof(dhcp_sock_filter) / sizeof(dhcp_sock_filter[0])]; - memcpy(filter, dhcp_sock_filter, sizeof(filter)); - struct sock_fprog fprog = { - .len = sizeof(filter) / sizeof(filter[0]), - .filter = filter - }; - if (setsockopt(BDatagram_GetFd(&o->dgram), SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) { - BLog(BLOG_NOTICE, "not using socket filter"); - } - } - - // bind dgram - BAddr bind_addr; - BAddr_InitPacket(&bind_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_HOST, if_mac); - if (!BDatagram_Bind(&o->dgram, bind_addr)) { - BLog(BLOG_ERROR, "BDatagram_Bind failed"); - goto fail1; - } - - // set dgram send addresses - BAddr dest_addr; - uint8_t broadcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BAddr_InitPacket(&dest_addr, hton16(ETHERTYPE_IPV4), if_index, BADDR_PACKET_HEADER_TYPE_ETHERNET, BADDR_PACKET_PACKET_TYPE_BROADCAST, broadcast_mac); - BIPAddr local_addr; - BIPAddr_InitInvalid(&local_addr); - BDatagram_SetSendAddrs(&o->dgram, dest_addr, local_addr); - - // init dgram interfaces - BDatagram_SendAsync_Init(&o->dgram, if_mtu); - BDatagram_RecvAsync_Init(&o->dgram, if_mtu); - - // init sending - - // init copier - PacketCopier_Init(&o->send_copier, dhcp_mtu, BReactor_PendingGroup(o->reactor)); - - // init encoder - DHCPIpUdpEncoder_Init(&o->send_encoder, PacketCopier_GetOutput(&o->send_copier), BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->send_buffer, DHCPIpUdpEncoder_GetOutput(&o->send_encoder), BDatagram_SendAsync_GetIf(&o->dgram), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail2; - } - - // init receiving - - // init copier - PacketCopier_Init(&o->recv_copier, dhcp_mtu, BReactor_PendingGroup(o->reactor)); - - // init decoder - DHCPIpUdpDecoder_Init(&o->recv_decoder, PacketCopier_GetInput(&o->recv_copier), BReactor_PendingGroup(o->reactor)); - - // init buffer - if (!SinglePacketBuffer_Init(&o->recv_buffer, BDatagram_RecvAsync_GetIf(&o->dgram), DHCPIpUdpDecoder_GetInput(&o->recv_decoder), BReactor_PendingGroup(o->reactor))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed"); - goto fail3; - } - - // init options - struct BDHCPClientCore_opts core_opts; - core_opts.hostname = opts.hostname; - core_opts.vendorclassid = opts.vendorclassid; - core_opts.clientid = opts.clientid; - core_opts.clientid_len = opts.clientid_len; - - // auto-generate clientid from MAC if requested - uint8_t mac_cid[7]; - if (opts.auto_clientid) { - mac_cid[0] = DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET; - memcpy(mac_cid + 1, if_mac, 6); - core_opts.clientid = mac_cid; - core_opts.clientid_len = sizeof(mac_cid); - } - - // init dhcp - if (!BDHCPClientCore_Init(&o->dhcp, PacketCopier_GetInput(&o->send_copier), PacketCopier_GetOutput(&o->recv_copier), if_mac, core_opts, o->reactor, random2, o, - (BDHCPClientCore_func_getsendermac)dhcp_func_getsendermac, - (BDHCPClientCore_handler)dhcp_handler - )) { - BLog(BLOG_ERROR, "BDHCPClientCore_Init failed"); - goto fail4; - } - - // set not up - o->up = 0; - - DebugError_Init(&o->d_err, BReactor_PendingGroup(o->reactor)); - DebugObject_Init(&o->d_obj); - return 1; - -fail4: - SinglePacketBuffer_Free(&o->recv_buffer); -fail3: - DHCPIpUdpDecoder_Free(&o->recv_decoder); - PacketCopier_Free(&o->recv_copier); - SinglePacketBuffer_Free(&o->send_buffer); -fail2: - DHCPIpUdpEncoder_Free(&o->send_encoder); - PacketCopier_Free(&o->send_copier); - BDatagram_RecvAsync_Free(&o->dgram); - BDatagram_SendAsync_Free(&o->dgram); -fail1: - BDatagram_Free(&o->dgram); -fail0: - return 0; -} - -void BDHCPClient_Free (BDHCPClient *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); - - // free dhcp - BDHCPClientCore_Free(&o->dhcp); - - // free receiving - SinglePacketBuffer_Free(&o->recv_buffer); - DHCPIpUdpDecoder_Free(&o->recv_decoder); - PacketCopier_Free(&o->recv_copier); - - // free sending - SinglePacketBuffer_Free(&o->send_buffer); - DHCPIpUdpEncoder_Free(&o->send_encoder); - PacketCopier_Free(&o->send_copier); - - // free dgram interfaces - BDatagram_RecvAsync_Free(&o->dgram); - BDatagram_SendAsync_Free(&o->dgram); - - // free dgram - BDatagram_Free(&o->dgram); -} - -int BDHCPClient_IsUp (BDHCPClient *o) -{ - DebugObject_Access(&o->d_obj); - - return o->up; -} - -void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetClientIP(&o->dhcp, out_ip); -} - -void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetClientMask(&o->dhcp, out_mask); -} - -int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return BDHCPClientCore_GetRouter(&o->dhcp, out_router); -} - -int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - return BDHCPClientCore_GetDNS(&o->dhcp, out_dns_servers, max_dns_servers); -} - -void BDHCPClient_GetServerMAC (BDHCPClient *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->up) - - BDHCPClientCore_GetServerMAC(&o->dhcp, out_mac); -} diff --git a/v2rayng/badvpn/dhcpclient/BDHCPClient.h b/v2rayng/badvpn/dhcpclient/BDHCPClient.h deleted file mode 100644 index c0da0c41f9..0000000000 --- a/v2rayng/badvpn/dhcpclient/BDHCPClient.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file BDHCPClient.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DHCP client. - */ - -#ifndef BADVPN_DHCPCLIENT_BDHCPCLIENT_H -#define BADVPN_DHCPCLIENT_BDHCPCLIENT_H - -#include -#include -#include -#include -#include -#include -#include - -#define BDHCPCLIENT_EVENT_UP 1 -#define BDHCPCLIENT_EVENT_DOWN 2 -#define BDHCPCLIENT_EVENT_ERROR 3 - -#define BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS - -typedef void (*BDHCPClient_handler) (void *user, int event); - -typedef struct { - BReactor *reactor; - BDatagram dgram; - BDHCPClient_handler handler; - void *user; - PacketCopier send_copier; - DHCPIpUdpEncoder send_encoder; - SinglePacketBuffer send_buffer; - SinglePacketBuffer recv_buffer; - DHCPIpUdpDecoder recv_decoder; - PacketCopier recv_copier; - BDHCPClientCore dhcp; - int up; - DebugError d_err; - DebugObject d_obj; -} BDHCPClient; - -struct BDHCPClient_opts { - const char *hostname; - const char *vendorclassid; - const uint8_t *clientid; - size_t clientid_len; - int auto_clientid; -}; - -int BDHCPClient_Init (BDHCPClient *o, const char *ifname, struct BDHCPClient_opts opts, BReactor *reactor, BRandom2 *random2, BDHCPClient_handler handler, void *user); -void BDHCPClient_Free (BDHCPClient *o); -int BDHCPClient_IsUp (BDHCPClient *o); -void BDHCPClient_GetClientIP (BDHCPClient *o, uint32_t *out_ip); -void BDHCPClient_GetClientMask (BDHCPClient *o, uint32_t *out_mask); -int BDHCPClient_GetRouter (BDHCPClient *o, uint32_t *out_router); -int BDHCPClient_GetDNS (BDHCPClient *o, uint32_t *out_dns_servers, size_t max_dns_servers); -void BDHCPClient_GetServerMAC (BDHCPClient *o, uint8_t *out_mac); - -#endif diff --git a/v2rayng/badvpn/dhcpclient/BDHCPClientCore.c b/v2rayng/badvpn/dhcpclient/BDHCPClientCore.c deleted file mode 100644 index 5a605e4221..0000000000 --- a/v2rayng/badvpn/dhcpclient/BDHCPClientCore.c +++ /dev/null @@ -1,860 +0,0 @@ -/** - * @file BDHCPClientCore.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define RESET_TIMEOUT 4000 -#define REQUEST_TIMEOUT 3000 -#define RENEW_REQUEST_TIMEOUT 20000 -#define MAX_REQUESTS 4 -#define RENEW_TIMEOUT(lease) ((btime_t)500 * (lease)) -#define XID_REUSE_MAX 8 - -#define LEASE_TIMEOUT(lease) ((btime_t)1000 * (lease) - RENEW_TIMEOUT(lease)) - -#define STATE_RESETTING 1 -#define STATE_SENT_DISCOVER 2 -#define STATE_SENT_REQUEST 3 -#define STATE_FINISHED 4 -#define STATE_RENEWING 5 - -#define IP_UDP_HEADERS_SIZE 28 - -static void report_up (BDHCPClientCore *o) -{ - o->handler(o->user, BDHCPCLIENTCORE_EVENT_UP); - return; -} - -static void report_down (BDHCPClientCore *o) -{ - o->handler(o->user, BDHCPCLIENTCORE_EVENT_DOWN); - return; -} - -static void send_message ( - BDHCPClientCore *o, - int type, - uint32_t xid, - int have_requested_ip_address, uint32_t requested_ip_address, - int have_dhcp_server_identifier, uint32_t dhcp_server_identifier -) -{ - ASSERT(type == DHCP_MESSAGE_TYPE_DISCOVER || type == DHCP_MESSAGE_TYPE_REQUEST) - - if (o->sending) { - BLog(BLOG_ERROR, "already sending"); - return; - } - - // write header - struct dhcp_header header; - memset(&header, 0, sizeof(header)); - header.op = hton8(DHCP_OP_BOOTREQUEST); - header.htype = hton8(DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET); - header.hlen = hton8(6); - header.xid = xid; - header.secs = hton16(0); - memcpy(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr)); - header.magic = hton32(DHCP_MAGIC); - memcpy(o->send_buf, &header, sizeof(header)); - - // write options - - char *out = o->send_buf + sizeof(header); - struct dhcp_option_header oh; - - // DHCP message type - { - oh.type = hton8(DHCP_OPTION_DHCP_MESSAGE_TYPE); - oh.len = hton8(sizeof(struct dhcp_option_dhcp_message_type)); - struct dhcp_option_dhcp_message_type opt; - opt.type = hton8(type); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (have_requested_ip_address) { - // requested IP address - oh.type = hton8(DHCP_OPTION_REQUESTED_IP_ADDRESS); - oh.len = hton8(sizeof(struct dhcp_option_addr)); - struct dhcp_option_addr opt; - opt.addr = requested_ip_address; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (have_dhcp_server_identifier) { - // DHCP server identifier - oh.type = hton8(DHCP_OPTION_DHCP_SERVER_IDENTIFIER); - oh.len = hton8(sizeof(struct dhcp_option_dhcp_server_identifier)); - struct dhcp_option_dhcp_server_identifier opt; - opt.id = dhcp_server_identifier; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - // maximum message size - { - oh.type = hton8(DHCP_OPTION_MAXIMUM_MESSAGE_SIZE); - oh.len = hton8(sizeof(struct dhcp_option_maximum_message_size)); - struct dhcp_option_maximum_message_size opt; - opt.size = hton16(IP_UDP_HEADERS_SIZE + PacketRecvInterface_GetMTU(o->recv_if)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - // parameter request list - { - oh.type = hton8(DHCP_OPTION_PARAMETER_REQUEST_LIST); - oh.len = hton8(4); - uint8_t opt[4]; - opt[0] = DHCP_OPTION_SUBNET_MASK; - opt[1] = DHCP_OPTION_ROUTER; - opt[2] = DHCP_OPTION_DOMAIN_NAME_SERVER; - opt[3] = DHCP_OPTION_IP_ADDRESS_LEASE_TIME; - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), &opt, sizeof(opt)); - out += sizeof(oh) + sizeof(opt); - } - - if (o->hostname) { - // host name - oh.type = hton8(DHCP_OPTION_HOST_NAME); - oh.len = hton8(strlen(o->hostname)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->hostname, strlen(o->hostname)); - out += sizeof(oh) + strlen(o->hostname); - } - - if (o->vendorclassid) { - // vendor class identifier - oh.type = hton8(DHCP_OPTION_VENDOR_CLASS_IDENTIFIER); - oh.len = hton8(strlen(o->vendorclassid)); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->vendorclassid, strlen(o->vendorclassid)); - out += sizeof(oh) + strlen(o->vendorclassid); - } - - if (o->clientid) { - // client identifier - oh.type = hton8(DHCP_OPTION_CLIENT_IDENTIFIER); - oh.len = hton8(o->clientid_len); - memcpy(out, &oh, sizeof(oh)); - memcpy(out + sizeof(oh), o->clientid, o->clientid_len); - out += sizeof(oh) + o->clientid_len; - } - - // end option - uint8_t end = 0xFF; - memcpy(out, &end, sizeof(end)); - out += sizeof(end); - - // send it - PacketPassInterface_Sender_Send(o->send_if, (uint8_t *)o->send_buf, out - o->send_buf); - o->sending = 1; -} - -static void send_handler_done (BDHCPClientCore *o) -{ - ASSERT(o->sending) - DebugObject_Access(&o->d_obj); - - o->sending = 0; -} - -static void recv_handler_done (BDHCPClientCore *o, int data_len) -{ - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - // receive more packets - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)o->recv_buf); - - if (o->state == STATE_RESETTING) { - return; - } - - // check header - - if (data_len < sizeof(struct dhcp_header)) { - return; - } - - struct dhcp_header header; - memcpy(&header, o->recv_buf, sizeof(header)); - - if (ntoh8(header.op) != DHCP_OP_BOOTREPLY) { - return; - } - - if (ntoh8(header.htype) != DHCP_HARDWARE_ADDRESS_TYPE_ETHERNET) { - return; - } - - if (ntoh8(header.hlen) != 6) { - return; - } - - if (header.xid != o->xid) { - return; - } - - if (memcmp(header.chaddr, o->client_mac_addr, sizeof(o->client_mac_addr))) { - return; - } - - if (ntoh32(header.magic) != DHCP_MAGIC) { - return; - } - - // parse and check options - - uint8_t *pos = (uint8_t *)o->recv_buf + sizeof(header); - int len = data_len - sizeof(header); - - int have_end = 0; - - int dhcp_message_type = -1; - - int have_dhcp_server_identifier = 0; - uint32_t dhcp_server_identifier = 0; // to remove warning - - int have_ip_address_lease_time = 0; - uint32_t ip_address_lease_time = 0; // to remove warning - - int have_subnet_mask = 0; - uint32_t subnet_mask = 0; // to remove warning - - int have_router = 0; - uint32_t router = 0; // to remove warning - - int domain_name_servers_count = 0; - uint32_t domain_name_servers[BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS]; - - while (len > 0) { - // padding option ? - if (*pos == 0) { - pos++; - len--; - continue; - } - - if (have_end) { - return; - } - - // end option ? - if (*pos == 0xff) { - pos++; - len--; - have_end = 1; - continue; - } - - // check option header - if (len < sizeof(struct dhcp_option_header)) { - return; - } - struct dhcp_option_header opt; - memcpy(&opt, pos, sizeof(opt)); - pos += sizeof(opt); - len -= sizeof(opt); - int opt_type = ntoh8(opt.type); - int opt_len = ntoh8(opt.len); - - // check option payload - if (opt_len > len) { - return; - } - uint8_t *optval = pos; - pos += opt_len; - len -= opt_len; - - switch (opt_type) { - case DHCP_OPTION_DHCP_MESSAGE_TYPE: { - if (opt_len != sizeof(struct dhcp_option_dhcp_message_type)) { - return; - } - struct dhcp_option_dhcp_message_type val; - memcpy(&val, optval, sizeof(val)); - - dhcp_message_type = ntoh8(val.type); - } break; - - case DHCP_OPTION_DHCP_SERVER_IDENTIFIER: { - if (opt_len != sizeof(struct dhcp_option_dhcp_server_identifier)) { - return; - } - struct dhcp_option_dhcp_server_identifier val; - memcpy(&val, optval, sizeof(val)); - - dhcp_server_identifier = val.id; - have_dhcp_server_identifier = 1; - } break; - - case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: { - if (opt_len != sizeof(struct dhcp_option_time)) { - return; - } - struct dhcp_option_time val; - memcpy(&val, optval, sizeof(val)); - - ip_address_lease_time = ntoh32(val.time); - have_ip_address_lease_time = 1; - } break; - - case DHCP_OPTION_SUBNET_MASK: { - if (opt_len != sizeof(struct dhcp_option_addr)) { - return; - } - struct dhcp_option_addr val; - memcpy(&val, optval, sizeof(val)); - - subnet_mask = val.addr; - have_subnet_mask = 1; - } break; - - case DHCP_OPTION_ROUTER: { - if (opt_len != sizeof(struct dhcp_option_addr)) { - return; - } - struct dhcp_option_addr val; - memcpy(&val, optval, sizeof(val)); - - router = val.addr; - have_router = 1; - } break; - - case DHCP_OPTION_DOMAIN_NAME_SERVER: { - if (opt_len % sizeof(struct dhcp_option_addr)) { - return; - } - - int num_servers = opt_len / sizeof(struct dhcp_option_addr); - - int i; - for (i = 0; i < num_servers && i < BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS; i++) { - struct dhcp_option_addr addr; - memcpy(&addr, optval + i * sizeof(addr), sizeof(addr)); - domain_name_servers[i] = addr.addr; - } - - domain_name_servers_count = i; - } break; - } - } - - if (!have_end) { - return; - } - - if (dhcp_message_type == -1) { - return; - } - - if (dhcp_message_type != DHCP_MESSAGE_TYPE_OFFER && dhcp_message_type != DHCP_MESSAGE_TYPE_ACK && dhcp_message_type != DHCP_MESSAGE_TYPE_NAK) { - return; - } - - if (!have_dhcp_server_identifier) { - return; - } - - if (dhcp_message_type == DHCP_MESSAGE_TYPE_NAK) { - if (o->state != STATE_SENT_REQUEST && o->state != STATE_FINISHED && o->state != STATE_RENEWING) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - if (o->state == STATE_SENT_REQUEST) { - BLog(BLOG_INFO, "received NAK (in sent request)"); - - // stop request timer - BReactor_RemoveTimer(o->reactor, &o->request_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - } - else if (o->state == STATE_FINISHED) { - BLog(BLOG_INFO, "received NAK (in finished)"); - - // stop renew timer - BReactor_RemoveTimer(o->reactor, &o->renew_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - - // report to user - report_down(o); - return; - } - else { // STATE_RENEWING - BLog(BLOG_INFO, "received NAK (in renewing)"); - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // stop lease timer - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - - // start reset timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_RESETTING; - - // report to user - report_down(o); - return; - } - - return; - } - - if (ntoh32(header.yiaddr) == 0) { - return; - } - - if (!have_ip_address_lease_time) { - return; - } - - if (!have_subnet_mask) { - return; - } - - if (o->state == STATE_SENT_DISCOVER && dhcp_message_type == DHCP_MESSAGE_TYPE_OFFER) { - BLog(BLOG_INFO, "received OFFER"); - - // remember offer - o->offered.yiaddr = header.yiaddr; - o->offered.dhcp_server_identifier = dhcp_server_identifier; - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 1, o->offered.dhcp_server_identifier); - - // stop reset timer - BReactor_RemoveTimer(o->reactor, &o->reset_timer); - - // start request timer - BReactor_SetTimer(o->reactor, &o->request_timer); - - // set state - o->state = STATE_SENT_REQUEST; - - // set request count - o->request_count = 1; - } - else if (o->state == STATE_SENT_REQUEST && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) { - if (header.yiaddr != o->offered.yiaddr) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - BLog(BLOG_INFO, "received ACK (in sent request)"); - - // remember stuff - o->acked.ip_address_lease_time = ip_address_lease_time; - o->acked.subnet_mask = subnet_mask; - o->acked.have_router = have_router; - if (have_router) { - o->acked.router = router; - } - o->acked.domain_name_servers_count = domain_name_servers_count; - memcpy(o->acked.domain_name_servers, domain_name_servers, domain_name_servers_count * sizeof(uint32_t)); - o->func_getsendermac(o->user, o->acked.server_mac); - - // stop request timer - BReactor_RemoveTimer(o->reactor, &o->request_timer); - - // start renew timer - BReactor_SetTimerAfter(o->reactor, &o->renew_timer, RENEW_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_FINISHED; - - // report to user - report_up(o); - return; - } - else if (o->state == STATE_RENEWING && dhcp_message_type == DHCP_MESSAGE_TYPE_ACK) { - if (header.yiaddr != o->offered.yiaddr) { - return; - } - - if (dhcp_server_identifier != o->offered.dhcp_server_identifier) { - return; - } - - // TODO: check parameters? - - BLog(BLOG_INFO, "received ACK (in renewing)"); - - // remember stuff - o->acked.ip_address_lease_time = ip_address_lease_time; - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // stop lease timer - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - - // start renew timer - BReactor_SetTimerAfter(o->reactor, &o->renew_timer, RENEW_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_FINISHED; - } -} - -static void start_process (BDHCPClientCore *o, int force_new_xid) -{ - if (force_new_xid || o->xid_reuse_counter == XID_REUSE_MAX) { - // generate xid - if (!BRandom2_GenBytes(o->random2, &o->xid, sizeof(o->xid))) { - BLog(BLOG_ERROR, "BRandom2_GenBytes failed"); - o->xid = UINT32_C(3416960072); - } - - // reset counter - o->xid_reuse_counter = 0; - } - - // increment counter - o->xid_reuse_counter++; - - // send discover - send_message(o, DHCP_MESSAGE_TYPE_DISCOVER, o->xid, 0, 0, 0, 0); - - // set timer - BReactor_SetTimer(o->reactor, &o->reset_timer); - - // set state - o->state = STATE_SENT_DISCOVER; -} - -static void reset_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RESETTING || o->state == STATE_SENT_DISCOVER) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "reset timer"); - - start_process(o, (o->state == STATE_RESETTING)); -} - -static void request_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_SENT_REQUEST) - ASSERT(o->request_count >= 1) - ASSERT(o->request_count <= MAX_REQUESTS) - DebugObject_Access(&o->d_obj); - - // if we have sent enough requests, start again - if (o->request_count == MAX_REQUESTS) { - BLog(BLOG_INFO, "request timer, aborting"); - - start_process(o, 0); - return; - } - - BLog(BLOG_INFO, "request timer, retrying"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 1, o->offered.dhcp_server_identifier); - - // start request timer - BReactor_SetTimer(o->reactor, &o->request_timer); - - // increment request count - o->request_count++; -} - -static void renew_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_FINISHED) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "renew timer"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 0, 0); - - // start renew request timer - BReactor_SetTimer(o->reactor, &o->renew_request_timer); - - // start lease timer - BReactor_SetTimerAfter(o->reactor, &o->lease_timer, LEASE_TIMEOUT(o->acked.ip_address_lease_time)); - - // set state - o->state = STATE_RENEWING; -} - -static void renew_request_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "renew request timer"); - - // send request - send_message(o, DHCP_MESSAGE_TYPE_REQUEST, o->xid, 1, o->offered.yiaddr, 0, 0); - - // start renew request timer - BReactor_SetTimer(o->reactor, &o->renew_request_timer); -} - -static void lease_timer_handler (BDHCPClientCore *o) -{ - ASSERT(o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - BLog(BLOG_INFO, "lease timer"); - - // stop renew request timer - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - - // start again now - start_process(o, 1); - - // report to user - report_down(o); - return; -} - -static bsize_t maybe_len (const char *str) -{ - return bsize_fromsize(str ? strlen(str) : 0); -} - -int BDHCPClientCore_Init (BDHCPClientCore *o, PacketPassInterface *send_if, PacketRecvInterface *recv_if, - uint8_t *client_mac_addr, struct BDHCPClientCore_opts opts, BReactor *reactor, - BRandom2 *random2, void *user, - BDHCPClientCore_func_getsendermac func_getsendermac, - BDHCPClientCore_handler handler) -{ - ASSERT(PacketPassInterface_GetMTU(send_if) == PacketRecvInterface_GetMTU(recv_if)) - ASSERT(PacketPassInterface_GetMTU(send_if) >= 576 - IP_UDP_HEADERS_SIZE) - ASSERT(func_getsendermac) - ASSERT(handler) - - // init arguments - o->send_if = send_if; - o->recv_if = recv_if; - memcpy(o->client_mac_addr, client_mac_addr, sizeof(o->client_mac_addr)); - o->reactor = reactor; - o->random2 = random2; - o->user = user; - o->func_getsendermac = func_getsendermac; - o->handler = handler; - - o->hostname = NULL; - o->vendorclassid = NULL; - o->clientid = NULL; - o->clientid_len = 0; - - // copy options - if (opts.hostname && !(o->hostname = strdup(opts.hostname))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail0; - } - if (opts.vendorclassid && !(o->vendorclassid = strdup(opts.vendorclassid))) { - BLog(BLOG_ERROR, "strdup failed"); - goto fail0; - } - if (opts.clientid) { - if (!(o->clientid = BAlloc(opts.clientid_len))) { - BLog(BLOG_ERROR, "BAlloc failed"); - goto fail0; - } - memcpy(o->clientid, opts.clientid, opts.clientid_len); - o->clientid_len = opts.clientid_len; - } - - // make sure options aren't too long - bsize_t opts_size = bsize_add(maybe_len(o->hostname), bsize_add(maybe_len(o->vendorclassid), bsize_fromsize(o->clientid_len))); - if (opts_size.is_overflow || opts_size.value > 100) { - BLog(BLOG_ERROR, "options too long together"); - goto fail0; - } - if (o->hostname && strlen(o->hostname) > 255) { - BLog(BLOG_ERROR, "hostname too long"); - goto fail0; - } - if (o->vendorclassid && strlen(o->vendorclassid) > 255) { - BLog(BLOG_ERROR, "vendorclassid too long"); - goto fail0; - } - if (o->clientid && o->clientid_len > 255) { - BLog(BLOG_ERROR, "clientid too long"); - goto fail0; - } - - // allocate buffers - if (!(o->send_buf = BAlloc(PacketPassInterface_GetMTU(send_if)))) { - BLog(BLOG_ERROR, "BAlloc send buf failed"); - goto fail0; - } - if (!(o->recv_buf = BAlloc(PacketRecvInterface_GetMTU(recv_if)))) { - BLog(BLOG_ERROR, "BAlloc recv buf failed"); - goto fail1; - } - - // init send interface - PacketPassInterface_Sender_Init(o->send_if, (PacketPassInterface_handler_done)send_handler_done, o); - - // init receive interface - PacketRecvInterface_Receiver_Init(o->recv_if, (PacketRecvInterface_handler_done)recv_handler_done, o); - - // set not sending - o->sending = 0; - - // init timers - BTimer_Init(&o->reset_timer, RESET_TIMEOUT, (BTimer_handler)reset_timer_handler, o); - BTimer_Init(&o->request_timer, REQUEST_TIMEOUT, (BTimer_handler)request_timer_handler, o); - BTimer_Init(&o->renew_timer, 0, (BTimer_handler)renew_timer_handler, o); - BTimer_Init(&o->renew_request_timer, RENEW_REQUEST_TIMEOUT, (BTimer_handler)renew_request_timer_handler, o); - BTimer_Init(&o->lease_timer, 0, (BTimer_handler)lease_timer_handler, o); - - // start receving - PacketRecvInterface_Receiver_Recv(o->recv_if, (uint8_t *)o->recv_buf); - - // start - start_process(o, 1); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - BFree(o->send_buf); -fail0: - BFree(o->clientid); - free(o->vendorclassid); - free(o->hostname); - return 0; -} - -void BDHCPClientCore_Free (BDHCPClientCore *o) -{ - DebugObject_Free(&o->d_obj); - - // free timers - BReactor_RemoveTimer(o->reactor, &o->lease_timer); - BReactor_RemoveTimer(o->reactor, &o->renew_request_timer); - BReactor_RemoveTimer(o->reactor, &o->renew_timer); - BReactor_RemoveTimer(o->reactor, &o->request_timer); - BReactor_RemoveTimer(o->reactor, &o->reset_timer); - - // free buffers - BFree(o->recv_buf); - BFree(o->send_buf); - - // free options - BFree(o->clientid); - free(o->vendorclassid); - free(o->hostname); -} - -void BDHCPClientCore_GetClientIP (BDHCPClientCore *o, uint32_t *out_ip) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - *out_ip = o->offered.yiaddr; -} - -void BDHCPClientCore_GetClientMask (BDHCPClientCore *o, uint32_t *out_mask) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - *out_mask = o->acked.subnet_mask; -} - -int BDHCPClientCore_GetRouter (BDHCPClientCore *o, uint32_t *out_router) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - if (!o->acked.have_router) { - return 0; - } - - *out_router = o->acked.router; - return 1; -} - -int BDHCPClientCore_GetDNS (BDHCPClientCore *o, uint32_t *out_dns_servers, size_t max_dns_servers) -{ - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - DebugObject_Access(&o->d_obj); - - int num_return = bmin_int(o->acked.domain_name_servers_count, max_dns_servers); - - memcpy(out_dns_servers, o->acked.domain_name_servers, num_return * sizeof(uint32_t)); - return num_return; -} - -void BDHCPClientCore_GetServerMAC (BDHCPClientCore *o, uint8_t *out_mac) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->state == STATE_FINISHED || o->state == STATE_RENEWING) - - memcpy(out_mac, o->acked.server_mac, 6); -} diff --git a/v2rayng/badvpn/dhcpclient/BDHCPClientCore.h b/v2rayng/badvpn/dhcpclient/BDHCPClientCore.h deleted file mode 100644 index 98cda365bf..0000000000 --- a/v2rayng/badvpn/dhcpclient/BDHCPClientCore.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file BDHCPClientCore.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * DHCP client, excluding system-dependent details. - */ - -#ifndef BADVPN_DHCPCLIENT_BDHCPCLIENTCORE_H -#define BADVPN_DHCPCLIENT_BDHCPCLIENTCORE_H - -#include -#include - -#include -#include -#include -#include -#include - -#define BDHCPCLIENTCORE_EVENT_UP 1 -#define BDHCPCLIENTCORE_EVENT_DOWN 2 - -#define BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS 16 - -typedef void (*BDHCPClientCore_func_getsendermac) (void *user, uint8_t *out_mac); -typedef void (*BDHCPClientCore_handler) (void *user, int event); - -struct BDHCPClientCore_opts { - const char *hostname; - const char *vendorclassid; - const uint8_t *clientid; - size_t clientid_len; -}; - -typedef struct { - PacketPassInterface *send_if; - PacketRecvInterface *recv_if; - uint8_t client_mac_addr[6]; - BReactor *reactor; - BRandom2 *random2; - void *user; - BDHCPClientCore_func_getsendermac func_getsendermac; - BDHCPClientCore_handler handler; - char *hostname; - char *vendorclassid; - uint8_t *clientid; - size_t clientid_len; - char *send_buf; - char *recv_buf; - int sending; - BTimer reset_timer; - BTimer request_timer; - BTimer renew_timer; - BTimer renew_request_timer; - BTimer lease_timer; - int state; - int request_count; - uint32_t xid; - int xid_reuse_counter; - struct { - uint32_t yiaddr; - uint32_t dhcp_server_identifier; - } offered; - struct { - uint32_t ip_address_lease_time; - uint32_t subnet_mask; - int have_router; - uint32_t router; - int domain_name_servers_count; - uint32_t domain_name_servers[BDHCPCLIENTCORE_MAX_DOMAIN_NAME_SERVERS]; - uint8_t server_mac[6]; - } acked; - DebugObject d_obj; -} BDHCPClientCore; - -int BDHCPClientCore_Init (BDHCPClientCore *o, PacketPassInterface *send_if, PacketRecvInterface *recv_if, - uint8_t *client_mac_addr, struct BDHCPClientCore_opts opts, BReactor *reactor, - BRandom2 *random2, void *user, - BDHCPClientCore_func_getsendermac func_getsendermac, - BDHCPClientCore_handler handler); -void BDHCPClientCore_Free (BDHCPClientCore *o); -void BDHCPClientCore_GetClientIP (BDHCPClientCore *o, uint32_t *out_ip); -void BDHCPClientCore_GetClientMask (BDHCPClientCore *o, uint32_t *out_mask); -int BDHCPClientCore_GetRouter (BDHCPClientCore *o, uint32_t *out_router); -int BDHCPClientCore_GetDNS (BDHCPClientCore *o, uint32_t *out_dns_servers, size_t max_dns_servers); -void BDHCPClientCore_GetServerMAC (BDHCPClientCore *o, uint8_t *out_mac); - -#endif diff --git a/v2rayng/badvpn/dhcpclient/CMakeLists.txt b/v2rayng/badvpn/dhcpclient/CMakeLists.txt deleted file mode 100644 index 5fd13005e6..0000000000 --- a/v2rayng/badvpn/dhcpclient/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -badvpn_add_library(dhcpclientcore "system;flow;flowextra;badvpn_random" "" BDHCPClientCore.c) - -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(DHCPCLIENT_SOURCES - BDHCPClient.c - DHCPIpUdpEncoder.c - DHCPIpUdpDecoder.c - ) - badvpn_add_library(dhcpclient "system;flow;dhcpclientcore" "" "${DHCPCLIENT_SOURCES}") -endif () diff --git a/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.c b/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.c deleted file mode 100644 index 1d1c7a757e..0000000000 --- a/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file DHCPIpUdpDecoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include - -#include - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_HEADER_SIZE (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static void input_handler_send (DHCPIpUdpDecoder *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - struct ipv4_header iph; - uint8_t *pl; - int pl_len; - - if (!ipv4_check(data, data_len, &iph, &pl, &pl_len)) { - goto fail; - } - - if (ntoh8(iph.protocol) != IPV4_PROTOCOL_UDP) { - goto fail; - } - - if (pl_len < sizeof(struct udp_header)) { - goto fail; - } - struct udp_header udph; - memcpy(&udph, pl, sizeof(udph)); - - if (ntoh16(udph.source_port) != DHCP_SERVER_PORT) { - goto fail; - } - - if (ntoh16(udph.dest_port) != DHCP_CLIENT_PORT) { - goto fail; - } - - int udph_length = ntoh16(udph.length); - if (udph_length < sizeof(udph)) { - goto fail; - } - if (udph_length > data_len - (pl - data)) { - goto fail; - } - - if (ntoh16(udph.checksum) != 0) { - uint16_t checksum_in_packet = udph.checksum; - udph.checksum = 0; - uint16_t checksum_computed = udp_checksum(&udph, pl + sizeof(udph), udph_length - sizeof(udph), iph.source_address, iph.destination_address); - if (checksum_in_packet != checksum_computed) { - goto fail; - } - } - - // pass payload to output - PacketPassInterface_Sender_Send(o->output, pl + sizeof(udph), udph_length - sizeof(udph)); - - return; - -fail: - PacketPassInterface_Done(&o->input); -} - -static void output_handler_done (DHCPIpUdpDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Done(&o->input); -} - -void DHCPIpUdpDecoder_Init (DHCPIpUdpDecoder *o, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) <= INT_MAX - IPUDP_HEADER_SIZE) - - // init arguments - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init input - PacketPassInterface_Init(&o->input, IPUDP_HEADER_SIZE + PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DHCPIpUdpDecoder_Free (DHCPIpUdpDecoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * DHCPIpUdpDecoder_GetInput (DHCPIpUdpDecoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.h b/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.h deleted file mode 100644 index ce9213861c..0000000000 --- a/v2rayng/badvpn/dhcpclient/DHCPIpUdpDecoder.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file DHCPIpUdpDecoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_DHCPCLIENT_DHCPIPUDPDECODER_H -#define BADVPN_DHCPCLIENT_DHCPIPUDPDECODER_H - -#include - -#include -#include - -typedef struct { - PacketPassInterface *output; - PacketPassInterface input; - uint8_t *data; - DebugObject d_obj; -} DHCPIpUdpDecoder; - -void DHCPIpUdpDecoder_Init (DHCPIpUdpDecoder *o, PacketPassInterface *output, BPendingGroup *pg); -void DHCPIpUdpDecoder_Free (DHCPIpUdpDecoder *o); -PacketPassInterface * DHCPIpUdpDecoder_GetInput (DHCPIpUdpDecoder *o); - -#endif diff --git a/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.c b/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.c deleted file mode 100644 index da6645c10a..0000000000 --- a/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file DHCPIpUdpEncoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -#include - -#define DHCP_SERVER_PORT 67 -#define DHCP_CLIENT_PORT 68 - -#define IPUDP_HEADER_SIZE (sizeof(struct ipv4_header) + sizeof(struct udp_header)) - -static void output_handler_recv (DHCPIpUdpEncoder *o, uint8_t *data) -{ - DebugObject_Access(&o->d_obj); - - // remember output packet - o->data = data; - - // receive payload - PacketRecvInterface_Receiver_Recv(o->input, o->data + IPUDP_HEADER_SIZE); -} - -static void input_handler_done (DHCPIpUdpEncoder *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // build IP header - struct ipv4_header iph; - iph.version4_ihl4 = IPV4_MAKE_VERSION_IHL(sizeof(iph)); - iph.ds = hton8(0); - iph.total_length = hton16(IPUDP_HEADER_SIZE + data_len); - iph.identification = hton16(0); - iph.flags3_fragmentoffset13 = hton16(0); - iph.ttl = hton8(64); - iph.protocol = hton8(IPV4_PROTOCOL_UDP); - iph.checksum = hton16(0); - iph.source_address = hton32(0x00000000); - iph.destination_address = hton32(0xFFFFFFFF); - iph.checksum = ipv4_checksum(&iph, NULL, 0); - - // write UDP header - struct udp_header udph; - udph.source_port = hton16(DHCP_CLIENT_PORT); - udph.dest_port = hton16(DHCP_SERVER_PORT); - udph.length = hton16(sizeof(udph) + data_len); - udph.checksum = hton16(0); - udph.checksum = udp_checksum(&udph, o->data + IPUDP_HEADER_SIZE, data_len, iph.source_address, iph.destination_address); - - // write header - memcpy(o->data, &iph, sizeof(iph)); - memcpy(o->data + sizeof(iph), &udph, sizeof(udph)); - - // finish packet - PacketRecvInterface_Done(&o->output, IPUDP_HEADER_SIZE + data_len); -} - -void DHCPIpUdpEncoder_Init (DHCPIpUdpEncoder *o, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= INT_MAX - IPUDP_HEADER_SIZE) - - // init arguments - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketRecvInterface_Init(&o->output, IPUDP_HEADER_SIZE + PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - DebugObject_Init(&o->d_obj); -} - -void DHCPIpUdpEncoder_Free (DHCPIpUdpEncoder *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * DHCPIpUdpEncoder_GetOutput (DHCPIpUdpEncoder *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.h b/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.h deleted file mode 100644 index d3e0ac0603..0000000000 --- a/v2rayng/badvpn/dhcpclient/DHCPIpUdpEncoder.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file DHCPIpUdpEncoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_DHCPCLIENT_DHCPIPUDPENCODER_H -#define BADVPN_DHCPCLIENT_DHCPIPUDPENCODER_H - -#include - -#include -#include - -typedef struct { - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *data; - DebugObject d_obj; -} DHCPIpUdpEncoder; - -void DHCPIpUdpEncoder_Init (DHCPIpUdpEncoder *o, PacketRecvInterface *input, BPendingGroup *pg); -void DHCPIpUdpEncoder_Free (DHCPIpUdpEncoder *o); -PacketRecvInterface * DHCPIpUdpEncoder_GetOutput (DHCPIpUdpEncoder *o); - -#endif diff --git a/v2rayng/badvpn/dostest/CMakeLists.txt b/v2rayng/badvpn/dostest/CMakeLists.txt deleted file mode 100644 index 8d3b74223a..0000000000 --- a/v2rayng/badvpn/dostest/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_executable(dostest-server - dostest-server.c - StreamBuffer.c -) -target_link_libraries(dostest-server base system) - -add_executable(dostest-attacker - dostest-attacker.c -) -target_link_libraries(dostest-attacker base system) diff --git a/v2rayng/badvpn/dostest/StreamBuffer.c b/v2rayng/badvpn/dostest/StreamBuffer.c deleted file mode 100644 index d439127677..0000000000 --- a/v2rayng/badvpn/dostest/StreamBuffer.c +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file StreamBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "StreamBuffer.h" - -// called when receive operation is complete -static void input_handler_done (void *vo, int data_len) -{ - StreamBuffer *o = (StreamBuffer *)vo; - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_size - (o->buf_start + o->buf_used)) - - // remember if buffer was empty - int was_empty = (o->buf_used == 0); - - // increment buf_used by the amount that was received - o->buf_used += data_len; - - // start another receive operation unless buffer is full - if (o->buf_used < o->buf_size - o->buf_start) { - int end = o->buf_start + o->buf_used; - StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, o->buf_size - end); - } - else if (o->buf_used < o->buf_size) { - // wrap around - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_start); - } - - // if buffer was empty before, start send operation - if (was_empty) { - StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, o->buf_used); - } -} - -// called when send operation is complete -static void output_handler_done (void *vo, int data_len) -{ - StreamBuffer *o = (StreamBuffer *)vo; - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_used) - ASSERT(data_len <= o->buf_size - o->buf_start) - - // remember if buffer was full - int was_full = (o->buf_used == o->buf_size); - - // increment buf_start and decrement buf_used by the - // amount that was sent - o->buf_start += data_len; - o->buf_used -= data_len; - - // wrap around buf_start - if (o->buf_start == o->buf_size) { - o->buf_start = 0; - } - - // start receive operation if buffer was full - if (was_full) { - int end; - int avail; - if (o->buf_used >= o->buf_size - o->buf_start) { - end = o->buf_used - (o->buf_size - o->buf_start); - avail = o->buf_start - end; - } else { - end = o->buf_start + o->buf_used; - avail = o->buf_size - end; - } - StreamRecvInterface_Receiver_Recv(o->input, o->buf + end, avail); - } - - // start another receive send unless buffer is empty - if (o->buf_used > 0) { - int to_send = bmin_int(o->buf_used, o->buf_size - o->buf_start); - StreamPassInterface_Sender_Send(o->output, o->buf + o->buf_start, to_send); - } -} - -int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output) -{ - ASSERT(buf_size > 0) - ASSERT(input) - ASSERT(output) - - // remember arguments - o->buf_size = buf_size; - o->input = input; - o->output = output; - - // allocate buffer memory - o->buf = (uint8_t *)BAllocSize(bsize_fromint(o->buf_size)); - if (!o->buf) { - goto fail0; - } - - // set initial buffer state - o->buf_start = 0; - o->buf_used = 0; - - // set receive and send done callbacks - StreamRecvInterface_Receiver_Init(o->input, input_handler_done, o); - StreamPassInterface_Sender_Init(o->output, output_handler_done, o); - - // start receive operation - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void StreamBuffer_Free (StreamBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer memory - BFree(o->buf); -} diff --git a/v2rayng/badvpn/dostest/StreamBuffer.h b/v2rayng/badvpn/dostest/StreamBuffer.h deleted file mode 100644 index dd441f5b40..0000000000 --- a/v2rayng/badvpn/dostest/StreamBuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file StreamBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STREAMBUFFER_H -#define BADVPN_STREAMBUFFER_H - -#include -#include -#include -#include - -/** - * Buffer object which reads data from a \link StreamRecvInterface and writes - * it to a \link StreamPassInterface. - */ -typedef struct { - int buf_size; - StreamRecvInterface *input; - StreamPassInterface *output; - uint8_t *buf; - int buf_start; - int buf_used; - DebugObject d_obj; -} StreamBuffer; - -/** - * Initializes the buffer object. - * - * @param o object to initialize - * @param buf_size size of the buffer. Must be >0. - * @param input input interface - * @param outout output interface - * @return 1 on success, 0 on failure - */ -int StreamBuffer_Init (StreamBuffer *o, int buf_size, StreamRecvInterface *input, StreamPassInterface *output) WARN_UNUSED; - -/** - * Frees the buffer object. - * - * @param o object to free - */ -void StreamBuffer_Free (StreamBuffer *o); - -#endif diff --git a/v2rayng/badvpn/dostest/dostest-attacker.c b/v2rayng/badvpn/dostest/dostest-attacker.c deleted file mode 100644 index 723dadd81a..0000000000 --- a/v2rayng/badvpn/dostest/dostest-attacker.c +++ /dev/null @@ -1,512 +0,0 @@ -/** - * @file dostest-attacker.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define PROGRAM_NAME "dostest-attacker" - -// connection structure -struct connection { - int connected; - BConnector connector; - BConnection con; - StreamRecvInterface *recv_if; - uint8_t buf[512]; - LinkedList1Node connections_list_node; -}; - -// command-line options -static struct { - int help; - int version; - char *connect_addr; - int max_connections; - int max_connecting; - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; -} options; - -// connect address -static BAddr connect_addr; - -// reactor -static BReactor reactor; - -// connections -static LinkedList1 connections_list; -static int num_connections; -static int num_connecting; - -// timer for scheduling creation of more connections -static BTimer make_connections_timer; - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static int connection_new (void); -static void connection_free (struct connection *conn); -static void connection_logfunc (struct connection *conn); -static void connection_log (struct connection *conn, int level, const char *fmt, ...); -static void connection_connector_handler (struct connection *conn, int is_error); -static void connection_connection_handler (struct connection *conn, int event); -static void connection_recv_handler_done (struct connection *conn, int data_len); -static void make_connections_timer_handler (void *unused); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // init loger - BLog_InitStderr(); - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&reactor)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // init connections list - LinkedList1_Init(&connections_list); - num_connections = 0; - num_connecting = 0; - - // init make connections timer - BTimer_Init(&make_connections_timer, 0, make_connections_timer_handler, NULL); - BReactor_SetTimer(&reactor, &make_connections_timer); - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&reactor); - - // free connections - while (!LinkedList1_IsEmpty(&connections_list)) { - struct connection *conn = UPPER_OBJECT(LinkedList1_GetFirst(&connections_list), struct connection, connections_list_node); - connection_free(conn); - } - // free make connections timer - BReactor_RemoveTimer(&reactor, &make_connections_timer); - // free signal - BSignal_Finish(); -fail2: - // free reactor - BReactor_Free(&reactor); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish debug objects - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " --connect-addr \n" - " --max-connections \n" - " --max-connecting \n" - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <0-5/none/error/warning/notice/info/debug>] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - options.help = 0; - options.version = 0; - options.connect_addr = NULL; - options.max_connections = -1; - options.max_connecting = -1; - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--connect-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.connect_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--max-connections")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_connections = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--max-connecting")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_connecting = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.connect_addr) { - fprintf(stderr, "--connect-addr missing\n"); - return 0; - } - - if (options.max_connections == -1) { - fprintf(stderr, "--max-connections missing\n"); - return 0; - } - - if (options.max_connecting == -1) { - fprintf(stderr, "--max-connecting missing\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen address - if (!BAddr_Parse(&connect_addr, options.connect_addr, NULL, 0)) { - BLog(BLOG_ERROR, "connect addr: BAddr_Parse failed"); - return 0; - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&reactor, 1); -} - -int connection_new (void) -{ - // allocate structure - struct connection *conn = (struct connection *)malloc(sizeof(*conn)); - if (!conn) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // set not connected - conn->connected = 0; - - // init connector - if (!BConnector_Init(&conn->connector, connect_addr, &reactor, conn, (BConnector_handler)connection_connector_handler)) { - BLog(BLOG_ERROR, "BConnector_Init failed"); - goto fail1; - } - - // add to connections list - LinkedList1_Append(&connections_list, &conn->connections_list_node); - num_connections++; - num_connecting++; - - return 1; - -fail1: - free(conn); -fail0: - return 0; -} - -void connection_free (struct connection *conn) -{ - // remove from connections list - LinkedList1_Remove(&connections_list, &conn->connections_list_node); - num_connections--; - if (!conn->connected) { - num_connecting--; - } - - if (conn->connected) { - // free receive interface - BConnection_RecvAsync_Free(&conn->con); - - // free connection - BConnection_Free(&conn->con); - } - - // free connector - BConnector_Free(&conn->connector); - - // free structure - free(conn); -} - -void connection_logfunc (struct connection *conn) -{ - BLog_Append("%d connection (%p): ", num_connecting, (void *)conn); -} - -void connection_log (struct connection *conn, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)connection_logfunc, conn, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void connection_connector_handler (struct connection *conn, int is_error) -{ - ASSERT(!conn->connected) - - // check for connection error - if (is_error) { - connection_log(conn, BLOG_INFO, "failed to connect"); - goto fail0; - } - - // init connection from connector - if (!BConnection_Init(&conn->con, BConnection_source_connector(&conn->connector), &reactor, conn, (BConnection_handler)connection_connection_handler)) { - connection_log(conn, BLOG_INFO, "BConnection_Init failed"); - goto fail0; - } - - // init receive interface - BConnection_RecvAsync_Init(&conn->con); - conn->recv_if = BConnection_RecvAsync_GetIf(&conn->con); - StreamRecvInterface_Receiver_Init(conn->recv_if, (StreamRecvInterface_handler_done)connection_recv_handler_done, conn); - - // start receiving - StreamRecvInterface_Receiver_Recv(conn->recv_if, conn->buf, sizeof(conn->buf)); - - // no longer connecting - conn->connected = 1; - num_connecting--; - - connection_log(conn, BLOG_INFO, "connected"); - - // schedule making connections (because of connecting limit) - BReactor_SetTimer(&reactor, &make_connections_timer); - return; - -fail0: - // free connection - connection_free(conn); - - // schedule making connections - BReactor_SetTimer(&reactor, &make_connections_timer); -} - -void connection_connection_handler (struct connection *conn, int event) -{ - ASSERT(conn->connected) - - if (event == BCONNECTION_EVENT_RECVCLOSED) { - connection_log(conn, BLOG_INFO, "connection closed"); - } else { - connection_log(conn, BLOG_INFO, "connection error"); - } - - // free connection - connection_free(conn); - - // schedule making connections - BReactor_SetTimer(&reactor, &make_connections_timer); -} - -void connection_recv_handler_done (struct connection *conn, int data_len) -{ - ASSERT(conn->connected) - - // receive more - StreamRecvInterface_Receiver_Recv(conn->recv_if, conn->buf, sizeof(conn->buf)); - - connection_log(conn, BLOG_INFO, "received %d bytes", data_len); -} - -void make_connections_timer_handler (void *unused) -{ - int make_num = bmin_int(options.max_connections - num_connections, options.max_connecting - num_connecting); - - if (make_num <= 0) { - return; - } - - BLog(BLOG_INFO, "making %d connections", make_num); - - for (int i = 0; i < make_num; i++) { - if (!connection_new()) { - // can happen if fd limit is reached - BLog(BLOG_ERROR, "failed to make connection, waiting"); - BReactor_SetTimerAfter(&reactor, &make_connections_timer, 10); - return; - } - } -} diff --git a/v2rayng/badvpn/dostest/dostest-server.c b/v2rayng/badvpn/dostest/dostest-server.c deleted file mode 100644 index 744759145d..0000000000 --- a/v2rayng/badvpn/dostest/dostest-server.c +++ /dev/null @@ -1,567 +0,0 @@ -/** - * @file dostest-server.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#ifdef BADVPN_LINUX -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "StreamBuffer.h" - -#include - -#define PROGRAM_NAME "dostest-server" - -#ifdef BADVPN_LINUX -#ifndef SO_DOSDEF_PREPARE -#define SO_DOSDEF_PREPARE 48 -#endif -#ifndef SO_DOSDEF_ACTIVATE -#define SO_DOSDEF_ACTIVATE 49 -#endif -#endif - -#define BUF_SIZE 1024 - -// client structure -struct client { - BConnection con; - BAddr addr; - StreamBuffer buf; - BTimer disconnect_timer; - LinkedList1Node clients_list_node; -}; - -// command-line options -static struct { - int help; - int version; - char *listen_addr; - int max_clients; - int disconnect_time; - int defense_prepare_clients; - int defense_activate_clients; - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; -} options; - -// listen address -static BAddr listen_addr; - -// reactor -static BReactor ss; - -// listener -static BListener listener; - -// clients -static LinkedList1 clients_list; -static int num_clients; - -// defense status -static int defense_prepare; -static int defense_activate; - -static void print_help (const char *name); -static void print_version (void); -static int parse_arguments (int argc, char *argv[]); -static int process_arguments (void); -static void signal_handler (void *unused); -static void listener_handler (void *unused); -static void client_free (struct client *client); -static void client_logfunc (struct client *client); -static void client_log (struct client *client, int level, const char *fmt, ...); -static void client_disconnect_timer_handler (struct client *client); -static void client_connection_handler (struct client *client, int event); -static void update_defense (void); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // init loger - BLog_InitStderr(); - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // process arguments - if (!process_arguments()) { - BLog(BLOG_ERROR, "Failed to process arguments"); - goto fail1; - } - - // init time - BTime_Init(); - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail2; - } - - // initialize listener - if (!BListener_Init(&listener, listen_addr, &ss, NULL, listener_handler)) { - BLog(BLOG_ERROR, "Listener_Init failed"); - goto fail3; - } - - // init clients list - LinkedList1_Init(&clients_list); - num_clients = 0; - - // clear defense state - defense_prepare = 0; - defense_activate = 0; - - // update defense - update_defense(); - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - // free clients - while (!LinkedList1_IsEmpty(&clients_list)) { - struct client *client = UPPER_OBJECT(LinkedList1_GetFirst(&clients_list), struct client, clients_list_node); - client_free(client); - } - // free listener - BListener_Free(&listener); -fail3: - // free signal - BSignal_Finish(); -fail2: - // free reactor - BReactor_Free(&ss); -fail1: - // free logger - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - // finish debug objects - DebugObjectGlobal_Finish(); - - return 1; -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " --listen-addr \n" - " --max-clients \n" - " --disconnect-time \n" - " [--defense-prepare-clients ]\n" - " [--defense-activate-clients ]\n" - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <0-5/none/error/warning/notice/info/debug>] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - options.help = 0; - options.version = 0; - options.listen_addr = NULL; - options.max_clients = -1; - options.disconnect_time = -1; - options.defense_prepare_clients = -1; - options.defense_activate_clients = -1; - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--listen-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.listen_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--max-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.max_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--disconnect-time")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.disconnect_time = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--defense-prepare-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.defense_prepare_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--defense-activate-clients")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.defense_activate_clients = atoi(argv[i + 1])) <= 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (!options.listen_addr) { - fprintf(stderr, "--listen-addr missing\n"); - return 0; - } - - if (options.max_clients == -1) { - fprintf(stderr, "--max-clients missing\n"); - return 0; - } - - if (options.disconnect_time == -1) { - fprintf(stderr, "--disconnect-time missing\n"); - return 0; - } - - return 1; -} - -int process_arguments (void) -{ - // resolve listen address - if (!BAddr_Parse(&listen_addr, options.listen_addr, NULL, 0)) { - BLog(BLOG_ERROR, "listen addr: BAddr_Parse failed"); - return 0; - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - // exit event loop - BReactor_Quit(&ss, 1); -} - -void listener_handler (void *unused) -{ - if (num_clients == options.max_clients) { - BLog(BLOG_ERROR, "maximum number of clients reached"); - goto fail0; - } - - // allocate structure - struct client *client = (struct client *)malloc(sizeof(*client)); - if (!client) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // accept client - if (!BConnection_Init(&client->con, BConnection_source_listener(&listener, &client->addr), &ss, client, (BConnection_handler)client_connection_handler)) { - BLog(BLOG_ERROR, "BConnection_Init failed"); - goto fail1; - } - - // init connection interfaces - BConnection_RecvAsync_Init(&client->con); - BConnection_SendAsync_Init(&client->con); - StreamRecvInterface *recv_if = BConnection_RecvAsync_GetIf(&client->con); - StreamPassInterface *send_if = BConnection_SendAsync_GetIf(&client->con); - - // init stream buffer (to loop received data back to the client) - if (!StreamBuffer_Init(&client->buf, BUF_SIZE, recv_if, send_if)) { - BLog(BLOG_ERROR, "StreamBuffer_Init failed"); - goto fail2; - } - - // init disconnect timer - BTimer_Init(&client->disconnect_timer, options.disconnect_time, (BTimer_handler)client_disconnect_timer_handler, client); - BReactor_SetTimer(&ss, &client->disconnect_timer); - - // insert to clients list - LinkedList1_Append(&clients_list, &client->clients_list_node); - num_clients++; - - client_log(client, BLOG_INFO, "connected"); - BLog(BLOG_NOTICE, "%d clients", num_clients); - - // update defense - update_defense(); - return; - -fail2: - BConnection_SendAsync_Free(&client->con); - BConnection_RecvAsync_Free(&client->con); - BConnection_Free(&client->con); -fail1: - free(client); -fail0: - return; -} - -void client_free (struct client *client) -{ - // remove from clients list - LinkedList1_Remove(&clients_list, &client->clients_list_node); - num_clients--; - - // free disconnect timer - BReactor_RemoveTimer(&ss, &client->disconnect_timer); - - // free stream buffer - StreamBuffer_Free(&client->buf); - - // free connection interfaces - BConnection_SendAsync_Free(&client->con); - BConnection_RecvAsync_Free(&client->con); - - // free connection - BConnection_Free(&client->con); - - // free structure - free(client); - - BLog(BLOG_NOTICE, "%d clients", num_clients); - - // update defense - update_defense(); -} - -void client_logfunc (struct client *client) -{ - char addr[BADDR_MAX_PRINT_LEN]; - BAddr_Print(&client->addr, addr); - - BLog_Append("client (%s): ", addr); -} - -void client_log (struct client *client, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - BLog_LogViaFuncVarArg((BLog_logfunc)client_logfunc, client, BLOG_CURRENT_CHANNEL, level, fmt, vl); - va_end(vl); -} - -void client_disconnect_timer_handler (struct client *client) -{ - client_log(client, BLOG_INFO, "timed out, disconnecting"); - - // free client - client_free(client); -} - -void client_connection_handler (struct client *client, int event) -{ - if (event == BCONNECTION_EVENT_RECVCLOSED) { - client_log(client, BLOG_INFO, "client closed"); - } else { - client_log(client, BLOG_INFO, "client error"); - } - - // free client - client_free(client); -} - -void update_defense (void) -{ -#ifdef BADVPN_LINUX - if (options.defense_prepare_clients != -1) { - int val = num_clients >= options.defense_prepare_clients; - int res = setsockopt(listener.fd, SOL_SOCKET, SO_DOSDEF_PREPARE, &val, sizeof(val)); - if (res < 0) { - BLog(BLOG_ERROR, "failed to %s defense preparation", (val ? "enable" : "disable")); - } else { - if (!defense_prepare && val) { - BLog(BLOG_NOTICE, "defense preparation enabled"); - } - else if (defense_prepare && !val) { - BLog(BLOG_NOTICE, "defense preparation disabled"); - } - } - defense_prepare = val; - } - - if (options.defense_activate_clients != -1) { - int val = num_clients >= options.defense_activate_clients; - int res = setsockopt(listener.fd, SOL_SOCKET, SO_DOSDEF_ACTIVATE, &val, sizeof(val)); - if (res < 0) { - BLog(BLOG_ERROR, "failed to %s defense activation", (val ? "enable" : "disable")); - } else { - if (!defense_activate && val) { - BLog(BLOG_NOTICE, "defense activation enabled"); - } - else if (defense_activate && !val) { - BLog(BLOG_NOTICE, "defense activation disabled"); - } - } - defense_activate = val; - } -#endif -} diff --git a/v2rayng/badvpn/examples/CMakeLists.txt b/v2rayng/badvpn/examples/CMakeLists.txt deleted file mode 100644 index 27dbeaa9e1..0000000000 --- a/v2rayng/badvpn/examples/CMakeLists.txt +++ /dev/null @@ -1,97 +0,0 @@ -if (NOT EMSCRIPTEN) - add_executable(btimer_example btimer_example.c) - target_link_libraries(btimer_example system) -endif () - -if (BUILDING_PREDICATE) - add_executable(predicate_test predicate_test.c) - target_link_libraries(predicate_test predicate) -endif () - -if (NOT EMSCRIPTEN) - add_executable(fairqueue_test fairqueue_test.c) - target_link_libraries(fairqueue_test system flow) -endif () - -add_executable(indexedlist_test indexedlist_test.c) - -if (BUILDING_SECURITY) - add_executable(fairqueue_test2 fairqueue_test2.c) - target_link_libraries(fairqueue_test2 system flow security) - - add_executable(bavl_test bavl_test.c) - target_link_libraries(bavl_test security) - - add_executable(savl_test savl_test.c) - target_link_libraries(savl_test security) - - add_executable(bencryption_bench bencryption_bench.c) - target_link_libraries(bencryption_bench system security) -endif () - -if (BUILD_NCD) - add_executable(ncd_tokenizer_test ncd_tokenizer_test.c) - target_link_libraries(ncd_tokenizer_test ncdtokenizer) - - add_executable(ncd_parser_test ncd_parser_test.c) - target_link_libraries(ncd_parser_test ncdconfigparser ncdvalgenerator ncdsugar) - - add_executable(ncd_value_parser_test ncd_value_parser_test.c) - target_link_libraries(ncd_value_parser_test ncdvalparser ncdvalgenerator) - - if (NOT EMSCRIPTEN) - add_executable(ncdinterfacemonitor_test ncdinterfacemonitor_test.c) - target_link_libraries(ncdinterfacemonitor_test ncdinterfacemonitor) - endif () - - add_executable(ncdval_test ncdval_test.c) - target_link_libraries(ncdval_test ncdval) - - add_executable(ncdvalcons_test ncdvalcons_test.c) - target_link_libraries(ncdvalcons_test ncdvalcons ncdvalgenerator) -endif () - -if (BUILDING_UDEVMONITOR) - add_executable(ncdudevmonitor_test ncdudevmonitor_test.c) - target_link_libraries(ncdudevmonitor_test udevmonitor) - - add_executable(ncdudevmanager_test ncdudevmanager_test.c) - target_link_libraries(ncdudevmanager_test udevmonitor) -endif () - -if (NOT WIN32 AND NOT EMSCRIPTEN) - add_executable(bprocess_example bprocess_example.c) - target_link_libraries(bprocess_example system) - - add_executable(stdin_input stdin_input.c) - target_link_libraries(stdin_input system flow flowextra) -endif () - -if (BUILDING_DHCPCLIENT) - add_executable(dhcpclient_test dhcpclient_test.c) - target_link_libraries(dhcpclient_test dhcpclient) -endif () - -if (BUILDING_ARPPROBE) - add_executable(arpprobe_test arpprobe_test.c) - target_link_libraries(arpprobe_test arpprobe) -endif () - -add_executable(substring_test substring_test.c) - -if (NOT WIN32) - add_executable(ipaddr6_test ipaddr6_test.c) - add_executable(parse_number_test parse_number_test.c) -endif () - -if (BUILDING_RANDOM) - add_executable(brandom2_test brandom2_test.c) - target_link_libraries(brandom2_test badvpn_random) -endif () - -add_executable(cavl_test cavl_test.c) - -if (EMSCRIPTEN) - add_executable(emscripten_test emscripten_test.c) - target_link_libraries(emscripten_test system) -endif () diff --git a/v2rayng/badvpn/examples/FastPacketSource.h b/v2rayng/badvpn/examples/FastPacketSource.h deleted file mode 100644 index e13e2f2c29..0000000000 --- a/v2rayng/badvpn/examples/FastPacketSource.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file FastPacketSource.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _FASTPACKETSOURCE_H -#define _FASTPACKETSOURCE_H - -#include -#include - -#include -#include -#include - -typedef struct { - PacketPassInterface *output; - int psize; - uint8_t *data; - int data_len; - DebugObject d_obj; -} FastPacketSource; - -static void _FastPacketSource_output_handler_done (FastPacketSource *s) -{ - DebugObject_Access(&s->d_obj); - - PacketPassInterface_Sender_Send(s->output, s->data, s->data_len); -} - -static void FastPacketSource_Init (FastPacketSource *s, PacketPassInterface *output, uint8_t *data, int data_len, BPendingGroup *pg) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= PacketPassInterface_GetMTU(output)); - - // init arguments - s->output = output; - s->data = data; - s->data_len = data_len; - - // init output - PacketPassInterface_Sender_Init(s->output, (PacketPassInterface_handler_done)_FastPacketSource_output_handler_done, s); - - // schedule send - PacketPassInterface_Sender_Send(s->output, s->data, s->data_len); - - DebugObject_Init(&s->d_obj); -} - -static void FastPacketSource_Free (FastPacketSource *s) -{ - DebugObject_Free(&s->d_obj); -} - -#endif diff --git a/v2rayng/badvpn/examples/RandomPacketSink.h b/v2rayng/badvpn/examples/RandomPacketSink.h deleted file mode 100644 index cbadf78793..0000000000 --- a/v2rayng/badvpn/examples/RandomPacketSink.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file RandomPacketSink.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _RANDOMPACKETSINK_H -#define _RANDOMPACKETSINK_H - -#include - -#include -#include -#include -#include -#include - -typedef struct { - BReactor *reactor; - PacketPassInterface input; - BTimer timer; - DebugObject d_obj; -} RandomPacketSink; - -static void _RandomPacketSink_input_handler_send (RandomPacketSink *s, uint8_t *data, int data_len) -{ - DebugObject_Access(&s->d_obj); - - printf("sink: send '"); - size_t res = fwrite(data, data_len, 1, stdout); - B_USE(res) - - uint8_t r; - BRandom_randomize(&r, sizeof(r)); - if (r&(uint8_t)1) { - printf("' accepting\n"); - PacketPassInterface_Done(&s->input); - } else { - printf("' delaying\n"); - BReactor_SetTimer(s->reactor, &s->timer); - } -} - -static void _RandomPacketSink_input_handler_requestcancel (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - printf("sink: cancelled\n"); - BReactor_RemoveTimer(s->reactor, &s->timer); - PacketPassInterface_Done(&s->input); -} - -static void _RandomPacketSink_timer_handler (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - PacketPassInterface_Done(&s->input); -} - -static void RandomPacketSink_Init (RandomPacketSink *s, BReactor *reactor, int mtu, int ms) -{ - // init arguments - s->reactor = reactor; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)_RandomPacketSink_input_handler_send, s, BReactor_PendingGroup(reactor)); - PacketPassInterface_EnableCancel(&s->input, (PacketPassInterface_handler_requestcancel)_RandomPacketSink_input_handler_requestcancel); - - // init timer - BTimer_Init(&s->timer, ms, (BTimer_handler)_RandomPacketSink_timer_handler, s); - - DebugObject_Init(&s->d_obj); -} - -static void RandomPacketSink_Free (RandomPacketSink *s) -{ - DebugObject_Free(&s->d_obj); - - // free timer - BReactor_RemoveTimer(s->reactor, &s->timer); - - // free input - PacketPassInterface_Free(&s->input); -} - -static PacketPassInterface * RandomPacketSink_GetInput (RandomPacketSink *s) -{ - DebugObject_Access(&s->d_obj); - - return &s->input; -} - -#endif diff --git a/v2rayng/badvpn/examples/TimerPacketSink.h b/v2rayng/badvpn/examples/TimerPacketSink.h deleted file mode 100644 index e1e82172c0..0000000000 --- a/v2rayng/badvpn/examples/TimerPacketSink.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file TimerPacketSink.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIMERPACKETSINK_H -#define _TIMERPACKETSINK_H - -#include - -#include -#include -#include - -typedef struct { - BReactor *reactor; - PacketPassInterface input; - BTimer timer; -} TimerPacketSink; - -static void _TimerPacketSink_input_handler_send (TimerPacketSink *s, uint8_t *data, int data_len) -{ - printf("sink: send '"); - size_t res = fwrite(data, data_len, 1, stdout); - B_USE(res) - printf("'\n"); - - BReactor_SetTimer(s->reactor, &s->timer); -} - -static void _TimerPacketSink_input_handler_requestcancel (TimerPacketSink *s) -{ - printf("sink: cancelled\n"); - - BReactor_RemoveTimer(s->reactor, &s->timer); - PacketPassInterface_Done(&s->input); -} - -static void _TimerPacketSink_timer_handler (TimerPacketSink *s) -{ - printf("sink: done\n"); - - PacketPassInterface_Done(&s->input); -} - -static void TimerPacketSink_Init (TimerPacketSink *s, BReactor *reactor, int mtu, int ms) -{ - // init arguments - s->reactor = reactor; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)_TimerPacketSink_input_handler_send, s, BReactor_PendingGroup(s->reactor)); - PacketPassInterface_EnableCancel(&s->input, (PacketPassInterface_handler_requestcancel)_TimerPacketSink_input_handler_requestcancel); - - // init timer - BTimer_Init(&s->timer, ms, (BTimer_handler)_TimerPacketSink_timer_handler, s); -} - -static void TimerPacketSink_Free (TimerPacketSink *s) -{ - // free timer - BReactor_RemoveTimer(s->reactor, &s->timer); - - // free input - PacketPassInterface_Free(&s->input); -} - -static PacketPassInterface * TimerPacketSink_GetInput (TimerPacketSink *s) -{ - return &s->input; -} - -#endif diff --git a/v2rayng/badvpn/examples/arpprobe_test.c b/v2rayng/badvpn/examples/arpprobe_test.c deleted file mode 100644 index d075f523f5..0000000000 --- a/v2rayng/badvpn/examples/arpprobe_test.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file arpprobe_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -BArpProbe arpprobe; - -static void signal_handler (void *user); -static void arpprobe_handler (void *unused, int event); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 3) { - printf("Usage: %s \n", argv[0]); - goto fail0; - } - - char *ifname = argv[1]; - uint32_t addr = inet_addr(argv[2]); - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - if (!BArpProbe_Init(&arpprobe, ifname, addr, &reactor, NULL, arpprobe_handler)) { - DEBUG("BArpProbe_Init failed"); - goto fail3; - } - - BReactor_Exec(&reactor); - - BArpProbe_Free(&arpprobe); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 0); -} - -void arpprobe_handler (void *unused, int event) -{ - switch (event) { - case BARPPROBE_EVENT_EXIST: { - printf("ARPPROBE: exist\n"); - } break; - - case BARPPROBE_EVENT_NOEXIST: { - printf("ARPPROBE: noexist\n"); - } break; - - case BARPPROBE_EVENT_ERROR: { - printf("ARPPROBE: error\n"); - - // exit reactor - BReactor_Quit(&reactor, 0); - } break; - - default: - ASSERT(0); - } -} diff --git a/v2rayng/badvpn/examples/bavl_test.c b/v2rayng/badvpn/examples/bavl_test.c deleted file mode 100644 index c30ae6f31c..0000000000 --- a/v2rayng/badvpn/examples/bavl_test.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file bavl_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include - -struct mynode { - int used; - int num; - BAVLNode avl_node; -}; - -static int int_comparator (void *user, int *val1, int *val2) -{ - return B_COMPARE(*val1, *val2); -} - -static void verify (BAVL *tree) -{ - printf("Verifying...\n"); - BAVL_Verify(tree); -} - -int main (int argc, char **argv) -{ - int num_nodes; - int num_random_delete; - - if (argc != 3 || (num_nodes = atoi(argv[1])) <= 0 || (num_random_delete = atoi(argv[2])) < 0) { - fprintf(stderr, "Usage: %s \n", (argc > 0 ? argv[0] : NULL)); - return 1; - } - - struct mynode *nodes = (struct mynode *)BAllocArray(num_nodes, sizeof(*nodes)); - ASSERT_FORCE(nodes) - - int *values_ins = (int *)BAllocArray(num_nodes, sizeof(int)); - ASSERT_FORCE(values_ins) - - int *values = (int *)BAllocArray(num_random_delete, sizeof(int)); - ASSERT_FORCE(values) - - BAVL avl; - BAVL_Init(&avl, OFFSET_DIFF(struct mynode, num, avl_node), (BAVL_comparator)int_comparator, NULL); - verify(&avl); - - printf("Inserting random values...\n"); - int inserted = 0; - BRandom_randomize((uint8_t *)values_ins, num_nodes * sizeof(int)); - for (int i = 0; i < num_nodes; i++) { - nodes[i].num = values_ins[i]; - if (BAVL_Insert(&avl, &nodes[i].avl_node, NULL)) { - nodes[i].used = 1; - inserted++; - } else { - nodes[i].used = 0; - printf("Insert collision!\n"); - } - } - printf("Inserted %d entries\n", inserted); - verify(&avl); - - printf("Removing random entries...\n"); - int removed1 = 0; - BRandom_randomize((uint8_t *)values, num_random_delete * sizeof(int)); - for (int i = 0; i < num_random_delete; i++) { - int index = (((unsigned int *)values)[i] % num_nodes); - struct mynode *node = nodes + index; - if (node->used) { - BAVL_Remove(&avl, &node->avl_node); - node->used = 0; - removed1++; - } - } - printf("Removed %d entries\n", removed1); - verify(&avl); - - printf("Removing remaining...\n"); - int removed2 = 0; - while (!BAVL_IsEmpty(&avl)) { - struct mynode *node = UPPER_OBJECT(BAVL_GetFirst(&avl), struct mynode, avl_node); - ASSERT_FORCE(node->used) - BAVL_Remove(&avl, &node->avl_node); - node->used = 0; - removed2++; - } - printf("Removed %d entries\n", removed2); - ASSERT_FORCE(BAVL_IsEmpty(&avl)) - ASSERT_FORCE(removed1 + removed2 == inserted) - verify(&avl); - - BFree(nodes); - BFree(values_ins); - BFree(values); - - return 0; -} diff --git a/v2rayng/badvpn/examples/bencryption_bench.c b/v2rayng/badvpn/examples/bencryption_bench.c deleted file mode 100644 index c842bf2d77..0000000000 --- a/v2rayng/badvpn/examples/bencryption_bench.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file bencryption_bench.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static void usage (char *name) -{ - printf( - "Usage: %s \n" - " is one of (blowfish, aes).\n", - name - ); - - exit(1); -} - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 5) { - usage(argv[0]); - } - - char *mode_str = argv[1]; - char *cipher_str = argv[2]; - - int mode; - int cipher = 0; // silence warning - int num_blocks = atoi(argv[3]); - int num_ops = atoi(argv[4]); - - if (!strcmp(mode_str, "enc")) { - mode = BENCRYPTION_MODE_ENCRYPT; - } - else if (!strcmp(mode_str, "dec")) { - mode = BENCRYPTION_MODE_DECRYPT; - } - else { - usage(argv[0]); - } - - if (!strcmp(cipher_str, "blowfish")) { - cipher = BENCRYPTION_CIPHER_BLOWFISH; - } - else if (!strcmp(cipher_str, "aes")) { - cipher = BENCRYPTION_CIPHER_AES; - } - else { - usage(argv[0]); - } - - if (num_blocks < 0 || num_ops < 0) { - usage(argv[0]); - } - - int key_size = BEncryption_cipher_key_size(cipher); - int block_size = BEncryption_cipher_block_size(cipher); - - uint8_t key[BENCRYPTION_MAX_KEY_SIZE]; - BRandom_randomize(key, key_size); - - uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE]; - BRandom_randomize(iv, block_size); - - if (num_blocks > INT_MAX / block_size) { - printf("too much"); - goto fail0; - } - int unit_size = num_blocks * block_size; - - printf("unit size %d\n", unit_size); - - uint8_t *buf1 = (uint8_t *)BAlloc(unit_size); - if (!buf1) { - printf("BAlloc failed"); - goto fail0; - } - - uint8_t *buf2 = (uint8_t *)BAlloc(unit_size); - if (!buf2) { - printf("BAlloc failed"); - goto fail1; - } - - BEncryption enc; - BEncryption_Init(&enc, mode, cipher, key); - - uint8_t *in = buf1; - uint8_t *out = buf2; - BRandom_randomize(in, unit_size); - - for (int i = 0; i < num_ops; i++) { - BEncryption_Encrypt(&enc, in, out, unit_size, iv); - - uint8_t *t = in; - in = out; - out = t; - } - - BEncryption_Free(&enc); - BFree(buf2); -fail1: - BFree(buf1); -fail0: - DebugObjectGlobal_Finish(); - - return 0; -} diff --git a/v2rayng/badvpn/examples/bprocess_example.c b/v2rayng/badvpn/examples/bprocess_example.c deleted file mode 100644 index 0ece996f78..0000000000 --- a/v2rayng/badvpn/examples/bprocess_example.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file bprocess_example.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -BUnixSignal unixsignal; -BProcessManager manager; -BProcess process; - -static void unixsignal_handler (void *user, int signo); -static void process_handler (void *user, int normally, uint8_t normally_exit_status); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - int ret = 1; - - if (argc < 2) { - printf("Usage: %s [argument ...]\n", argv[0]); - goto fail0; - } - - char *program = argv[1]; - - // init time - BTime_Init(); - - // init logger - BLog_InitStdout(); - - // init reactor (event loop) - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - // choose signals to catch - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - - // init BUnixSignal for catching signals - if (!BUnixSignal_Init(&unixsignal, &reactor, set, unixsignal_handler, NULL)) { - DEBUG("BUnixSignal_Init failed"); - goto fail2; - } - - // init process manager - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - char **p_argv = argv + 1; - - // map fds 0, 1, 2 in child to fds 0, 1, 2 in parent - int fds[] = { 0, 1, 2, -1 }; - int fds_map[] = { 0, 1, 2 }; - - // start child process - if (!BProcess_InitWithFds(&process, &manager, process_handler, NULL, program, p_argv, NULL, fds, fds_map)) { - DEBUG("BProcess_Init failed"); - goto fail4; - } - - // enter event loop - ret = BReactor_Exec(&reactor); - - BProcess_Free(&process); -fail4: - BProcessManager_Free(&manager); -fail3: - BUnixSignal_Free(&unixsignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void unixsignal_handler (void *user, int signo) -{ - DEBUG("received %s, terminating child", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // send SIGTERM to child - BProcess_Terminate(&process); -} - -void process_handler (void *user, int normally, uint8_t normally_exit_status) -{ - DEBUG("process terminated"); - - int ret = (normally ? normally_exit_status : 1); - - // return from event loop - BReactor_Quit(&reactor, ret); -} diff --git a/v2rayng/badvpn/examples/brandom2_test.c b/v2rayng/badvpn/examples/brandom2_test.c deleted file mode 100644 index 539735ca0f..0000000000 --- a/v2rayng/badvpn/examples/brandom2_test.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file brandom2_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -#define NUM_NUMBERS 10 - -static BRandom2 brandom; - -int main (int argc, char *argv[]) -{ - int ret = 1; - - if (!BRandom2_Init(&brandom, 0)) { - DEBUG("BRandom2_Init failed"); - goto fail0; - } - - uint32_t numbers[NUM_NUMBERS]; - if (!BRandom2_GenBytes(&brandom, numbers, sizeof(numbers))) { - DEBUG("BRandom2_GenBytes failed"); - goto fail1; - } - - for (int i = 0; i < NUM_NUMBERS; i++) { - printf("%"PRIu32"\n", numbers[i]); - } - - ret = 0; - -fail1: - BRandom2_Free(&brandom); -fail0: - return ret; -} diff --git a/v2rayng/badvpn/examples/btimer_example.c b/v2rayng/badvpn/examples/btimer_example.c deleted file mode 100644 index c4d8d54a56..0000000000 --- a/v2rayng/badvpn/examples/btimer_example.c +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file btimer_example.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -// gives average firing rate 100kHz -#define TIMER_NUM 500 -#define TIMER_MODULO 10 - -BReactor sys; - -void handle_timer (BTimer *bt) -{ - #ifdef BADVPN_USE_WINAPI - btime_t time = btime_gettime() + rand()%TIMER_MODULO; - #else - btime_t time = btime_gettime() + random()%TIMER_MODULO; - #endif - BReactor_SetTimerAbsolute(&sys, bt, time); -} - -int main () -{ - BLog_InitStdout(); - - #ifdef BADVPN_USE_WINAPI - srand(time(NULL)); - #else - srandom(time(NULL)); - #endif - - // init time - BTime_Init(); - - if (!BReactor_Init(&sys)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - BTimer timers[TIMER_NUM]; - - int i; - for (i=0; i - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define USE_COUNTS 0 -#define USE_ASSOC 1 - -typedef size_t entry_index; -#define MAX_INDICES SIZE_MAX - -typedef uint32_t entry_key; - -typedef uint8_t assoc_value; -typedef uint64_t assoc_sum; - -struct entry { - entry_index tree_child[2]; - entry_index tree_parent; - int8_t tree_balance; -#if USE_COUNTS - size_t tree_count; -#endif -#if USE_ASSOC - assoc_value assoc_value; - assoc_sum assoc_sum; -#endif - entry_key key; -}; - -typedef struct entry *entry_ptr; - -#include "cavl_test_tree.h" -#include - -#include "cavl_test_tree.h" -#include - -static void random_bytes (char *buf, size_t len) -{ - while (len > 0) { - *((unsigned char *)buf) = rand(); - buf++; - len--; - } -} - -static int uint64_less (void *user, uint64_t a, uint64_t b) -{ - return (a < b); -} - -#if USE_ASSOC -static MyTreeRef assoc_continue_last_lesser_equal (MyTree *tree, struct entry *arg, MyTreeRef ref, assoc_sum target_sum) -{ - assoc_sum cur_sum = MyTree_ExclusiveAssocPrefixSum(tree, arg, ref); - ASSERT(target_sum >= cur_sum) - while (cur_sum + ref.ptr->assoc_value <= target_sum) { - MyTreeRef next_ref = MyTree_GetNext(tree, arg, ref); - if (next_ref.link == -1) { - break; - } - cur_sum += ref.ptr->assoc_value; - ref = next_ref; - } - return ref; -} -#endif - -static void test_assoc (MyTree *tree, struct entry *arg) -{ -#if USE_ASSOC - assoc_sum sum = 0; - for (MyTreeRef ref = MyTree_GetFirst(tree, arg); ref.link != -1; ref = MyTree_GetNext(tree, arg, ref)) { - assoc_sum tree_sum = MyTree_ExclusiveAssocPrefixSum(tree, arg, ref); - ASSERT_FORCE(tree_sum == sum); - ASSERT_FORCE(MyTree_FindLastExclusiveAssocPrefixSumLesserEqual(tree, arg, sum, uint64_less, NULL).link == assoc_continue_last_lesser_equal(tree, arg, ref, sum).link); - ASSERT_FORCE(MyTree_FindLastExclusiveAssocPrefixSumLesserEqual(tree, arg, sum + 1, uint64_less, NULL).link == assoc_continue_last_lesser_equal(tree, arg, ref, sum + 1).link); - sum += ref.ptr->assoc_value; - } - ASSERT_FORCE(sum == MyTree_AssocSum(tree, arg)); -#endif -} - -int main (int argc, char *argv[]) -{ - //srand(time(NULL)); - - printf("sizeof(struct entry)=%" PRIsz "\n", sizeof(struct entry)); - - if (argc != 6) { - fprintf(stderr, "Usage: %s \n", (argc > 0 ? argv[0] : "")); - return 1; - } - - size_t num_keys = atoi(argv[1]); - size_t num_lookups = atoi(argv[2]); - size_t num_remove = atoi(argv[3]); - size_t do_remove = atoi(argv[4]); - size_t do_verify = atoi(argv[5]); - - printf("Allocating keys...\n"); - entry_key *keys = (entry_key *)BAllocArray(num_keys, sizeof(keys[0])); - ASSERT_FORCE(keys); - - printf("Generating random keys...\n"); - random_bytes((char *)keys, num_keys * sizeof(keys[0])); - - printf("Allocating lookup indices...\n"); - uint64_t *lookup_indices = (uint64_t *)BAllocArray(num_lookups, sizeof(lookup_indices[0])); - ASSERT_FORCE(lookup_indices); - - printf("Generating random lookup indices...\n"); - random_bytes((char *)lookup_indices, num_lookups * sizeof(lookup_indices[0])); - - printf("Allocating remove indices...\n"); - uint64_t *remove_indices = (uint64_t *)BAllocArray(num_remove, sizeof(remove_indices[0])); - ASSERT_FORCE(remove_indices); - - printf("Generating random remove indices...\n"); - random_bytes((char *)remove_indices, num_remove * sizeof(remove_indices[0])); - -#if USE_ASSOC - printf("Allocating assoc values...\n"); - assoc_value *assoc_values = (assoc_value *)BAllocArray(num_keys, sizeof(assoc_values[0])); - ASSERT_FORCE(assoc_values); - - printf("Generating random assoc values...\n"); - random_bytes((char *)assoc_values, num_keys * sizeof(assoc_values[0])); -#endif - - printf("Allocating entries...\n"); - ASSERT_FORCE(num_keys <= MAX_INDICES); - struct entry *entries = (struct entry *)BAllocArray(num_keys, sizeof(*entries)); - ASSERT_FORCE(entries); - entry_index num_used_entries = 0; - - MyTree tree; - MyTree_Init(&tree); - - struct entry *arg = entries; - - ASSERT_FORCE(MyTree_IsEmpty(&tree)); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == 0); -#endif - test_assoc(&tree, arg); - - size_t num; -#if USE_COUNTS - size_t prevNum; -#endif - - printf("Inserting random numbers...\n"); - num = 0; - for (size_t i = 0; i < num_keys; i++) { - entries[num_used_entries].key = keys[i]; -#if USE_ASSOC - entries[num_used_entries].assoc_value = assoc_values[i]; -#endif - MyTreeRef ref = {&entries[num_used_entries], num_used_entries}; - if (!MyTree_Insert(&tree, arg, ref, NULL)) { - //printf("Insert collision!\n"); - continue; - } - num_used_entries++; - num++; - } - printf("Inserted %" PRIsz ".\n", num); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == num); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - test_assoc(&tree, arg); - } - - printf("Looking up random inserted keys...\n"); - for (size_t i = 0; i < num_lookups; i++) { - entry_index idx = lookup_indices[i] % num_keys; - MyTreeRef entry = MyTree_LookupExact(&tree, arg, keys[idx]); - ASSERT_FORCE(!MyTreeIsNullRef(entry)); - } - -#if USE_COUNTS - prevNum = MyTree_Count(&tree, arg); -#endif - num = 0; - printf("Looking up and removing random inserted keys...\n"); - for (size_t i = 0; i < num_remove; i++) { - entry_index idx = remove_indices[i] % num_keys; - MyTreeRef entry = MyTree_LookupExact(&tree, arg, keys[idx]); - if (MyTreeIsNullRef(entry)) { - //printf("Remove collision!\n"); - continue; - } - ASSERT_FORCE(entry.ptr->key == keys[idx]); - MyTree_Remove(&tree, arg, entry); - num++; - } - printf("Removed %" PRIsz ".\n", num); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == prevNum - num); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - test_assoc(&tree, arg); - } - - if (do_remove) { -#if USE_COUNTS - prevNum = MyTree_Count(&tree, arg); -#endif - num = 0; - printf("Removing remaining...\n"); - - MyTreeRef cur = MyTree_GetFirst(&tree, arg); - while (!MyTreeIsNullRef(cur)) { - MyTreeRef prev = cur; - cur = MyTree_GetNext(&tree, arg, cur); - MyTree_Remove(&tree, arg, prev); - num++; - } - - printf("Removed %" PRIsz ".\n", num); - ASSERT_FORCE(MyTree_IsEmpty(&tree)); -#if USE_COUNTS - ASSERT_FORCE(MyTree_Count(&tree, arg) == 0); - ASSERT_FORCE(num == prevNum); -#endif - if (do_verify) { - printf("Verifying...\n"); - MyTree_Verify(&tree, arg); - } - } - - printf("Freeing...\n"); - BFree(keys); - BFree(lookup_indices); - BFree(remove_indices); -#if USE_ASSOC - BFree(assoc_values); -#endif - BFree(entries); - - return 0; -} diff --git a/v2rayng/badvpn/examples/cavl_test_tree.h b/v2rayng/badvpn/examples/cavl_test_tree.h deleted file mode 100644 index 463076f65e..0000000000 --- a/v2rayng/badvpn/examples/cavl_test_tree.h +++ /dev/null @@ -1,23 +0,0 @@ -#define CAVL_PARAM_NAME MyTree -#define CAVL_PARAM_FEATURE_COUNTS USE_COUNTS -#define CAVL_PARAM_FEATURE_KEYS_ARE_INDICES 0 -#define CAVL_PARAM_FEATURE_ASSOC USE_ASSOC -#define CAVL_PARAM_TYPE_ENTRY struct entry -#define CAVL_PARAM_TYPE_LINK entry_index -#define CAVL_PARAM_TYPE_KEY entry_key -#define CAVL_PARAM_TYPE_ARG entry_ptr -#define CAVL_PARAM_TYPE_COUNT size_t -#define CAVL_PARAM_TYPE_ASSOC assoc_sum -#define CAVL_PARAM_VALUE_COUNT_MAX SIZE_MAX -#define CAVL_PARAM_VALUE_NULL ((entry_index)-1) -#define CAVL_PARAM_VALUE_ASSOC_ZERO 0 -#define CAVL_PARAM_FUN_DEREF(arg, link) (&(arg)[(link)]) -#define CAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1).ptr->key, (entry2).ptr->key) -#define CAVL_PARAM_FUN_COMPARE_KEY_ENTRY(arg, key1, entry2) B_COMPARE((key1), (entry2).ptr->key) -#define CAVL_PARAM_FUN_ASSOC_VALUE(arg, entry) ((entry).ptr->assoc_value) -#define CAVL_PARAM_FUN_ASSOC_OPER(arg, value1, value2) ((value1) + (value2)) -#define CAVL_PARAM_MEMBER_CHILD tree_child -#define CAVL_PARAM_MEMBER_BALANCE tree_balance -#define CAVL_PARAM_MEMBER_PARENT tree_parent -#define CAVL_PARAM_MEMBER_COUNT tree_count -#define CAVL_PARAM_MEMBER_ASSOC assoc_sum diff --git a/v2rayng/badvpn/examples/dhcpclient_test.c b/v2rayng/badvpn/examples/dhcpclient_test.c deleted file mode 100644 index 9601c014b9..0000000000 --- a/v2rayng/badvpn/examples/dhcpclient_test.c +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @file dhcpclient_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -BRandom2 random2; -BDHCPClient dhcp; - -static void signal_handler (void *user); -static void dhcp_handler (void *unused, int event); - -int main (int argc, char **argv) -{ - if (argc <= 0) { - return 1; - } - - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - goto fail0; - } - - char *ifname = argv[1]; - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BRandom2_Init(&random2, 0)) { - DEBUG("BRandom2_Init failed"); - goto fail1a; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - struct BDHCPClient_opts opts = {}; - - if (!BDHCPClient_Init(&dhcp, ifname, opts, &reactor, &random2, dhcp_handler, NULL)) { - DEBUG("BDHCPClient_Init failed"); - goto fail3; - } - - BReactor_Exec(&reactor); - - BDHCPClient_Free(&dhcp); -fail3: - BSignal_Finish(); -fail2: - BRandom2_Free(&random2); -fail1a: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 0); -} - -void dhcp_handler (void *unused, int event) -{ - switch (event) { - case BDHCPCLIENT_EVENT_UP: { - printf("DHCP: up"); - - uint32_t ip; - uint8_t *ipb = (void *)&ip; - - BDHCPClient_GetClientIP(&dhcp, &ip); - printf(" IP=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - - BDHCPClient_GetClientMask(&dhcp, &ip); - printf(" Mask=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - - if (BDHCPClient_GetRouter(&dhcp, &ip)) { - printf(" Router=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - } - - uint32_t dns[BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS]; - int num = BDHCPClient_GetDNS(&dhcp, dns, BDHCPCLIENT_MAX_DOMAIN_NAME_SERVERS); - for (int i = 0; i < num; i++) { - ip=dns[i]; - printf(" DNS=%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, ipb[0], ipb[1], ipb[2], ipb[3]); - } - - printf("\n"); - } break; - - case BDHCPCLIENT_EVENT_DOWN: { - printf("DHCP: down\n"); - } break; - - case BDHCPCLIENT_EVENT_ERROR: { - printf("DHCP: error\n"); - - // exit reactor - BReactor_Quit(&reactor, 0); - } break; - - default: - ASSERT(0); - } -} diff --git a/v2rayng/badvpn/examples/emscripten_test.c b/v2rayng/badvpn/examples/emscripten_test.c deleted file mode 100644 index 52b0351438..0000000000 --- a/v2rayng/badvpn/examples/emscripten_test.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file emscripten_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include - -#include -#include -#include - -BReactor reactor; -BTimer timer; -BPending job; - -static void timer_handler (void *unused) -{ - printf("timer_handler %"PRIu64"\n", btime_gettime()); - - BPending_Set(&job); - BReactor_SetTimer(&reactor, &timer); -} - -static void job_handler (void *unused) -{ - printf("job_handler %"PRIu64"\n", btime_gettime()); -} - -int main () -{ - BTime_Init(); - - BReactor_EmscriptenInit(&reactor); - - BTimer_Init(&timer, 500, timer_handler, NULL); - BReactor_SetTimer(&reactor, &timer); - - BPending_Init(&job, BReactor_PendingGroup(&reactor), job_handler, NULL); - BPending_Set(&job); - - BReactor_EmscriptenSync(&reactor); - return 0; -} diff --git a/v2rayng/badvpn/examples/fairqueue_test.c b/v2rayng/badvpn/examples/fairqueue_test.c deleted file mode 100644 index 482e08608f..0000000000 --- a/v2rayng/badvpn/examples/fairqueue_test.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file fairqueue_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define OUTPUT_INTERVAL 0 -#define REMOVE_INTERVAL 1 -#define NUM_INPUTS 3 - -BReactor reactor; -TimerPacketSink sink; -PacketPassFairQueue fq; -PacketPassFairQueueFlow flows[NUM_INPUTS]; -FastPacketSource sources[NUM_INPUTS]; -char *data[] = {"0 data", "1 datadatadata", "2 datadatadatadatadata"}; -BTimer timer; -int current_cancel; - -static void init_input (int i) -{ - PacketPassFairQueueFlow_Init(&flows[i], &fq); - FastPacketSource_Init(&sources[i], PacketPassFairQueueFlow_GetInput(&flows[i]), (uint8_t *)data[i], strlen(data[i]), BReactor_PendingGroup(&reactor)); -} - -static void free_input (int i) -{ - FastPacketSource_Free(&sources[i]); - PacketPassFairQueueFlow_Free(&flows[i]); -} - -static void reset_input (void) -{ - PacketPassFairQueueFlow_AssertFree(&flows[current_cancel]); - - printf("removing %d\n", current_cancel); - - // remove flow - free_input(current_cancel); - - // init flow - init_input(current_cancel); - - // increment cancel - current_cancel = (current_cancel + 1) % NUM_INPUTS; - - // reset timer - BReactor_SetTimer(&reactor, &timer); -} - -static void flow_handler_busy (void *user) -{ - PacketPassFairQueueFlow_AssertFree(&flows[current_cancel]); - - reset_input(); -} - -static void timer_handler (void *user) -{ - // if flow is busy, request cancel and wait for it - if (PacketPassFairQueueFlow_IsBusy(&flows[current_cancel])) { - printf("cancelling %d\n", current_cancel); - PacketPassFairQueueFlow_RequestCancel(&flows[current_cancel]); - PacketPassFairQueueFlow_SetBusyHandler(&flows[current_cancel], flow_handler_busy, NULL); - return; - } - - reset_input(); -} - -int main () -{ - // initialize logging - BLog_InitStdout(); - - // init time - BTime_Init(); - - // initialize reactor - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - // initialize sink - TimerPacketSink_Init(&sink, &reactor, 500, OUTPUT_INTERVAL); - - // initialize queue - if (!PacketPassFairQueue_Init(&fq, TimerPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 1, 1)) { - DEBUG("PacketPassFairQueue_Init failed"); - return 1; - } - - // initialize inputs - for (int i = 0; i < NUM_INPUTS; i++) { - init_input(i); - } - - // init cancel timer - BTimer_Init(&timer, REMOVE_INTERVAL, timer_handler, NULL); - BReactor_SetTimer(&reactor, &timer); - - // init cancel counter - current_cancel = 0; - - // run reactor - int ret = BReactor_Exec(&reactor); - BReactor_Free(&reactor); - return ret; -} diff --git a/v2rayng/badvpn/examples/fairqueue_test2.c b/v2rayng/badvpn/examples/fairqueue_test2.c deleted file mode 100644 index 0fe9d3422f..0000000000 --- a/v2rayng/badvpn/examples/fairqueue_test2.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file fairqueue_test2.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define SINK_TIMER 0 - -int main () -{ - // initialize logging - BLog_InitStdout(); - - // init time - BTime_Init(); - - // initialize reactor - BReactor reactor; - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - return 1; - } - - // initialize sink - RandomPacketSink sink; - RandomPacketSink_Init(&sink, &reactor, 500, SINK_TIMER); - - // initialize queue - PacketPassFairQueue fq; - if (!PacketPassFairQueue_Init(&fq, RandomPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 0, 1)) { - DEBUG("PacketPassFairQueue_Init failed"); - return 1; - } - - // initialize source 1 - PacketPassFairQueueFlow flow1; - PacketPassFairQueueFlow_Init(&flow1, &fq); - FastPacketSource source1; - char data1[] = "data1"; - FastPacketSource_Init(&source1, PacketPassFairQueueFlow_GetInput(&flow1), (uint8_t *)data1, strlen(data1), BReactor_PendingGroup(&reactor)); - - // initialize source 2 - PacketPassFairQueueFlow flow2; - PacketPassFairQueueFlow_Init(&flow2, &fq); - FastPacketSource source2; - char data2[] = "data2data2"; - FastPacketSource_Init(&source2, PacketPassFairQueueFlow_GetInput(&flow2), (uint8_t *)data2, strlen(data2), BReactor_PendingGroup(&reactor)); - - // initialize source 3 - PacketPassFairQueueFlow flow3; - PacketPassFairQueueFlow_Init(&flow3, &fq); - FastPacketSource source3; - char data3[] = "data3data3data3data3data3data3data3data3data3"; - FastPacketSource_Init(&source3, PacketPassFairQueueFlow_GetInput(&flow3), (uint8_t *)data3, strlen(data3), BReactor_PendingGroup(&reactor)); - - // run reactor - int ret = BReactor_Exec(&reactor); - BReactor_Free(&reactor); - return ret; -} diff --git a/v2rayng/badvpn/examples/indexedlist_test.c b/v2rayng/badvpn/examples/indexedlist_test.c deleted file mode 100644 index d5282c066b..0000000000 --- a/v2rayng/badvpn/examples/indexedlist_test.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file indexedlist_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -IndexedList il; - -struct elem { - int value; - IndexedListNode node; -}; - -static void elem_insert (struct elem *e, int value, uint64_t index) -{ - e->value = value; - IndexedList_InsertAt(&il, &e->node, index); -} - -static void remove_at (uint64_t index) -{ - IndexedListNode *n = IndexedList_GetAt(&il, index); - struct elem *e = UPPER_OBJECT(n, struct elem, node); - IndexedList_Remove(&il, &e->node); -} - -static void print_list (void) -{ - for (uint64_t i = 0; i < IndexedList_Count(&il); i++) { - IndexedListNode *n = IndexedList_GetAt(&il, i); - struct elem *e = UPPER_OBJECT(n, struct elem, node); - printf("%d ", e->value); - } - printf("\n"); -} - -int main (int argc, char *argv[]) -{ - IndexedList_Init(&il); - - struct elem arr[100]; - - print_list(); - - elem_insert(&arr[0], 1, 0); - print_list(); - elem_insert(&arr[1], 2, 0); - print_list(); - elem_insert(&arr[2], 3, 0); - print_list(); - elem_insert(&arr[3], 4, 0); - print_list(); - elem_insert(&arr[4], 5, 0); - print_list(); - elem_insert(&arr[5], 6, 0); - print_list(); - - elem_insert(&arr[6], 7, 1); - print_list(); - - remove_at(0); - print_list(); - - remove_at(5); - print_list(); - - return 0; -} diff --git a/v2rayng/badvpn/examples/ipaddr6_test.c b/v2rayng/badvpn/examples/ipaddr6_test.c deleted file mode 100644 index b4304baad2..0000000000 --- a/v2rayng/badvpn/examples/ipaddr6_test.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file ipaddr6_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include - -#define PRINT_TEST(addr_bytes, string) \ - { \ - struct ipv6_addr addr = {addr_bytes}; \ - char str[IPADDR6_PRINT_MAX]; \ - ipaddr6_print_addr(addr, str); \ - ASSERT_FORCE(!strcmp(str, (string))); \ - struct ipv6_addr parsed_addr; \ - int res = ipaddr6_parse_ipv6_addr(MemRef_MakeCstr(str), &parsed_addr); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(!memcmp(parsed_addr.bytes, addr.bytes, 16)); \ - } - -#define PARSE_TEST(string, addr_bytes) \ - { \ - struct ipv6_addr exp_addr = {addr_bytes}; \ - struct ipv6_addr addr; \ - int res = ipaddr6_parse_ipv6_addr(MemRef_MakeCstr((string)), &addr); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(!memcmp(addr.bytes, exp_addr.bytes, 16)); \ - } - -#define PARSE_FAIL_TEST(string) \ - { \ - struct ipv6_addr addr; \ - int res = ipaddr6_parse_ipv6_addr(MemRef_MakeCstr((string)), &addr); \ - ASSERT_FORCE(!res); \ - } - -#define MASK_TEST(mask_bytes, prefix) \ - { \ - struct ipv6_addr mask = {mask_bytes}; \ - int parsed_prefix; \ - int res = ipaddr6_ipv6_prefix_from_mask(mask, &parsed_prefix); \ - ASSERT_FORCE(res); \ - ASSERT_FORCE(parsed_prefix == (prefix)); \ - struct ipv6_addr generated_mask; \ - ipaddr6_ipv6_mask_from_prefix(parsed_prefix, &generated_mask); \ - ASSERT_FORCE(!memcmp(generated_mask.bytes, mask.bytes, 16)); \ - } - -#define PASS(...) __VA_ARGS__ - -int main () -{ - PRINT_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), "::1") - PRINT_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), "::") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),"2001:db8::1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01}), "2001:db8::2:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}), "2001:db8:0:1:1:1:1:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}), "2001:db8:0:1:1:1:1:1") - PRINT_TEST(PASS({0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), "2001:db8::1:0:0:1") - - PARSE_TEST("::", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("::1", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) - PARSE_TEST("::abcd", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd})) - PARSE_TEST("::0123:abcd", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0xab, 0xcd})) - PARSE_TEST("abcd::", PASS({0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("abcd:0123::", PASS({0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) - PARSE_TEST("1::2", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02})) - PARSE_TEST("abcd:0123::3210:dcba", PASS({0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("4567:abcd:0123::3210:dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("4567:abcd:0123:1111:2222:3333:3210::", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0x00, 0x00})) - PARSE_TEST("::4567:abcd:0123:1111:2222:3333:3210", PASS({0x00, 0x00, 0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10})) - PARSE_TEST("4567:abcd:0123:1111:2222:3333:3210:dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("04567:000abcd:00000123:01111:2222:03333:0003210:0dcba", PASS({0x45, 0x67, 0xab, 0xcd, 0x01, 0x23, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x32, 0x10, 0xdc, 0xba})) - PARSE_TEST("::1.2.3.4", PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ff::1.2.3.4", PASS({0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ff::0.2.3.4", PASS({0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04})) - PARSE_TEST("1:2:3:4:5:6:1.2.3.4", PASS({0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255", PASS({0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})) - PARSE_TEST("1::fffa:1.2.3.4", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfa, 0x01, 0x02, 0x03, 0x04})) - PARSE_TEST("1::fffa:0.0.0.0", PASS({0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00})) - - PARSE_FAIL_TEST("") - PARSE_FAIL_TEST(":") - PARSE_FAIL_TEST("a") - PARSE_FAIL_TEST("a:b") - PARSE_FAIL_TEST(":b") - PARSE_FAIL_TEST("b:") - PARSE_FAIL_TEST("1:2:3:4:5:6:7") - PARSE_FAIL_TEST(":1:2:3:4:5:6:7") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:") - PARSE_FAIL_TEST(":::") - PARSE_FAIL_TEST("::a::") - PARSE_FAIL_TEST("::a::b") - PARSE_FAIL_TEST("c::a::b") - PARSE_FAIL_TEST("c::a::") - PARSE_FAIL_TEST("10000::") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:8:9") - PARSE_FAIL_TEST("1:2:3:4::5:6:7:8:9") - PARSE_FAIL_TEST("::1:2:3:4:5:6:7:8:9") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:8:9::") - PARSE_FAIL_TEST("a::b:") - PARSE_FAIL_TEST(":a::b") - PARSE_FAIL_TEST("::g") - PARSE_FAIL_TEST("::1.2") - PARSE_FAIL_TEST("::1.2.3.4.5") - PARSE_FAIL_TEST("::01.2.3.4") - PARSE_FAIL_TEST("::1.2.3.04") - PARSE_FAIL_TEST("::1.2.3.256") - PARSE_FAIL_TEST("1.2.3.4") - PARSE_FAIL_TEST("::8259.2.473.256") - PARSE_FAIL_TEST("1:2:3:4:5:6:7:1.2.3.4") - PARSE_FAIL_TEST("1:2:3:4:5:1.2.3.4") - PARSE_FAIL_TEST("::1.2.3.4::") - PARSE_FAIL_TEST("::1.2.3.4:1") - PARSE_FAIL_TEST("localhost6") - - MASK_TEST(PASS({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 0) - MASK_TEST(PASS({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 1) - MASK_TEST(PASS({0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 2) - MASK_TEST(PASS({0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 3) - MASK_TEST(PASS({0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 4) - MASK_TEST(PASS({0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 5) - MASK_TEST(PASS({0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 6) - MASK_TEST(PASS({0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 7) - MASK_TEST(PASS({0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 8) - - MASK_TEST(PASS({0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 9) - MASK_TEST(PASS({0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 10) - MASK_TEST(PASS({0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 11) - MASK_TEST(PASS({0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 12) - MASK_TEST(PASS({0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 13) - MASK_TEST(PASS({0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 14) - MASK_TEST(PASS({0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 15) - MASK_TEST(PASS({0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), 16) - - MASK_TEST(PASS({0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}), 127) - MASK_TEST(PASS({0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}), 128) - - return 0; -} diff --git a/v2rayng/badvpn/examples/ncd_parser_test.c b/v2rayng/badvpn/examples/ncd_parser_test.c deleted file mode 100644 index 1742c54b5c..0000000000 --- a/v2rayng/badvpn/examples/ncd_parser_test.c +++ /dev/null @@ -1,328 +0,0 @@ -/** - * @file ncd_parser_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static int generate_val (NCDValue *value, ExpString *out_str) -{ - switch (NCDValue_Type(value)) { - case NCDVALUE_STRING: { - const char *str = NCDValue_StringValue(value); - size_t len = NCDValue_StringLength(value); - - if (!ExpString_AppendChar(out_str, '"')) { - goto fail; - } - - for (size_t i = 0; i < len; i++) { - if (str[i] == '\0') { - char buf[5]; - snprintf(buf, sizeof(buf), "\\x%02"PRIx8, (uint8_t)str[i]); - - if (!ExpString_Append(out_str, buf)) { - goto fail; - } - - continue; - } - - if (str[i] == '"' || str[i] == '\\') { - if (!ExpString_AppendChar(out_str, '\\')) { - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, str[i])) { - goto fail; - } - } - - if (!ExpString_AppendChar(out_str, '"')) { - goto fail; - } - } break; - - case NCDVALUE_LIST: { - if (!ExpString_AppendChar(out_str, '{')) { - goto fail; - } - - int is_first = 1; - - for (NCDValue *e = NCDValue_ListFirst(value); e; e = NCDValue_ListNext(value, e)) { - if (!is_first) { - if (!ExpString_Append(out_str, ", ")) { - goto fail; - } - } - - if (!generate_val(e, out_str)) { - goto fail; - } - - is_first = 0; - } - - if (!ExpString_AppendChar(out_str, '}')) { - goto fail; - } - } break; - - case NCDVALUE_MAP: { - if (!ExpString_AppendChar(out_str, '[')) { - goto fail; - } - - int is_first = 1; - - for (NCDValue *ekey = NCDValue_MapFirstKey(value); ekey; ekey = NCDValue_MapNextKey(value, ekey)) { - NCDValue *eval = NCDValue_MapKeyValue(value, ekey); - - if (!is_first) { - if (!ExpString_Append(out_str, ", ")) { - goto fail; - } - } - - if (!generate_val(ekey, out_str)) { - goto fail; - } - - if (!ExpString_AppendChar(out_str, ':')) { - goto fail; - } - - if (!generate_val(eval, out_str)) { - goto fail; - } - - is_first = 0; - } - - if (!ExpString_AppendChar(out_str, ']')) { - goto fail; - } - } break; - - case NCDVALUE_VAR: { - if (!ExpString_Append(out_str, NCDValue_VarName(value))) { - goto fail; - } - } break; - - case NCDVALUE_INVOC: { - if (!generate_val(NCDValue_InvocFunc(value), out_str)) { - goto fail; - } - - if (!ExpString_AppendChar(out_str, '(')) { - goto fail; - } - - if (!generate_val(NCDValue_InvocArg(value), out_str)) { - goto fail; - } - - if (!ExpString_AppendChar(out_str, ')')) { - goto fail; - } - } break; - - default: ASSERT(0); - } - - return 1; - -fail: - return 0; -} - -static void print_indent (unsigned int indent) -{ - while (indent > 0) { - printf(" "); - indent--; - } -} - -static void print_value (NCDValue *v, unsigned int indent) -{ - ExpString estr; - if (!ExpString_Init(&estr)) { - DEBUG("ExpString_Init failed"); - exit(1); - } - - if (!generate_val(v, &estr)) { - DEBUG("generate_val failed"); - exit(1); - } - - print_indent(indent); - printf("%s\n", ExpString_Get(&estr)); - - ExpString_Free(&estr); -} - -static void print_block (NCDBlock *block, unsigned int indent) -{ - for (NCDStatement *st = NCDBlock_FirstStatement(block); st; st = NCDBlock_NextStatement(block, st)) { - const char *name = NCDStatement_Name(st) ? NCDStatement_Name(st) : ""; - - switch (NCDStatement_Type(st)) { - case NCDSTATEMENT_REG: { - const char *objname = NCDStatement_RegObjName(st) ? NCDStatement_RegObjName(st) : ""; - const char *cmdname = NCDStatement_RegCmdName(st); - - print_indent(indent); - printf("reg name=%s objname=%s cmdname=%s args:\n", name, objname, cmdname); - - print_value(NCDStatement_RegArgs(st), indent + 2); - } break; - - case NCDSTATEMENT_IF: { - print_indent(indent); - printf("if name=%s\n", name); - - NCDIfBlock *ifb = NCDStatement_IfBlock(st); - - for (NCDIf *ifc = NCDIfBlock_FirstIf(ifb); ifc; ifc = NCDIfBlock_NextIf(ifb, ifc)) { - print_indent(indent + 2); - printf("if\n"); - - print_value(NCDIf_Cond(ifc), indent + 4); - - print_indent(indent + 2); - printf("then\n"); - - print_block(NCDIf_Block(ifc), indent + 4); - } - - if (NCDStatement_IfElse(st)) { - print_indent(indent + 2); - printf("else\n"); - - print_block(NCDStatement_IfElse(st), indent + 4); - } - } break; - - case NCDSTATEMENT_FOREACH: { - const char *name1 = NCDStatement_ForeachName1(st); - const char *name2 = NCDStatement_ForeachName2(st) ? NCDStatement_ForeachName2(st) : ""; - - print_indent(indent); - printf("foreach name=%s name1=%s name2=%s\n", name, name1, name2); - - print_block(NCDStatement_ForeachBlock(st), indent + 2); - } break; - - case NCDSTATEMENT_BLOCK: { - print_indent(indent); - printf("block name=%s\n", name); - - print_block(NCDStatement_BlockBlock(st), indent + 2); - } break; - - default: { - print_indent(indent); - printf("unknown_statement_type name=%s\n", name); - } break; - } - } -} - -int main (int argc, char **argv) -{ - int res = 1; - - if (argc != 3) { - printf("Usage: %s \n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - int desugar = atoi(argv[1]); - char *text = argv[2]; - - BLog_InitStdout(); - - // parse - NCDProgram prog; - if (!NCDConfigParser_Parse(text, strlen(text), &prog)) { - DEBUG("NCDConfigParser_Parse failed"); - goto fail1; - } - - // desugar - if (desugar) { - if (!NCDSugar_Desugar(&prog)) { - DEBUG("NCDSugar_Desugar failed"); - goto fail2; - } - } - - // print - for (NCDProgramElem *elem = NCDProgram_FirstElem(&prog); elem; elem = NCDProgram_NextElem(&prog, elem)) { - switch (NCDProgramElem_Type(elem)) { - case NCDPROGRAMELEM_PROCESS: { - NCDProcess *p = NCDProgramElem_Process(elem); - printf("process name=%s is_template=%d\n", NCDProcess_Name(p), NCDProcess_IsTemplate(p)); - print_block(NCDProcess_Block(p), 2); - } break; - - case NCDPROGRAMELEM_INCLUDE: { - printf("include path=%s\n", NCDProgramElem_IncludePathData(elem)); - } break; - - case NCDPROGRAMELEM_INCLUDE_GUARD: { - printf("include_guard id=%s\n", NCDProgramElem_IncludeGuardIdData(elem)); - } break; - - default: ASSERT(0); - } - } - - res = 0; -fail2: - NCDProgram_Free(&prog); -fail1: - BLog_Free(); -fail0: - return res; -} diff --git a/v2rayng/badvpn/examples/ncd_tokenizer_test.c b/v2rayng/badvpn/examples/ncd_tokenizer_test.c deleted file mode 100644 index 9a1219763a..0000000000 --- a/v2rayng/badvpn/examples/ncd_tokenizer_test.c +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file ncd_tokenizer_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include - -int error; - -static int tokenizer_output (void *user, int token, char *value, size_t value_len, size_t line, size_t line_char) -{ - if (token == NCD_ERROR) { - printf("line %zu, character %zu: tokenizer error\n", line, line_char); - error = 1; - return 0; - } - - switch (token) { - case NCD_EOF: - printf("eof\n"); - break; - case NCD_TOKEN_CURLY_OPEN: - printf("curly_open\n"); - break; - case NCD_TOKEN_CURLY_CLOSE: - printf("curly_close\n"); - break; - case NCD_TOKEN_ROUND_OPEN: - printf("round_open\n"); - break; - case NCD_TOKEN_ROUND_CLOSE: - printf("round_close\n"); - break; - case NCD_TOKEN_SEMICOLON: - printf("semicolon\n"); - break; - case NCD_TOKEN_DOT: - printf("dot\n"); - break; - case NCD_TOKEN_COMMA: - printf("comma\n"); - break; - case NCD_TOKEN_PROCESS: - printf("process\n"); - break; - case NCD_TOKEN_NAME: - printf("name %s\n", value); - free(value); - break; - case NCD_TOKEN_STRING: - printf("string %s\n", value); - free(value); - break; - case NCD_TOKEN_ARROW: - printf("arrow\n"); - break; - case NCD_TOKEN_TEMPLATE: - printf("template\n"); - break; - case NCD_TOKEN_COLON: - printf("colon\n"); - break; - case NCD_TOKEN_BRACKET_OPEN: - printf("bracket open\n"); - break; - case NCD_TOKEN_BRACKET_CLOSE: - printf("bracket close\n"); - break; - case NCD_TOKEN_IF: - printf("if\n"); - break; - case NCD_TOKEN_ELIF: - printf("elif\n"); - break; - case NCD_TOKEN_ELSE: - printf("else\n"); - break; - case NCD_TOKEN_FOREACH: - printf("foreach\n"); - break; - case NCD_TOKEN_AS: - printf("as\n"); - break; - case NCD_TOKEN_INCLUDE: - printf("include\n"); - break; - case NCD_TOKEN_INCLUDE_GUARD: - printf("include_guard\n"); - break; - case NCD_TOKEN_AT: - printf("at\n"); - break; - case NCD_TOKEN_BLOCK: - printf("block\n"); - break; - case NCD_TOKEN_CARET: - printf("caret\n"); - break; - case NCD_TOKEN_DO: - printf("do\n"); - break; - case NCD_TOKEN_INTERRUPT: - printf("interrupt\n"); - break; - default: - printf("UNKNOWN_TOKEN\n"); - break; - } - - return 1; -} - -int main (int argc, char **argv) -{ - if (argc < 1) { - return 1; - } - - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - return 1; - } - - BLog_InitStdout(); - - error = 0; - - NCDConfigTokenizer_Tokenize(MemRef_MakeCstr(argv[1]), tokenizer_output, NULL); - - if (error) { - return 1; - } - - return 0; -} diff --git a/v2rayng/badvpn/examples/ncd_value_parser_test.c b/v2rayng/badvpn/examples/ncd_value_parser_test.c deleted file mode 100644 index 5eca59c44e..0000000000 --- a/v2rayng/badvpn/examples/ncd_value_parser_test.c +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file ncd_value_parser_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include -#include - -int main (int argc, char *argv[]) -{ - int res = 1; - - if (argc != 2) { - printf("Usage: %s \n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - BLog_InitStdout(); - - NCDStringIndex string_index; - if (!NCDStringIndex_Init(&string_index)) { - DEBUG("NCDStringIndex_Init failed"); - goto fail01; - } - - NCDValMem mem; - NCDValMem_Init(&mem, &string_index); - - // parse - NCDValRef val; - if (!NCDValParser_Parse(MemRef_MakeCstr(argv[1]), &mem, &val)) { - DEBUG("NCDValParser_Parse failed"); - goto fail1; - } - - // generate value string - char *str = NCDValGenerator_Generate(val); - if (!str) { - DEBUG("NCDValGenerator_Generate failed"); - goto fail1; - } - - // print value string - printf("%s\n", str); - - res = 0; - - free(str); -fail1: - NCDValMem_Free(&mem); - NCDStringIndex_Free(&string_index); -fail01: - BLog_Free(); -fail0: - return res; -} diff --git a/v2rayng/badvpn/examples/ncdinterfacemonitor_test.c b/v2rayng/badvpn/examples/ncdinterfacemonitor_test.c deleted file mode 100644 index 167f1bd32f..0000000000 --- a/v2rayng/badvpn/examples/ncdinterfacemonitor_test.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file ncdinterfacemonitor_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -NCDInterfaceMonitor monitor; - -static void signal_handler (void *user); -static void monitor_handler (void *unused, struct NCDInterfaceMonitor_event event); -static void monitor_handler_error (void *unused); - -int main (int argc, char **argv) -{ - int ret = 1; - - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", (argc > 0 ? argv[0] : "")); - goto fail0; - } - - int ifindex; - if (!badvpn_get_iface_info(argv[1], NULL, NULL, &ifindex)) { - DEBUG("get_iface_info failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail1; - } - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - int watch_flags = NCDIFMONITOR_WATCH_LINK|NCDIFMONITOR_WATCH_IPV4_ADDR|NCDIFMONITOR_WATCH_IPV6_ADDR; - - if (!NCDInterfaceMonitor_Init(&monitor, ifindex, watch_flags, &reactor, NULL, monitor_handler, monitor_handler_error)) { - DEBUG("NCDInterfaceMonitor_Init failed"); - goto fail3; - } - - ret = BReactor_Exec(&reactor); - - NCDInterfaceMonitor_Free(&monitor); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 1); -} - -void monitor_handler (void *unused, struct NCDInterfaceMonitor_event event) -{ - switch (event.event) { - case NCDIFMONITOR_EVENT_LINK_UP: - case NCDIFMONITOR_EVENT_LINK_DOWN: { - const char *type = (event.event == NCDIFMONITOR_EVENT_LINK_UP) ? "up" : "down"; - printf("link %s\n", type); - } break; - - case NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED: - case NCDIFMONITOR_EVENT_IPV4_ADDR_REMOVED: { - const char *type = (event.event == NCDIFMONITOR_EVENT_IPV4_ADDR_ADDED) ? "added" : "removed"; - uint8_t *addr = (uint8_t *)&event.u.ipv4_addr.addr; - printf("ipv4 addr %s %d.%d.%d.%d/%d\n", type, (int)addr[0], (int)addr[1], (int)addr[2], (int)addr[3], event.u.ipv4_addr.addr.prefix); - } break; - - case NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED: - case NCDIFMONITOR_EVENT_IPV6_ADDR_REMOVED: { - const char *type = (event.event == NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED) ? "added" : "removed"; - - char str[IPADDR6_PRINT_MAX]; - ipaddr6_print_addr(event.u.ipv6_addr.addr.addr, str); - - int dynamic = !!(event.u.ipv6_addr.addr_flags & NCDIFMONITOR_ADDR_FLAG_DYNAMIC); - - printf("ipv6 addr %s %s/%d scope=%"PRIu8" dynamic=%d\n", type, str, event.u.ipv6_addr.addr.prefix, event.u.ipv6_addr.scope, dynamic); - } break; - - default: ASSERT(0); - } -} - -void monitor_handler_error (void *unused) -{ - DEBUG("monitor error"); - - BReactor_Quit(&reactor, 1); -} diff --git a/v2rayng/badvpn/examples/ncdudevmanager_test.c b/v2rayng/badvpn/examples/ncdudevmanager_test.c deleted file mode 100644 index 9bbb3fe3da..0000000000 --- a/v2rayng/badvpn/examples/ncdudevmanager_test.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file ncdudevmanager_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -BUnixSignal usignal; -BProcessManager manager; -NCDUdevManager umanager; -NCDUdevClient client; - -static void signal_handler (void *user, int signo); -static void client_handler (void *unused, char *devpath, int have_map, BStringMap map); - -int main (int argc, char **argv) -{ - if (!(argc == 1 || (argc == 2 && !strcmp(argv[1], "--no-udev")))) { - fprintf(stderr, "Usage: %s [--no-udev]\n", (argc > 0 ? argv[0] : NULL)); - goto fail0; - } - - int no_udev = (argc == 2); - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - if (!BUnixSignal_Init(&usignal, &reactor, set, signal_handler, NULL)) { - fprintf(stderr, "BUnixSignal_Init failed\n"); - goto fail2; - } - - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - NCDUdevManager_Init(&umanager, no_udev, &reactor, &manager); - - NCDUdevClient_Init(&client, &umanager, NULL, client_handler); - - BReactor_Exec(&reactor); - - NCDUdevClient_Free(&client); - - NCDUdevManager_Free(&umanager); - - BProcessManager_Free(&manager); -fail3: - BUnixSignal_Free(&usignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -static void signal_handler (void *user, int signo) -{ - if (signo == SIGHUP) { - fprintf(stderr, "received SIGHUP, restarting client\n"); - - NCDUdevClient_Free(&client); - NCDUdevClient_Init(&client, &umanager, NULL, client_handler); - } else { - fprintf(stderr, "received %s, exiting\n", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // exit event loop - BReactor_Quit(&reactor, 1); - } -} - -void client_handler (void *unused, char *devpath, int have_map, BStringMap map) -{ - printf("event %s\n", devpath); - - if (!have_map) { - printf(" no map\n"); - } else { - printf(" map:\n"); - - const char *name = BStringMap_First(&map); - while (name) { - printf(" %s=%s\n", name, BStringMap_Get(&map, name)); - name = BStringMap_Next(&map, name); - } - } - - const BStringMap *cache_map = NCDUdevManager_Query(&umanager, devpath); - if (!cache_map) { - printf(" no cache\n"); - } else { - printf(" cache:\n"); - - const char *name = BStringMap_First(cache_map); - while (name) { - printf(" %s=%s\n", name, BStringMap_Get(cache_map, name)); - name = BStringMap_Next(cache_map, name); - } - } - - if (have_map) { - BStringMap_Free(&map); - } - free(devpath); -} diff --git a/v2rayng/badvpn/examples/ncdudevmonitor_test.c b/v2rayng/badvpn/examples/ncdudevmonitor_test.c deleted file mode 100644 index 94b4f6f411..0000000000 --- a/v2rayng/badvpn/examples/ncdudevmonitor_test.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file ncdudevmonitor_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -BReactor reactor; -BProcessManager manager; -NCDUdevMonitor monitor; - -static void signal_handler (void *user); -static void monitor_handler_event (void *unused); -static void monitor_handler_error (void *unused, int is_error); - -int main (int argc, char **argv) -{ - int ret = 1; - - if (argc < 2 || (strcmp(argv[1], "monitor_udev") && strcmp(argv[1], "monitor_kernel") && strcmp(argv[1], "info"))) { - fprintf(stderr, "Usage: %s \n", (argc > 0 ? argv[0] : NULL)); - goto fail0; - } - - int mode; - if (!strcmp(argv[1], "monitor_udev")) { - mode = NCDUDEVMONITOR_MODE_MONITOR_UDEV; - } else if (!strcmp(argv[1], "monitor_kernel")) { - mode = NCDUDEVMONITOR_MODE_MONITOR_KERNEL; - } else { - mode = NCDUDEVMONITOR_MODE_INFO; - } - - if (!BNetwork_GlobalInit()) { - DEBUG("BNetwork_GlobalInit failed"); - goto fail0; - } - - BTime_Init(); - - BLog_InitStdout(); - - if (!BReactor_Init(&reactor)) { - DEBUG("BReactor_Init failed"); - goto fail1; - } - - if (!BSignal_Init(&reactor, signal_handler, NULL)) { - DEBUG("BSignal_Init failed"); - goto fail2; - } - - if (!BProcessManager_Init(&manager, &reactor)) { - DEBUG("BProcessManager_Init failed"); - goto fail3; - } - - if (!NCDUdevMonitor_Init(&monitor, &reactor, &manager, mode, NULL, - monitor_handler_event, - monitor_handler_error - )) { - DEBUG("NCDUdevMonitor_Init failed"); - goto fail4; - } - - ret = BReactor_Exec(&reactor); - - NCDUdevMonitor_Free(&monitor); -fail4: - BProcessManager_Free(&manager); -fail3: - BSignal_Finish(); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return ret; -} - -void signal_handler (void *user) -{ - DEBUG("termination requested"); - - BReactor_Quit(&reactor, 1); -} - -void monitor_handler_event (void *unused) -{ - // accept event - NCDUdevMonitor_Done(&monitor); - - if (NCDUdevMonitor_IsReadyEvent(&monitor)) { - printf("ready\n"); - return; - } - - printf("event\n"); - - int num_props = NCDUdevMonitor_GetNumProperties(&monitor); - for (int i = 0; i < num_props; i++) { - const char *name; - const char *value; - NCDUdevMonitor_GetProperty(&monitor, i, &name, &value); - printf(" %s=%s\n", name, value); - } -} - -void monitor_handler_error (void *unused, int is_error) -{ - if (is_error) { - DEBUG("monitor error"); - } else { - DEBUG("monitor finished"); - } - - BReactor_Quit(&reactor, (is_error ? 1 : 0)); -} diff --git a/v2rayng/badvpn/examples/ncdval_test.c b/v2rayng/badvpn/examples/ncdval_test.c deleted file mode 100644 index 94234de9cb..0000000000 --- a/v2rayng/badvpn/examples/ncdval_test.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file ncdval_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define FORCE(cmd) if (!(cmd)) { fprintf(stderr, "failed\n"); exit(1); } - -static void test_string (NCDValRef str, const char *data, size_t length) -{ - FORCE( !NCDVal_IsInvalid(str) ) - FORCE( NCDVal_IsString(str) ) - FORCE( NCDVal_StringLength(str) == length ) - FORCE( NCDVal_StringHasNulls(str) == !!memchr(data, '\0', length) ) - FORCE( NCDVal_IsStringNoNulls(str) == !memchr(data, '\0', length) ) - FORCE( NCDVal_StringRegionEquals(str, 0, length, data) ) - - MemRef mr = NCDVal_StringMemRef(str); - FORCE( mr.ptr == NCDVal_StringData(str) ) - FORCE( mr.len == NCDVal_StringLength(str) ) - FORCE( mr.len == length ) - FORCE( !memcmp(mr.ptr, data, length) ) -} - -static void print_indent (int indent) -{ - for (int i = 0; i < indent; i++) { - printf(" "); - } -} - -static void print_value (NCDValRef val, unsigned int indent) -{ - switch (NCDVal_Type(val)) { - case NCDVAL_STRING: { - NCDValNullTermString nts; - FORCE( NCDVal_StringNullTerminate(val, &nts) ) - - print_indent(indent); - printf("string(%zu) %s\n", NCDVal_StringLength(val), nts.data); - - NCDValNullTermString_Free(&nts); - } break; - - case NCDVAL_LIST: { - size_t count = NCDVal_ListCount(val); - - print_indent(indent); - printf("list(%zu)\n", NCDVal_ListCount(val)); - - for (size_t i = 0; i < count; i++) { - NCDValRef elem_val = NCDVal_ListGet(val, i); - print_value(elem_val, indent + 1); - } - } break; - - case NCDVAL_MAP: { - print_indent(indent); - printf("map(%zu)\n", NCDVal_MapCount(val)); - - for (NCDValMapElem e = NCDVal_MapOrderedFirst(val); !NCDVal_MapElemInvalid(e); e = NCDVal_MapOrderedNext(val, e)) { - NCDValRef ekey = NCDVal_MapElemKey(val, e); - NCDValRef eval = NCDVal_MapElemVal(val, e); - - print_indent(indent + 1); - printf("key=\n"); - print_value(ekey, indent + 2); - - print_indent(indent + 1); - printf("val=\n"); - print_value(eval, indent + 2); - } - } break; - } -} - -int main () -{ - int res; - - BLog_InitStdout(); - - NCDStringIndex string_index; - FORCE( NCDStringIndex_Init(&string_index) ) - - // Some basic usage of values. - - NCDValMem mem; - NCDValMem_Init(&mem, &string_index); - - NCDValRef s1 = NCDVal_NewString(&mem, "Hello World"); - test_string(s1, "Hello World", 11); - ASSERT( NCDVal_IsString(s1) ) - ASSERT( !NCDVal_IsIdString(s1) ) - ASSERT( NCDVal_Type(s1) == NCDVAL_STRING ) - - NCDValRef s2 = NCDVal_NewString(&mem, "This is reeeeeeeeeeeeeallllllllyyyyy fun!"); - FORCE( !NCDVal_IsInvalid(s2) ) - - NCDValRef l1 = NCDVal_NewList(&mem, 10); - FORCE( !NCDVal_IsInvalid(l1) ) - - FORCE( NCDVal_ListAppend(l1, s1) ) - FORCE( NCDVal_ListAppend(l1, s2) ) - - print_value(s1, 0); - print_value(s2, 0); - print_value(l1, 0); - - NCDValRef k1 = NCDVal_NewString(&mem, "K1"); - FORCE( !NCDVal_IsInvalid(k1) ) - NCDValRef v1 = NCDVal_NewString(&mem, "V1"); - FORCE( !NCDVal_IsInvalid(v1) ) - - NCDValRef k2 = NCDVal_NewString(&mem, "K2"); - FORCE( !NCDVal_IsInvalid(k2) ) - NCDValRef v2 = NCDVal_NewString(&mem, "V2"); - FORCE( !NCDVal_IsInvalid(v2) ) - - NCDValRef m1 = NCDVal_NewMap(&mem, 3); - FORCE( !NCDVal_IsInvalid(m1) ) - - FORCE( NCDVal_MapInsert(m1, k1, v1, &res) && res ) - FORCE( NCDVal_MapInsert(m1, k2, v2, &res) && res ) - - ASSERT( NCDVal_MapGetValue(m1, "K1").idx == v1.idx ) - ASSERT( NCDVal_MapGetValue(m1, "K2").idx == v2.idx ) - ASSERT( NCDVal_IsInvalid(NCDVal_MapGetValue(m1, "K3")) ) - - NCDValRef ids1 = NCDVal_NewIdString(&mem, NCD_STRING_ARG1); - test_string(ids1, "_arg1", 5); - ASSERT( !memcmp(NCDVal_StringData(ids1), "_arg1", 5) ) - ASSERT( NCDVal_StringLength(ids1) == 5 ) - ASSERT( !NCDVal_StringHasNulls(ids1) ) - ASSERT( NCDVal_StringEquals(ids1, "_arg1") ) - ASSERT( NCDVal_Type(ids1) == NCDVAL_STRING ) - ASSERT( NCDVal_IsIdString(ids1) ) - - NCDValRef ids2 = NCDVal_NewIdString(&mem, NCD_STRING_ARG2); - test_string(ids2, "_arg2", 5); - ASSERT( !memcmp(NCDVal_StringData(ids2), "_arg2", 5) ) - ASSERT( NCDVal_StringLength(ids2) == 5 ) - ASSERT( !NCDVal_StringHasNulls(ids2) ) - ASSERT( NCDVal_StringEquals(ids2, "_arg2") ) - ASSERT( NCDVal_Type(ids2) == NCDVAL_STRING ) - ASSERT( NCDVal_IsIdString(ids2) ) - - FORCE( NCDVal_MapInsert(m1, ids1, ids2, &res) && res ) - - ASSERT( NCDVal_MapGetValue(m1, "_arg1").idx == ids2.idx ) - - print_value(m1, 0); - - NCDValRef copy = NCDVal_NewCopy(&mem, m1); - FORCE( !NCDVal_IsInvalid(copy) ) - ASSERT( NCDVal_Compare(copy, m1) == 0 ) - - NCDValMem_Free(&mem); - - // Try to make copies of a string within the same memory object. - // This is an evil test because we cannot simply copy a string using e.g. - // NCDVal_NewStringBin() - it requires that the buffer passed - // be outside the memory object of the new string. - // We use NCDVal_NewCopy(), which takes care of this by creating - // an uninitialized string using NCDVal_NewStringUninitialized() and - // then copyng the data. - - NCDValMem_Init(&mem, &string_index); - - NCDValRef s[100]; - - s[0] = NCDVal_NewString(&mem, "Eeeeeeeeeeeevil."); - FORCE( !NCDVal_IsInvalid(s[0]) ) - - for (int i = 1; i < 100; i++) { - s[i] = NCDVal_NewCopy(&mem, s[i - 1]); - FORCE( !NCDVal_IsInvalid(s[i]) ) - ASSERT( NCDVal_StringEquals(s[i - 1], "Eeeeeeeeeeeevil.") ) - ASSERT( NCDVal_StringEquals(s[i], "Eeeeeeeeeeeevil.") ) - } - - for (int i = 0; i < 100; i++) { - ASSERT( NCDVal_StringEquals(s[i], "Eeeeeeeeeeeevil.") ) - } - - NCDValMem_Free(&mem); - - NCDStringIndex_Free(&string_index); - - return 0; -} diff --git a/v2rayng/badvpn/examples/ncdvalcons_test.c b/v2rayng/badvpn/examples/ncdvalcons_test.c deleted file mode 100644 index c09faf3659..0000000000 --- a/v2rayng/badvpn/examples/ncdvalcons_test.c +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file ncdvalcons_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include - -static NCDStringIndex string_index; -static NCDValMem mem; -static NCDValCons cons; - -static NCDValConsVal make_string (const char *data) -{ - NCDValConsVal val; - int error; - int res = NCDValCons_NewString(&cons, (const uint8_t *)data, strlen(data), &val, &error); - ASSERT_FORCE(res) - return val; -} - -static NCDValConsVal make_list (void) -{ - NCDValConsVal val; - NCDValCons_NewList(&cons, &val); - return val; -} - -static NCDValConsVal make_map (void) -{ - NCDValConsVal val; - NCDValCons_NewMap(&cons, &val); - return val; -} - -static NCDValConsVal list_prepend (NCDValConsVal list, NCDValConsVal elem) -{ - int error; - int res = NCDValCons_ListPrepend(&cons, &list, elem, &error); - ASSERT_FORCE(res) - return list; -} - -static NCDValConsVal map_insert (NCDValConsVal map, NCDValConsVal key, NCDValConsVal value) -{ - int error; - int res = NCDValCons_MapInsert(&cons, &map, key, value, &error); - ASSERT_FORCE(res) - return map; -} - -static NCDValRef complete (NCDValConsVal cval) -{ - int error; - NCDValRef val; - int res = NCDValCons_Complete(&cons, cval, &val, &error); - ASSERT_FORCE(res) - return val; -} - -int main () -{ - int res; - - res = NCDStringIndex_Init(&string_index); - ASSERT_FORCE(res) - - NCDValMem_Init(&mem, &string_index); - - res = NCDValCons_Init(&cons, &mem); - ASSERT_FORCE(res) - - NCDValRef val1 = complete(list_prepend(list_prepend(list_prepend(make_list(), make_string("hello")), make_string("world")), make_list())); - char *str1 = NCDValGenerator_Generate(val1); - ASSERT_FORCE(str1) - ASSERT_FORCE(!strcmp(str1, "{{}, \"world\", \"hello\"}")) - free(str1); - - NCDValRef val2 = complete(map_insert(map_insert(map_insert(make_map(), make_list(), make_list()), make_string("A"), make_list()), make_string("B"), make_list())); - char *str2 = NCDValGenerator_Generate(val2); - ASSERT_FORCE(str2) - printf("%s\n", str2); - ASSERT_FORCE(!strcmp(str2, "[\"A\":{}, \"B\":{}, {}:{}]")) - free(str2); - - NCDValCons_Free(&cons); - NCDValMem_Free(&mem); - NCDStringIndex_Free(&string_index); - return 0; -} diff --git a/v2rayng/badvpn/examples/parse_number_test.c b/v2rayng/badvpn/examples/parse_number_test.c deleted file mode 100644 index 8545f5321f..0000000000 --- a/v2rayng/badvpn/examples/parse_number_test.c +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file parse_number_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -static void test_random (int num_digits, int digit_modulo) -{ - ASSERT(num_digits > 0); - ASSERT(digit_modulo > 0); - - uint8_t digits[40]; - - for (int i = 0; i < num_digits; i++) { - digits[i] = '0' + (rand() % digit_modulo); - } - digits[num_digits] = '\0'; - - char *endptr; - uintmax_t std_num = strtoumax((const char *)digits, &endptr, 10); - int std_res = !*endptr && !(std_num == UINTMAX_MAX && errno == ERANGE); - - uintmax_t num = 0; - int res = parse_unsigned_integer(MemRef_Make((const char *)digits, num_digits), &num); - - if (res != std_res) { - printf("fail1 %s\n", (const char *)digits); - ASSERT_FORCE(0); - } - - if (res && num != std_num) { - printf("fail2 %s\n", (const char *)digits); - ASSERT_FORCE(0); - } - - if (res) { - uint8_t *nozero_digits = digits; - while (*nozero_digits == '0' && nozero_digits != &digits[num_digits - 1]) { - nozero_digits++; - } - - char buf[40]; - int size = compute_decimal_repr_size(num); - generate_decimal_repr(num, buf, size); - buf[size] = '\0'; - ASSERT_FORCE(!strcmp(buf, (const char *)nozero_digits)); - } -} - -static void test_value (uintmax_t x) -{ - char str[40]; - sprintf(str, "%" PRIuMAX, x); - uintmax_t y; - int res = parse_unsigned_integer(MemRef_MakeCstr(str), &y); - ASSERT_FORCE(res); - ASSERT_FORCE(y == x); - - char str2[40]; - int size = compute_decimal_repr_size(x); - generate_decimal_repr(x, str2, size); - str2[size] = '\0'; - - ASSERT_FORCE(!strcmp(str2, str)); -} - -static void test_value_range (uintmax_t start, uintmax_t count) -{ - uintmax_t i = start; - do { - test_value(i); - i++; - } while (i != start + count); -} - -int main () -{ - srand(time(NULL)); - - for (int num_digits = 1; num_digits <= 22; num_digits++) { - for (int i = 0; i < 1000000; i++) { - test_random(num_digits, 10); - } - for (int i = 0; i < 1000000; i++) { - test_random(num_digits, 11); - } - } - - test_value_range(UINTMAX_C(0), 5000000); - test_value_range(UINTMAX_C(100000000), 5000000); - test_value_range(UINTMAX_C(258239003), 5000000); - test_value_range(UINTMAX_C(8241096180752634), 5000000); - test_value_range(UINTMAX_C(9127982390882308083), 5000000); - test_value_range(UINTMAX_C(18446744073700000000), 20000000); - - return 0; -} diff --git a/v2rayng/badvpn/examples/predicate_test.c b/v2rayng/badvpn/examples/predicate_test.c deleted file mode 100644 index 324a96031a..0000000000 --- a/v2rayng/badvpn/examples/predicate_test.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file predicate_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -static int func_hello (void *user, void **args) -{ - return 1; -} - -static int func_neg (void *user, void **args) -{ - int arg = *((int *)args[0]); - - return !arg; -} - -static int func_conj (void *user, void **args) -{ - int arg1 = *((int *)args[0]); - int arg2 = *((int *)args[1]); - - return (arg1 && arg2); -} - -static int func_strcmp (void *user, void **args) -{ - char *arg1 = (char *)args[0]; - char *arg2 = (char *)args[1]; - - return (!strcmp(arg1, arg2)); -} - -static int func_error (void *user, void **args) -{ - return -1; -} - -int main (int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - // init logger - BLog_InitStdout(); - - // init predicate - BPredicate pr; - if (!BPredicate_Init(&pr, argv[1])) { - fprintf(stderr, "BPredicate_Init failed\n"); - return 1; - } - - // init functions - BPredicateFunction f_hello; - BPredicateFunction_Init(&f_hello, &pr, "hello", NULL, 0, func_hello, NULL); - int arr1[] = {PREDICATE_TYPE_BOOL}; - BPredicateFunction f_neg; - BPredicateFunction_Init(&f_neg, &pr, "neg", arr1, 1, func_neg, NULL); - int arr2[] = {PREDICATE_TYPE_BOOL, PREDICATE_TYPE_BOOL}; - BPredicateFunction f_conj; - BPredicateFunction_Init(&f_conj, &pr, "conj", arr2, 2, func_conj, NULL); - int arr3[] = {PREDICATE_TYPE_STRING, PREDICATE_TYPE_STRING}; - BPredicateFunction f_strcmp; - BPredicateFunction_Init(&f_strcmp, &pr, "strcmp", arr3, 2, func_strcmp, NULL); - BPredicateFunction f_error; - BPredicateFunction_Init(&f_error, &pr, "error", NULL, 0, func_error, NULL); - - // evaluate - int result = BPredicate_Eval(&pr); - printf("%d\n", result); - - // free functions - BPredicateFunction_Free(&f_hello); - BPredicateFunction_Free(&f_neg); - BPredicateFunction_Free(&f_conj); - BPredicateFunction_Free(&f_strcmp); - BPredicateFunction_Free(&f_error); - - // free predicate - BPredicate_Free(&pr); - - return 0; -} diff --git a/v2rayng/badvpn/examples/savl_test.c b/v2rayng/badvpn/examples/savl_test.c deleted file mode 100644 index 18cf191234..0000000000 --- a/v2rayng/badvpn/examples/savl_test.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file savl_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include - -struct mynode; - -#include "savl_test_tree.h" -#include - -struct mynode { - int used; - int num; - MyTreeNode tree_node; -}; - -#include "savl_test_tree.h" -#include - -static void verify (MyTree *tree) -{ - printf("Verifying...\n"); - MyTree_Verify(tree, 0); -} - -int main (int argc, char **argv) -{ - int num_nodes; - int num_random_delete; - - if (argc != 3 || (num_nodes = atoi(argv[1])) <= 0 || (num_random_delete = atoi(argv[2])) < 0) { - fprintf(stderr, "Usage: %s \n", (argc > 0 ? argv[0] : NULL)); - return 1; - } - - struct mynode *nodes = (struct mynode *)BAllocArray(num_nodes, sizeof(*nodes)); - ASSERT_FORCE(nodes) - - int *values_ins = (int *)BAllocArray(num_nodes, sizeof(int)); - ASSERT_FORCE(values_ins) - - int *values = (int *)BAllocArray(num_random_delete, sizeof(int)); - ASSERT_FORCE(values) - - MyTree tree; - MyTree_Init(&tree); - verify(&tree); - - printf("Inserting random values...\n"); - int inserted = 0; - BRandom_randomize((uint8_t *)values_ins, num_nodes * sizeof(int)); - for (int i = 0; i < num_nodes; i++) { - nodes[i].num = values_ins[i]; - if (MyTree_Insert(&tree, 0, &nodes[i], NULL)) { - nodes[i].used = 1; - inserted++; - } else { - nodes[i].used = 0; - printf("Insert collision!\n"); - } - } - printf("Inserted %d entries\n", inserted); - ASSERT_FORCE(MyTree_Count(&tree, 0) == inserted) - verify(&tree); - - printf("Removing random entries...\n"); - int removed1 = 0; - BRandom_randomize((uint8_t *)values, num_random_delete * sizeof(int)); - for (int i = 0; i < num_random_delete; i++) { - int index = (((unsigned int *)values)[i] % num_nodes); - struct mynode *node = nodes + index; - if (node->used) { - MyTree_Remove(&tree, 0, node); - node->used = 0; - removed1++; - } - } - printf("Removed %d entries\n", removed1); - ASSERT_FORCE(MyTree_Count(&tree, 0) == inserted - removed1) - verify(&tree); - - printf("Removing remaining...\n"); - int removed2 = 0; - while (!MyTree_IsEmpty(&tree)) { - struct mynode *node = MyTree_GetFirst(&tree, 0); - ASSERT_FORCE(node->used) - MyTree_Remove(&tree, 0, node); - node->used = 0; - removed2++; - } - printf("Removed %d entries\n", removed2); - ASSERT_FORCE(MyTree_IsEmpty(&tree)) - ASSERT_FORCE(removed1 + removed2 == inserted) - ASSERT_FORCE(MyTree_Count(&tree, 0) == 0) - verify(&tree); - - BFree(nodes); - BFree(values_ins); - BFree(values); - - return 0; -} diff --git a/v2rayng/badvpn/examples/savl_test_tree.h b/v2rayng/badvpn/examples/savl_test_tree.h deleted file mode 100644 index 41964e96ba..0000000000 --- a/v2rayng/badvpn/examples/savl_test_tree.h +++ /dev/null @@ -1,9 +0,0 @@ -#define SAVL_PARAM_NAME MyTree -#define SAVL_PARAM_FEATURE_COUNTS 1 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct mynode -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_TYPE_COUNT int -#define SAVL_PARAM_VALUE_COUNT_MAX INT_MAX -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) B_COMPARE((entry1)->num, (entry2)->num) -#define SAVL_PARAM_MEMBER_NODE tree_node diff --git a/v2rayng/badvpn/examples/stdin_input.c b/v2rayng/badvpn/examples/stdin_input.c deleted file mode 100644 index 726a64aa7a..0000000000 --- a/v2rayng/badvpn/examples/stdin_input.c +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @file stdin_input.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Example program which reads stdin and waits for SIGINT and SIGTERM. - */ - -#include -#include - -#include -#include -#include -#include -#include - -#define BUF_SIZE 64 - -BReactor reactor; -BConnection pipe_con; -BUnixSignal usignal; -StreamRecvInterface *source_if; -uint8_t buf[BUF_SIZE + 1]; - -static void signal_handler (void *user, int signo) -{ - fprintf(stderr, "received %s, exiting\n", (signo == SIGINT ? "SIGINT" : "SIGTERM")); - - // exit event loop - BReactor_Quit(&reactor, 1); -} - -static void connection_handler (void *user, int event) -{ - if (event == BCONNECTION_EVENT_RECVCLOSED) { - fprintf(stderr, "pipe closed\n"); - } else { - fprintf(stderr, "pipe error\n"); - } - - // exit event loop - BReactor_Quit(&reactor, (event == BCONNECTION_EVENT_RECVCLOSED ? 0 : 1)); -} - -static void input_handler_done (void *user, int data_len) -{ - // receive next chunk - StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE); - - // print this chunk - buf[data_len] = '\0'; - printf("Received: '%s'\n", buf); -} - -int main () -{ - int ret = 1; - - BLog_InitStdout(); - - // init network - if (!BNetwork_GlobalInit()) { - fprintf(stderr, "BNetwork_GlobalInit failed\n"); - goto fail1; - } - - // init reactor (event loop) - if (!BReactor_Init(&reactor)) { - fprintf(stderr, "BReactor_Init failed\n"); - goto fail1; - } - - // init signal handling - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - if (!BUnixSignal_Init(&usignal, &reactor, set, signal_handler, NULL)) { - fprintf(stderr, "BUnixSignal_Init failed\n"); - goto fail2; - } - - // init BConnection object backed by the stdin fd - if (!BConnection_Init(&pipe_con, BConnection_source_pipe(0, 0), &reactor, NULL, connection_handler)) { - fprintf(stderr, "BConnection_Init failed\n"); - goto fail3; - } - - // init connection receive interface - BConnection_RecvAsync_Init(&pipe_con); - source_if = BConnection_RecvAsync_GetIf(&pipe_con); - - // init receive done callback - StreamRecvInterface_Receiver_Init(source_if, input_handler_done, NULL); - - // receive first chunk - StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE); - - // run event loop - ret = BReactor_Exec(&reactor); - - BConnection_RecvAsync_Free(&pipe_con); - BConnection_Free(&pipe_con); -fail3: - BUnixSignal_Free(&usignal, 0); -fail2: - BReactor_Free(&reactor); -fail1: - BLog_Free(); - DebugObjectGlobal_Finish(); - return ret; -} diff --git a/v2rayng/badvpn/examples/substring_test.c b/v2rayng/badvpn/examples/substring_test.c deleted file mode 100644 index 37aaf5a6cd..0000000000 --- a/v2rayng/badvpn/examples/substring_test.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - * @file substring_test.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -static int find_substring_slow (const char *str, size_t str_len, const char *sub, size_t sub_len, size_t *out_pos) -{ - ASSERT(sub_len > 0) - - if (str_len < sub_len) { - return 0; - } - - for (size_t i = 0; i <= str_len - sub_len; i++) { - if (!memcmp(str + i, sub, sub_len)) { - *out_pos = i; - return 1; - } - } - - return 0; -} - -static void print_data (const char *str, size_t str_len) -{ - while (str_len > 0) { - printf("%02"PRIx8" ", (uint8_t)(*str)); - str++; - str_len--; - } - printf("\n"); -} - -static void print_table (const size_t *table, size_t len) -{ - for (size_t i = 1; i < len; i++) { - printf("%zu ", table[i]); - } - printf("\n"); -} - -static void test_tables (int len, int count) -{ - ASSERT(len > 0) - ASSERT(count >= 0) - - char *word = (char *)BAllocSize(bsize_fromint(len)); - ASSERT_FORCE(word) - - size_t *table = (size_t *)BAllocSize(bsize_mul(bsize_fromint(len), bsize_fromsize(sizeof(table[0])))); - ASSERT_FORCE(table) - - for (int i = 0; i < count; i++) { - for (int j = 0; j < len; j++) { - word[j] = rand() % 2; - } - - build_substring_backtrack_table(MemRef_Make(word, len), table); - - for (int j = 1; j < len; j++) { - for (int k = j - 1; k >= 0; k--) { - if (!memcmp(word + j - k, word, k)) { - ASSERT_FORCE(table[j] == k) - break; - } - } - } - } - - BFree(table); - BFree(word); -} - -static void test_substring (int word_len, int text_len, int word_count, int text_count) -{ - assert(word_len > 0); - assert(text_len >= 0); - assert(word_count >= 0); - assert(text_count >= 0); - - char *word = (char *)BAllocSize(bsize_fromint(word_len)); - ASSERT_FORCE(word) - - size_t *table = (size_t *)BAllocSize(bsize_mul(bsize_fromint(word_len), bsize_fromsize(sizeof(table[0])))); - ASSERT_FORCE(table) - - char *text = (char *)BAllocSize(bsize_fromint(text_len)); - ASSERT_FORCE(text) - - for (int i = 0; i < word_count; i++) { - for (int j = 0; j < word_len; j++) { - word[j] = rand() % 2; - } - - build_substring_backtrack_table(MemRef_Make(word, word_len), table); - - for (int j = 0; j < text_count; j++) { - for (int k = 0; k < text_len; k++) { - text[k] = rand() % 2; - } - - size_t pos = 36; // to remove warning - int res = find_substring(MemRef_Make(text, text_len), MemRef_Make(word, word_len), table, &pos); - - size_t spos = 59; // to remove warning - int sres = find_substring_slow(text, text_len, word, word_len, &spos); - - ASSERT_FORCE(res == sres) - if (res) { - ASSERT_FORCE(pos == spos) - } - } - } - - BFree(text); - BFree(table); - BFree(word); -} - -int main (int argc, char *argv[]) -{ - if (argc != 7) { - printf("Usage: %s \n", (argc == 0 ? "" : argv[0])); - return 1; - } - - int tables_len = atoi(argv[1]); - int tables_count = atoi(argv[2]); - int word_len = atoi(argv[3]); - int text_len = atoi(argv[4]); - int word_count = atoi(argv[5]); - int text_count = atoi(argv[6]); - - if (tables_len <= 0 || tables_count < 0 || word_len <= 0 || text_len < 0 || word_count < 0 || text_count < 0) { - printf("Bad arguments.\n"); - return 1; - } - - srand(time(NULL)); - - test_tables(tables_len, tables_count); - - test_substring(word_len, text_len, word_count, text_count); - - { - char text[] = "aggagaa"; - char word[] = "aga"; - size_t table[sizeof(word) - 1]; - build_substring_backtrack_table(MemRef_MakeCstr(word), table); - - size_t pos; - int res = find_substring(MemRef_MakeCstr(text), MemRef_MakeCstr(word), table, &pos); - ASSERT_FORCE(res) - ASSERT_FORCE(pos == 3) - } - - { - char text[] = "aagagga"; - char word[] = "aga"; - size_t table[sizeof(word) - 1]; - build_substring_backtrack_table_reverse(MemRef_MakeCstr(word), table); - - size_t pos; - int res = find_substring_reverse(MemRef_MakeCstr(text), MemRef_MakeCstr(word), table, &pos); - ASSERT_FORCE(res) - ASSERT_FORCE(pos == 1) - } - - return 0; -} diff --git a/v2rayng/badvpn/fix_flex.php b/v2rayng/badvpn/fix_flex.php deleted file mode 100644 index bd026d0bd2..0000000000 --- a/v2rayng/badvpn/fix_flex.php +++ /dev/null @@ -1,10 +0,0 @@ -", "#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L"); -$replace = array("", "#if 1"); -$contents = str_replace($search, $replace, $contents); -$res = file_put_contents($filename, $contents); -if ($res === FALSE) exit(1); diff --git a/v2rayng/badvpn/flooder/CMakeLists.txt b/v2rayng/badvpn/flooder/CMakeLists.txt deleted file mode 100644 index a523244c17..0000000000 --- a/v2rayng/badvpn/flooder/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_executable(badvpn-flooder flooder.c) -target_link_libraries(badvpn-flooder system flow server_conection ${NSPR_LIBRARIES} ${NSS_LIBRARIES}) - -install( - TARGETS badvpn-flooder - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) diff --git a/v2rayng/badvpn/flooder/flooder.c b/v2rayng/badvpn/flooder/flooder.c deleted file mode 100644 index 1f3f05cce8..0000000000 --- a/v2rayng/badvpn/flooder/flooder.c +++ /dev/null @@ -1,671 +0,0 @@ -/** - * @file flooder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BADVPN_USE_WINAPI -#include -#endif - -#include - -#include - -#define LOGGER_STDOUT 1 -#define LOGGER_SYSLOG 2 - -// command-line options -struct { - int help; - int version; - int logger; - #ifndef BADVPN_USE_WINAPI - char *logger_syslog_facility; - char *logger_syslog_ident; - #endif - int loglevel; - int loglevels[BLOG_NUM_CHANNELS]; - int ssl; - char *nssdb; - char *client_cert_name; - char *server_name; - char *server_addr; - peerid_t floods[MAX_FLOODS]; - int num_floods; -} options; - -// server address we connect to -BAddr server_addr; - -// server name to use for SSL -char server_name[256]; - -// reactor -BReactor ss; - -// client certificate if using SSL -CERTCertificate *client_cert; - -// client private key if using SSL -SECKEYPrivateKey *client_key; - -// server connection -ServerConnection server; - -// whether server is ready -int server_ready; - -// my ID, defined only after server_ready -peerid_t my_id; - -// flooding output -PacketRecvInterface flood_source; -PacketProtoEncoder flood_encoder; -SinglePacketBuffer flood_buffer; - -// whether we were asked for a packet and blocked -int flood_blocking; - -// index of next peer to send packet too -int flood_next; - -/** - * Cleans up everything that can be cleaned up from inside the event loop. - */ -static void terminate (void); - -/** - * Prints command line help. - */ -static void print_help (const char *name); - -/** - * Prints program name, version and copyright notice. - */ -static void print_version (void); - -/** - * Parses command line options into the options strucute. - * - * @return 1 on success, 0 on failure - */ -static int parse_arguments (int argc, char *argv[]); - -/** - * Processes command line options. - * - * @return 1 on success, 0 on failure - */ -static int resolve_arguments (void); - -/** - * Handler invoked when program termination is requested. - */ -static void signal_handler (void *unused); - -static void server_handler_error (void *user); -static void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip); -static void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len); -static void server_handler_endclient (void *user, peerid_t peer_id); -static void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len); - -static void flood_source_handler_recv (void *user, uint8_t *data); - -int main (int argc, char *argv[]) -{ - if (argc <= 0) { - return 1; - } - - // open standard streams - open_standard_streams(); - - // parse command-line arguments - if (!parse_arguments(argc, argv)) { - fprintf(stderr, "Failed to parse arguments\n"); - print_help(argv[0]); - goto fail0; - } - - // handle --help and --version - if (options.help) { - print_version(); - print_help(argv[0]); - return 0; - } - if (options.version) { - print_version(); - return 0; - } - - // initialize logger - switch (options.logger) { - case LOGGER_STDOUT: - BLog_InitStdout(); - break; - #ifndef BADVPN_USE_WINAPI - case LOGGER_SYSLOG: - if (!BLog_InitSyslog(options.logger_syslog_ident, options.logger_syslog_facility)) { - fprintf(stderr, "Failed to initialize syslog logger\n"); - goto fail0; - } - break; - #endif - default: - ASSERT(0); - } - - // configure logger channels - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - if (options.loglevels[i] >= 0) { - BLog_SetChannelLoglevel(i, options.loglevels[i]); - } - else if (options.loglevel >= 0) { - BLog_SetChannelLoglevel(i, options.loglevel); - } - } - - BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); - - // initialize network - if (!BNetwork_GlobalInit()) { - BLog(BLOG_ERROR, "BNetwork_GlobalInit failed"); - goto fail1; - } - - // init time - BTime_Init(); - - // resolve addresses - if (!resolve_arguments()) { - BLog(BLOG_ERROR, "Failed to resolve arguments"); - goto fail1; - } - - // init reactor - if (!BReactor_Init(&ss)) { - BLog(BLOG_ERROR, "BReactor_Init failed"); - goto fail1; - } - - // setup signal handler - if (!BSignal_Init(&ss, signal_handler, NULL)) { - BLog(BLOG_ERROR, "BSignal_Init failed"); - goto fail1a; - } - - if (options.ssl) { - // init NSPR - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - // register local NSPR file types - if (!BSSLConnection_GlobalInit()) { - BLog(BLOG_ERROR, "BSSLConnection_GlobalInit failed"); - goto fail3; - } - - // init NSS - if (NSS_Init(options.nssdb) != SECSuccess) { - BLog(BLOG_ERROR, "NSS_Init failed (%d)", (int)PR_GetError()); - goto fail2; - } - - // set cipher policy - if (NSS_SetDomesticPolicy() != SECSuccess) { - BLog(BLOG_ERROR, "NSS_SetDomesticPolicy failed (%d)", (int)PR_GetError()); - goto fail3; - } - - // init server cache - if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) { - BLog(BLOG_ERROR, "SSL_ConfigServerSessionIDCache failed (%d)", (int)PR_GetError()); - goto fail3; - } - - // open server certificate and private key - if (!open_nss_cert_and_key(options.client_cert_name, &client_cert, &client_key)) { - BLog(BLOG_ERROR, "Cannot open certificate and key"); - goto fail4; - } - } - - // start connecting to server - if (!ServerConnection_Init( - &server, &ss, NULL, server_addr, SC_KEEPALIVE_INTERVAL, SERVER_BUFFER_MIN_PACKETS, options.ssl, 0, client_cert, client_key, server_name, NULL, - server_handler_error, server_handler_ready, server_handler_newclient, server_handler_endclient, server_handler_message - )) { - BLog(BLOG_ERROR, "ServerConnection_Init failed"); - goto fail5; - } - - // set server not ready - server_ready = 0; - - // enter event loop - BLog(BLOG_NOTICE, "entering event loop"); - BReactor_Exec(&ss); - - if (server_ready) { - ServerConnection_ReleaseBuffers(&server); - SinglePacketBuffer_Free(&flood_buffer); - PacketProtoEncoder_Free(&flood_encoder); - PacketRecvInterface_Free(&flood_source); - } - - ServerConnection_Free(&server); -fail5: - if (options.ssl) { - CERT_DestroyCertificate(client_cert); - SECKEY_DestroyPrivateKey(client_key); -fail4: - ASSERT_FORCE(SSL_ShutdownServerSessionIDCache() == SECSuccess) -fail3: - SSL_ClearSessionCache(); - ASSERT_FORCE(NSS_Shutdown() == SECSuccess) -fail2: - ASSERT_FORCE(PR_Cleanup() == PR_SUCCESS) - PL_ArenaFinish(); - } - - BSignal_Finish(); -fail1a: - BReactor_Free(&ss); -fail1: - BLog(BLOG_NOTICE, "exiting"); - BLog_Free(); -fail0: - DebugObjectGlobal_Finish(); - - return 1; -} - -void terminate (void) -{ - BLog(BLOG_NOTICE, "tearing down"); - - // exit event loop - BReactor_Quit(&ss, 0); -} - -void print_help (const char *name) -{ - printf( - "Usage:\n" - " %s\n" - " [--help]\n" - " [--version]\n" - " [--logger <"LOGGERS_STRING">]\n" - #ifndef BADVPN_USE_WINAPI - " (logger=syslog?\n" - " [--syslog-facility ]\n" - " [--syslog-ident ]\n" - " )\n" - #endif - " [--loglevel <0-5/none/error/warning/notice/info/debug>]\n" - " [--channel-loglevel <0-5/none/error/warning/notice/info/debug>] ...\n" - " [--ssl --nssdb --client-cert-name ]\n" - " [--server-name ]\n" - " --server-addr \n" - " [--flood-id ] ...\n" - "Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n", - name - ); -} - -void print_version (void) -{ - printf(GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION"\n"GLOBAL_COPYRIGHT_NOTICE"\n"); -} - -int parse_arguments (int argc, char *argv[]) -{ - if (argc <= 0) { - return 0; - } - - options.help = 0; - options.version = 0; - options.logger = LOGGER_STDOUT; - #ifndef BADVPN_USE_WINAPI - options.logger_syslog_facility = "daemon"; - options.logger_syslog_ident = argv[0]; - #endif - options.loglevel = -1; - for (int i = 0; i < BLOG_NUM_CHANNELS; i++) { - options.loglevels[i] = -1; - } - options.ssl = 0; - options.nssdb = NULL; - options.client_cert_name = NULL; - options.server_name = NULL; - options.server_addr = NULL; - options.num_floods = 0; - - int i; - for (i = 1; i < argc; i++) { - char *arg = argv[i]; - if (!strcmp(arg, "--help")) { - options.help = 1; - } - else if (!strcmp(arg, "--version")) { - options.version = 1; - } - else if (!strcmp(arg, "--logger")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - char *arg2 = argv[i + 1]; - if (!strcmp(arg2, "stdout")) { - options.logger = LOGGER_STDOUT; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg2, "syslog")) { - options.logger = LOGGER_SYSLOG; - } - #endif - else { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - #ifndef BADVPN_USE_WINAPI - else if (!strcmp(arg, "--syslog-facility")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_facility = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--syslog-ident")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.logger_syslog_ident = argv[i + 1]; - i++; - } - #endif - else if (!strcmp(arg, "--loglevel")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if ((options.loglevel = parse_loglevel(argv[i + 1])) < 0) { - fprintf(stderr, "%s: wrong argument\n", arg); - return 0; - } - i++; - } - else if (!strcmp(arg, "--channel-loglevel")) { - if (2 >= argc - i) { - fprintf(stderr, "%s: requires two arguments\n", arg); - return 0; - } - int channel = BLogGlobal_GetChannelByName(argv[i + 1]); - if (channel < 0) { - fprintf(stderr, "%s: wrong channel argument\n", arg); - return 0; - } - int loglevel = parse_loglevel(argv[i + 2]); - if (loglevel < 0) { - fprintf(stderr, "%s: wrong loglevel argument\n", arg); - return 0; - } - options.loglevels[channel] = loglevel; - i += 2; - } - else if (!strcmp(arg, "--ssl")) { - options.ssl = 1; - } - else if (!strcmp(arg, "--nssdb")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.nssdb = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--client-cert-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.client_cert_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-name")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_name = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--server-addr")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - options.server_addr = argv[i + 1]; - i++; - } - else if (!strcmp(arg, "--flood-id")) { - if (1 >= argc - i) { - fprintf(stderr, "%s: requires an argument\n", arg); - return 0; - } - if (options.num_floods == MAX_FLOODS) { - fprintf(stderr, "%s: too many\n", arg); - return 0; - } - options.floods[options.num_floods] = atoi(argv[i + 1]); - options.num_floods++; - i++; - } - else { - fprintf(stderr, "unknown option: %s\n", arg); - return 0; - } - } - - if (options.help || options.version) { - return 1; - } - - if (options.ssl != !!options.nssdb) { - fprintf(stderr, "False: --ssl <=> --nssdb\n"); - return 0; - } - - if (options.ssl != !!options.client_cert_name) { - fprintf(stderr, "False: --ssl <=> --client-cert-name\n"); - return 0; - } - - if (!options.server_addr) { - fprintf(stderr, "False: --server-addr\n"); - return 0; - } - - return 1; -} - -int resolve_arguments (void) -{ - // resolve server address - ASSERT(options.server_addr) - if (!BAddr_Parse(&server_addr, options.server_addr, server_name, sizeof(server_name))) { - BLog(BLOG_ERROR, "server addr: BAddr_Parse failed"); - return 0; - } - if (!addr_supported(server_addr)) { - BLog(BLOG_ERROR, "server addr: not supported"); - return 0; - } - - // override server name if requested - if (options.server_name) { - if (strlen(options.server_name) >= sizeof(server_name)) { - BLog(BLOG_ERROR, "server name: too long"); - return 0; - } - strcpy(server_name, options.server_name); - } - - return 1; -} - -void signal_handler (void *unused) -{ - BLog(BLOG_NOTICE, "termination requested"); - - terminate(); -} - -void server_handler_error (void *user) -{ - BLog(BLOG_ERROR, "server connection failed, exiting"); - - terminate(); -} - -void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip) -{ - ASSERT(!server_ready) - - // remember our ID - my_id = param_my_id; - - // init flooding - - // init source - PacketRecvInterface_Init(&flood_source, SC_MAX_ENC, flood_source_handler_recv, NULL, BReactor_PendingGroup(&ss)); - - // init encoder - PacketProtoEncoder_Init(&flood_encoder, &flood_source, BReactor_PendingGroup(&ss)); - - // init buffer - if (!SinglePacketBuffer_Init(&flood_buffer, PacketProtoEncoder_GetOutput(&flood_encoder), ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss))) { - BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed, exiting"); - goto fail1; - } - - // set not blocking - flood_blocking = 0; - - // set server ready - server_ready = 1; - - BLog(BLOG_INFO, "server: ready, my ID is %d", (int)my_id); - - return; - -fail1: - PacketProtoEncoder_Free(&flood_encoder); - PacketRecvInterface_Free(&flood_source); - terminate(); -} - -void server_handler_newclient (void *user, peerid_t peer_id, int flags, const uint8_t *cert, int cert_len) -{ - ASSERT(server_ready) - - BLog(BLOG_INFO, "newclient %d", (int)peer_id); -} - -void server_handler_endclient (void *user, peerid_t peer_id) -{ - ASSERT(server_ready) - - BLog(BLOG_INFO, "endclient %d", (int)peer_id); -} - -void server_handler_message (void *user, peerid_t peer_id, uint8_t *data, int data_len) -{ - ASSERT(server_ready) - ASSERT(data_len >= 0) - ASSERT(data_len <= SC_MAX_MSGLEN) - - BLog(BLOG_INFO, "message from %d", (int)peer_id); -} - -void flood_source_handler_recv (void *user, uint8_t *data) -{ - ASSERT(server_ready) - ASSERT(!flood_blocking) - if (options.num_floods > 0) { - ASSERT(flood_next >= 0) - ASSERT(flood_next < options.num_floods) - } - - if (options.num_floods == 0) { - flood_blocking = 1; - return; - } - - peerid_t peer_id = options.floods[flood_next]; - flood_next = (flood_next + 1) % options.num_floods; - - BLog(BLOG_INFO, "message to %d", (int)peer_id); - - struct sc_header header; - header.type = SCID_OUTMSG; - memcpy(data, &header, sizeof(header)); - - struct sc_client_outmsg omsg; - omsg.clientid = htol16(peer_id); - memcpy(data + sizeof(header), &omsg, sizeof(omsg)); - - memset(data + sizeof(struct sc_header) + sizeof(struct sc_client_outmsg), 0, SC_MAX_MSGLEN); - - PacketRecvInterface_Done(&flood_source, sizeof(struct sc_header) + sizeof(struct sc_client_outmsg) + SC_MAX_MSGLEN); -} diff --git a/v2rayng/badvpn/flooder/flooder.h b/v2rayng/badvpn/flooder/flooder.h deleted file mode 100644 index c8b844310e..0000000000 --- a/v2rayng/badvpn/flooder/flooder.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file flooder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// name of the program -#define PROGRAM_NAME "flooder" - -// server output buffer size -#define SERVER_BUFFER_MIN_PACKETS 200 - -// maximum number of peers to flood -#define MAX_FLOODS 64 diff --git a/v2rayng/badvpn/flow/BufferWriter.c b/v2rayng/badvpn/flow/BufferWriter.c deleted file mode 100644 index b0e4129618..0000000000 --- a/v2rayng/badvpn/flow/BufferWriter.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file BufferWriter.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -static void output_handler_recv (BufferWriter *o, uint8_t *data) -{ - ASSERT(!o->out_have) - - // set output packet - o->out_have = 1; - o->out = data; -} - -void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init output - PacketRecvInterface_Init(&o->recv_interface, mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no output packet - o->out_have = 0; - - DebugObject_Init(&o->d_obj); - #ifndef NDEBUG - o->d_mtu = mtu; - o->d_writing = 0; - #endif -} - -void BufferWriter_Free (BufferWriter *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->recv_interface); -} - -PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->recv_interface; -} - -int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf) -{ - ASSERT(!o->d_writing) - DebugObject_Access(&o->d_obj); - - if (!o->out_have) { - return 0; - } - - if (buf) { - *buf = o->out; - } - - #ifndef NDEBUG - o->d_writing = 1; - #endif - - return 1; -} - -void BufferWriter_EndPacket (BufferWriter *o, int len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->d_mtu) - ASSERT(o->out_have) - ASSERT(o->d_writing) - DebugObject_Access(&o->d_obj); - - // set no output packet - o->out_have = 0; - - // finish packet - PacketRecvInterface_Done(&o->recv_interface, len); - - #ifndef NDEBUG - o->d_writing = 0; - #endif -} diff --git a/v2rayng/badvpn/flow/BufferWriter.h b/v2rayng/badvpn/flow/BufferWriter.h deleted file mode 100644 index 6b6a9c44ca..0000000000 --- a/v2rayng/badvpn/flow/BufferWriter.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file BufferWriter.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object for writing packets to a {@link PacketRecvInterface} client - * in a best-effort fashion. - */ - -#ifndef BADVPN_FLOW_BUFFERWRITER_H -#define BADVPN_FLOW_BUFFERWRITER_H - -#include - -#include -#include -#include - -/** - * Object for writing packets to a {@link PacketRecvInterface} client - * in a best-effort fashion. - */ -typedef struct { - PacketRecvInterface recv_interface; - int out_have; - uint8_t *out; - DebugObject d_obj; - #ifndef NDEBUG - int d_mtu; - int d_writing; - #endif -} BufferWriter; - -/** - * Initializes the object. - * The object is initialized in not writing state. - * - * @param o the object - * @param mtu maximum input packet length - * @param pg pending group - */ -void BufferWriter_Init (BufferWriter *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void BufferWriter_Free (BufferWriter *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * BufferWriter_GetOutput (BufferWriter *o); - -/** - * Attempts to provide a memory location for writing a packet. - * The object must be in not writing state. - * On success, the object enters writing state. - * - * @param o the object - * @param buf if not NULL, on success, the memory location will be stored here. - * It will have space for MTU bytes. - * @return 1 on success, 0 on failure - */ -int BufferWriter_StartPacket (BufferWriter *o, uint8_t **buf) WARN_UNUSED; - -/** - * Submits a packet written to the buffer. - * The object must be in writing state. - * Yhe object enters not writing state. - * - * @param o the object - * @param len length of the packet that was written. Must be >=0 and - * <=MTU. - */ -void BufferWriter_EndPacket (BufferWriter *o, int len); - -#endif diff --git a/v2rayng/badvpn/flow/CMakeLists.txt b/v2rayng/badvpn/flow/CMakeLists.txt deleted file mode 100644 index 6cd82f6c20..0000000000 --- a/v2rayng/badvpn/flow/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -set(FLOW_SOURCES - PacketPassFairQueue.c - PacketPassPriorityQueue.c - PacketPassConnector.c - PacketRecvConnector.c - StreamRecvConnector.c - PacketRecvBlocker.c - PacketPassNotifier.c - PacketBuffer.c - SinglePacketBuffer.c - PacketCopier.c - PacketStreamSender.c - PacketProtoEncoder.c - PacketProtoDecoder.c - PacketProtoFlow.c - SinglePacketSender.c - BufferWriter.c - PacketPassInterface.c - PacketRecvInterface.c - StreamPassInterface.c - StreamRecvInterface.c - RouteBuffer.c - PacketRouter.c - LineBuffer.c - SingleStreamSender.c - SingleStreamReceiver.c - StreamPacketSender.c - StreamPassConnector.c - PacketPassFifoQueue.c -) -badvpn_add_library(flow "base" "" "${FLOW_SOURCES}") diff --git a/v2rayng/badvpn/flow/LineBuffer.c b/v2rayng/badvpn/flow/LineBuffer.c deleted file mode 100644 index 15c996991a..0000000000 --- a/v2rayng/badvpn/flow/LineBuffer.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file LineBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include - -#include - -#include - -static void input_handler_done (LineBuffer *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->buf_size - o->buf_used) - - // update buffer - o->buf_used += data_len; - - // look for newline - int i; - for (i = o->buf_used - data_len; i < o->buf_used; i++) { - if (o->buf[i] == o->nl_char) { - break; - } - } - - if (i < o->buf_used || o->buf_used == o->buf_size) { - if (i == o->buf_used) { - BLog(BLOG_WARNING, "line too long"); - } - - // pass to output - o->buf_consumed = (i < o->buf_used ? i + 1 : i); - PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed); - } else { - // receive more data - StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used); - } -} - -static void output_handler_done (LineBuffer *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->buf_consumed > 0) - ASSERT(o->buf_consumed <= o->buf_used) - - // update buffer - memmove(o->buf, o->buf + o->buf_consumed, o->buf_used - o->buf_consumed); - o->buf_used -= o->buf_consumed; - - // look for newline - int i; - for (i = 0; i < o->buf_used; i++) { - if (o->buf[i] == o->nl_char) { - break; - } - } - - if (i < o->buf_used || o->buf_used == o->buf_size) { - // pass to output - o->buf_consumed = (i < o->buf_used ? i + 1 : i); - PacketPassInterface_Sender_Send(o->output, o->buf, o->buf_consumed); - } else { - // receive more data - StreamRecvInterface_Receiver_Recv(o->input, o->buf + o->buf_used, o->buf_size - o->buf_used); - } -} - -int LineBuffer_Init (LineBuffer *o, StreamRecvInterface *input, PacketPassInterface *output, int buf_size, uint8_t nl_char) -{ - ASSERT(buf_size > 0) - ASSERT(PacketPassInterface_GetMTU(output) >= buf_size) - - // init arguments - o->input = input; - o->output = output; - o->buf_size = buf_size; - o->nl_char = nl_char; - - // init input - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // set buffer empty - o->buf_used = 0; - - // allocate buffer - if (!(o->buf = (uint8_t *)malloc(o->buf_size))) { - BLog(BLOG_ERROR, "malloc failed"); - goto fail0; - } - - // start receiving - StreamRecvInterface_Receiver_Recv(o->input, o->buf, o->buf_size); - - DebugObject_Init(&o->d_obj); - return 1; - -fail0: - return 0; -} - -void LineBuffer_Free (LineBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - free(o->buf); -} diff --git a/v2rayng/badvpn/flow/LineBuffer.h b/v2rayng/badvpn/flow/LineBuffer.h deleted file mode 100644 index 6e15e323b8..0000000000 --- a/v2rayng/badvpn/flow/LineBuffer.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file LineBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_FLOW_LINEBUFFER_H -#define BADVPN_FLOW_LINEBUFFER_H - -#include - -#include -#include -#include -#include - -typedef struct { - StreamRecvInterface *input; - PacketPassInterface *output; - int buf_size; - uint8_t nl_char; - int buf_used; - uint8_t *buf; - int buf_consumed; - DebugObject d_obj; -} LineBuffer; - -int LineBuffer_Init (LineBuffer *o, StreamRecvInterface *input, PacketPassInterface *output, int buf_size, uint8_t nl_char) WARN_UNUSED; -void LineBuffer_Free (LineBuffer *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketBuffer.c b/v2rayng/badvpn/flow/PacketBuffer.c deleted file mode 100644 index 30afef6141..0000000000 --- a/v2rayng/badvpn/flow/PacketBuffer.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file PacketBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include - -static void input_handler_done (PacketBuffer *buf, int in_len); -static void output_handler_done (PacketBuffer *buf); - -void input_handler_done (PacketBuffer *buf, int in_len) -{ - ASSERT(in_len >= 0) - ASSERT(in_len <= buf->input_mtu) - DebugObject_Access(&buf->d_obj); - - // remember if buffer is empty - int was_empty = (buf->buf.output_avail < 0); - - // submit packet to buffer - ChunkBuffer2_SubmitPacket(&buf->buf, in_len); - - // if there is space, schedule receive - if (buf->buf.input_avail >= buf->input_mtu) { - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - } - - // if buffer was empty, schedule send - if (was_empty) { - PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail); - } -} - -void output_handler_done (PacketBuffer *buf) -{ - DebugObject_Access(&buf->d_obj); - - // remember if buffer is full - int was_full = (buf->buf.input_avail < buf->input_mtu); - - // remove packet from buffer - ChunkBuffer2_ConsumePacket(&buf->buf); - - // if buffer was full and there is space, schedule receive - if (was_full && buf->buf.input_avail >= buf->input_mtu) { - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - } - - // if there is more data, schedule send - if (buf->buf.output_avail >= 0) { - PacketPassInterface_Sender_Send(buf->output, buf->buf.output_dest, buf->buf.output_avail); - } -} - -int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input)) - ASSERT(num_packets > 0) - - // init arguments - buf->input = input; - buf->output = output; - - // init input - PacketRecvInterface_Receiver_Init(buf->input, (PacketRecvInterface_handler_done)input_handler_done, buf); - - // set input MTU - buf->input_mtu = PacketRecvInterface_GetMTU(buf->input); - - // init output - PacketPassInterface_Sender_Init(buf->output, (PacketPassInterface_handler_done)output_handler_done, buf); - - // allocate buffer - int num_blocks = ChunkBuffer2_calc_blocks(buf->input_mtu, num_packets); - if (num_blocks < 0) { - goto fail0; - } - if (!(buf->buf_data = (struct ChunkBuffer2_block *)BAllocArray(num_blocks, sizeof(buf->buf_data[0])))) { - goto fail0; - } - - // init buffer - ChunkBuffer2_Init(&buf->buf, buf->buf_data, num_blocks, buf->input_mtu); - - // schedule receive - PacketRecvInterface_Receiver_Recv(buf->input, buf->buf.input_dest); - - DebugObject_Init(&buf->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketBuffer_Free (PacketBuffer *buf) -{ - DebugObject_Free(&buf->d_obj); - - // free buffer - BFree(buf->buf_data); -} diff --git a/v2rayng/badvpn/flow/PacketBuffer.h b/v2rayng/badvpn/flow/PacketBuffer.h deleted file mode 100644 index 6daab69baf..0000000000 --- a/v2rayng/badvpn/flow/PacketBuffer.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file PacketBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output. - */ - -#ifndef BADVPN_FLOW_PACKETBUFFER_H -#define BADVPN_FLOW_PACKETBUFFER_H - -#include - -#include -#include -#include -#include -#include - -/** - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface *input; - int input_mtu; - PacketPassInterface *output; - struct ChunkBuffer2_block *buf_data; - ChunkBuffer2 buf; -} PacketBuffer; - -/** - * Initializes the buffer. - * Output MTU must be >= input MTU. - * - * @param buf the object - * @param input input interface - * @param output output interface - * @param num_packets minimum number of packets the buffer must hold. Must be >0. - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketBuffer_Init (PacketBuffer *buf, PacketRecvInterface *input, PacketPassInterface *output, int num_packets, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the buffer. - * - * @param buf the object - */ -void PacketBuffer_Free (PacketBuffer *buf); - -#endif diff --git a/v2rayng/badvpn/flow/PacketCopier.c b/v2rayng/badvpn/flow/PacketCopier.c deleted file mode 100644 index f4c71264d8..0000000000 --- a/v2rayng/badvpn/flow/PacketCopier.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file PacketCopier.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void input_handler_send (PacketCopier *o, uint8_t *data, int data_len) -{ - ASSERT(o->in_len == -1) - ASSERT(data_len >= 0) - DebugObject_Access(&o->d_obj); - - if (!o->out_have) { - o->in_len = data_len; - o->in = data; - return; - } - - memcpy(o->out, data, data_len); - - // finish input packet - PacketPassInterface_Done(&o->input); - - // finish output packet - PacketRecvInterface_Done(&o->output, data_len); - - o->out_have = 0; -} - -static void input_handler_requestcancel (PacketCopier *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // finish input packet - PacketPassInterface_Done(&o->input); - - o->in_len = -1; -} - -static void output_handler_recv (PacketCopier *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - if (o->in_len < 0) { - o->out_have = 1; - o->out = data; - return; - } - - memcpy(data, o->in, o->in_len); - - // finish input packet - PacketPassInterface_Done(&o->input); - - // finish output packet - PacketRecvInterface_Done(&o->output, o->in_len); - - o->in_len = -1; -} - -void PacketCopier_Init (PacketCopier *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init input - PacketPassInterface_Init(&o->input, mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - - // init output - PacketRecvInterface_Init(&o->output, mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // set no input packet - o->in_len = -1; - - // set no output packet - o->out_have = 0; - - DebugObject_Init(&o->d_obj); -} - -void PacketCopier_Free (PacketCopier *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketCopier_GetInput (PacketCopier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -PacketRecvInterface * PacketCopier_GetOutput (PacketCopier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} diff --git a/v2rayng/badvpn/flow/PacketCopier.h b/v2rayng/badvpn/flow/PacketCopier.h deleted file mode 100644 index 9b8ba863d7..0000000000 --- a/v2rayng/badvpn/flow/PacketCopier.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file PacketCopier.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which copies packets. - */ - -#ifndef BADVPN_FLOW_PACKETCOPIER_H -#define BADVPN_FLOW_PACKETCOPIER_H - -#include - -#include -#include - -/** - * Object which copies packets. - * Input is via {@link PacketPassInterface}. - * Output is via {@link PacketRecvInterface}. - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface input; - PacketRecvInterface output; - int in_len; - uint8_t *in; - int out_have; - uint8_t *out; -} PacketCopier; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. - * @param pg pending group - */ -void PacketCopier_Init (PacketCopier *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketCopier_Free (PacketCopier *o); - -/** - * Returns the input interface. - * The MTU of the interface will as in {@link PacketCopier_Init}. - * The interface will support cancel functionality. - * - * @return input interface - */ -PacketPassInterface * PacketCopier_GetInput (PacketCopier *o); - -/** - * Returns the output interface. - * The MTU of the interface will be as in {@link PacketCopier_Init}. - * - * @return output interface - */ -PacketRecvInterface * PacketCopier_GetOutput (PacketCopier *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassConnector.c b/v2rayng/badvpn/flow/PacketPassConnector.c deleted file mode 100644 index 1a10326d04..0000000000 --- a/v2rayng/badvpn/flow/PacketPassConnector.c +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file PacketPassConnector.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void input_handler_send (PacketPassConnector *o, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->input_mtu) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - o->in = data; - - if (o->output) { - // schedule send - PacketPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -static void output_handler_done (PacketPassConnector *o) -{ - ASSERT(o->in_len >= 0) - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // have no input packet - o->in_len = -1; - - // allow input to send more packets - PacketPassInterface_Done(&o->input); -} - -void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - o->input_mtu = mtu; - - // init input - PacketPassInterface_Init(&o->input, o->input_mtu, (PacketPassInterface_handler_send)input_handler_send, o, pg); - - // have no input packet - o->in_len = -1; - - // have no output - o->output = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketPassConnector_Free (PacketPassConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output) -{ - ASSERT(!o->output) - ASSERT(PacketPassInterface_GetMTU(output) >= o->input_mtu) - DebugObject_Access(&o->d_obj); - - // set output - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // if we have an input packet, schedule send - if (o->in_len >= 0) { - PacketPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -void PacketPassConnector_DisconnectOutput (PacketPassConnector *o) -{ - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // set no output - o->output = NULL; -} diff --git a/v2rayng/badvpn/flow/PacketPassConnector.h b/v2rayng/badvpn/flow/PacketPassConnector.h deleted file mode 100644 index 1a2cc6c750..0000000000 --- a/v2rayng/badvpn/flow/PacketPassConnector.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file PacketPassConnector.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_PACKETPASSCONNECTOR_H -#define BADVPN_FLOW_PACKETPASSCONNECTOR_H - -#include - -#include -#include - -/** - * A {@link PacketPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ -typedef struct { - PacketPassInterface input; - int input_mtu; - int in_len; - uint8_t *in; - PacketPassInterface *output; - DebugObject d_obj; -} PacketPassConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param mtu maximum input packet size. Must be >=0. - * @param pg pending group - */ -void PacketPassConnector_Init (PacketPassConnector *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassConnector_Free (PacketPassConnector *o); - -/** - * Returns the input interface. - * The MTU of the interface will be as in {@link PacketPassConnector_Init}. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassConnector_GetInput (PacketPassConnector *o); - -/** - * Connects output. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output output to connect. Its MTU must be >= MTU specified in - * {@link PacketPassConnector_Init}. - */ -void PacketPassConnector_ConnectOutput (PacketPassConnector *o, PacketPassInterface *output); - -/** - * Disconnects output. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void PacketPassConnector_DisconnectOutput (PacketPassConnector *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassFairQueue.c b/v2rayng/badvpn/flow/PacketPassFairQueue.c deleted file mode 100644 index bbfafe06b6..0000000000 --- a/v2rayng/badvpn/flow/PacketPassFairQueue.c +++ /dev/null @@ -1,405 +0,0 @@ -/** - * @file PacketPassFairQueue.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include - -#include - -static int compare_flows (PacketPassFairQueueFlow *f1, PacketPassFairQueueFlow *f2) -{ - int cmp = B_COMPARE(f1->time, f2->time); - if (cmp) { - return cmp; - } - - return B_COMPARE((uintptr_t)f1, (uintptr_t)f2); -} - -#include "PacketPassFairQueue_tree.h" -#include - -static uint64_t get_current_time (PacketPassFairQueue *m) -{ - if (m->sending_flow) { - return m->sending_flow->time; - } - - uint64_t time = 0; // to remove warning - int have = 0; - - PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - if (first_flow) { - ASSERT(first_flow->is_queued) - - time = first_flow->time; - have = 1; - } - - if (m->previous_flow) { - if (!have || m->previous_flow->time < time) { - time = m->previous_flow->time; - have = 1; - } - } - - return (have ? time : 0); -} - -static void increment_sent_flow (PacketPassFairQueueFlow *flow, uint64_t amount) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(amount <= FAIRQUEUE_MAX_TIME) - ASSERT(!flow->is_queued) - ASSERT(!m->sending_flow) - - // does time overflow? - if (amount > FAIRQUEUE_MAX_TIME - flow->time) { - // get time to subtract - uint64_t subtract; - PacketPassFairQueueFlow *first_flow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - if (!first_flow) { - subtract = flow->time; - } else { - ASSERT(first_flow->is_queued) - subtract = first_flow->time; - } - - // subtract time from all flows - for (LinkedList1Node *list_node = LinkedList1_GetFirst(&m->flows_list); list_node; list_node = LinkedList1Node_Next(list_node)) { - PacketPassFairQueueFlow *someflow = UPPER_OBJECT(list_node, PacketPassFairQueueFlow, list_node); - - // don't subtract more time than there is, except for the just finished flow, - // where we allow time to underflow and then overflow to the correct value after adding to it - if (subtract > someflow->time && someflow != flow) { - ASSERT(!someflow->is_queued) - someflow->time = 0; - } else { - someflow->time -= subtract; - } - } - } - - // add time to flow - flow->time += amount; -} - -static void schedule (PacketPassFairQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->previous_flow) - ASSERT(!m->freeing) - ASSERT(!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) - - // get first queued flow - PacketPassFairQueueFlow *qflow = PacketPassFairQueue__Tree_GetFirst(&m->queued_tree, 0); - ASSERT(qflow->is_queued) - - // remove flow from queue - PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, qflow); - qflow->is_queued = 0; - - // schedule send - PacketPassInterface_Sender_Send(m->output, qflow->queued.data, qflow->queued.data_len); - m->sending_flow = qflow; - m->sending_len = qflow->queued.data_len; -} - -static void schedule_job_handler (PacketPassFairQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // remove previous flow - m->previous_flow = NULL; - - if (!PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) { - schedule(m); - } -} - -static void input_handler_send (PacketPassFairQueueFlow *flow, uint8_t *data, int data_len) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(flow != m->sending_flow) - ASSERT(!flow->is_queued) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - if (flow == m->previous_flow) { - // remove from previous flow - m->previous_flow = NULL; - } else { - // raise time - flow->time = bmax_uint64(flow->time, get_current_time(m)); - } - - // queue flow - flow->queued.data = data; - flow->queued.data_len = data_len; - int res = PacketPassFairQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL); - ASSERT_EXECUTE(res) - flow->is_queued = 1; - - if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) { - schedule(m); - } -} - -static void output_handler_done (PacketPassFairQueue *m) -{ - ASSERT(m->sending_flow) - ASSERT(!m->previous_flow) - ASSERT(!BPending_IsSet(&m->schedule_job)) - ASSERT(!m->freeing) - ASSERT(!m->sending_flow->is_queued) - - PacketPassFairQueueFlow *flow = m->sending_flow; - - // sending finished - m->sending_flow = NULL; - - // remember this flow so the schedule job can remove its time if it didn's send - m->previous_flow = flow; - - // update flow time by packet size - increment_sent_flow(flow, (uint64_t)m->packet_weight + m->sending_len); - - // schedule schedule - BPending_Set(&m->schedule_job); - - // finish flow packet - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassFairQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) -{ - ASSERT(packet_weight > 0) - ASSERT(use_cancel == 0 || use_cancel == 1) - ASSERT(!use_cancel || PacketPassInterface_HasCancel(output)) - - // init arguments - m->output = output; - m->pg = pg; - m->use_cancel = use_cancel; - m->packet_weight = packet_weight; - - // make sure that (output MTU + packet_weight <= FAIRQUEUE_MAX_TIME) - if (!( - (PacketPassInterface_GetMTU(output) <= FAIRQUEUE_MAX_TIME) && - (packet_weight <= FAIRQUEUE_MAX_TIME - PacketPassInterface_GetMTU(output)) - )) { - goto fail0; - } - - // init output - PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m); - - // not sending - m->sending_flow = NULL; - - // no previous flow - m->previous_flow = NULL; - - // init queued tree - PacketPassFairQueue__Tree_Init(&m->queued_tree); - - // init flows list - LinkedList1_Init(&m->flows_list); - - // not freeing - m->freeing = 0; - - // init schedule job - BPending_Init(&m->schedule_job, m->pg, (BPending_handler)schedule_job_handler, m); - - DebugObject_Init(&m->d_obj); - DebugCounter_Init(&m->d_ctr); - return 1; - -fail0: - return 0; -} - -void PacketPassFairQueue_Free (PacketPassFairQueue *m) -{ - ASSERT(LinkedList1_IsEmpty(&m->flows_list)) - ASSERT(PacketPassFairQueue__Tree_IsEmpty(&m->queued_tree)) - ASSERT(!m->previous_flow) - ASSERT(!m->sending_flow) - DebugCounter_Free(&m->d_ctr); - DebugObject_Free(&m->d_obj); - - // free schedule job - BPending_Free(&m->schedule_job); -} - -void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m) -{ - DebugObject_Access(&m->d_obj); - - // set freeing - m->freeing = 1; -} - -int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m) -{ - DebugObject_Access(&m->d_obj); - - return PacketPassInterface_GetMTU(m->output); -} - -void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m) -{ - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // init arguments - flow->m = m; - - // have no canfree handler - flow->handler_busy = NULL; - - // init input - PacketPassInterface_Init(&flow->input, PacketPassInterface_GetMTU(flow->m->output), (PacketPassInterface_handler_send)input_handler_send, flow, m->pg); - - // set time - flow->time = 0; - - // add to flows list - LinkedList1_Append(&m->flows_list, &flow->list_node); - - // is not queued - flow->is_queued = 0; - - DebugObject_Init(&flow->d_obj); - DebugCounter_Increment(&m->d_ctr); -} - -void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(m->freeing || flow != m->sending_flow) - DebugCounter_Decrement(&m->d_ctr); - DebugObject_Free(&flow->d_obj); - - // remove from current flow - if (flow == m->sending_flow) { - m->sending_flow = NULL; - } - - // remove from previous flow - if (flow == m->previous_flow) { - m->previous_flow = NULL; - } - - // remove from queue - if (flow->is_queued) { - PacketPassFairQueue__Tree_Remove(&m->queued_tree, 0, flow); - } - - // remove from flows list - LinkedList1_Remove(&m->flows_list, &flow->list_node); - - // free input - PacketPassInterface_Free(&flow->input); -} - -void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - B_USE(m) - - ASSERT(m->freeing || flow != m->sending_flow) - DebugObject_Access(&flow->d_obj); -} - -int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - return (flow == m->sending_flow); -} - -void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow) -{ - PacketPassFairQueue *m = flow->m; - - ASSERT(flow == m->sending_flow) - ASSERT(m->use_cancel) - ASSERT(!m->freeing) - ASSERT(!BPending_IsSet(&m->schedule_job)) - DebugObject_Access(&flow->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(m->output); -} - -void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user) -{ - PacketPassFairQueue *m = flow->m; - B_USE(m) - - ASSERT(flow == m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // set handler - flow->handler_busy = handler; - flow->user = user; -} - -PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow) -{ - DebugObject_Access(&flow->d_obj); - - return &flow->input; -} diff --git a/v2rayng/badvpn/flow/PacketPassFairQueue.h b/v2rayng/badvpn/flow/PacketPassFairQueue.h deleted file mode 100644 index f84659649b..0000000000 --- a/v2rayng/badvpn/flow/PacketPassFairQueue.h +++ /dev/null @@ -1,204 +0,0 @@ -/** - * @file PacketPassFairQueue.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Fair queue using {@link PacketPassInterface}. - */ - -#ifndef BADVPN_FLOW_PACKETPASSFAIRQUEUE_H -#define BADVPN_FLOW_PACKETPASSFAIRQUEUE_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -// reduce this to test time overflow handling -#define FAIRQUEUE_MAX_TIME UINT64_MAX - -typedef void (*PacketPassFairQueue_handler_busy) (void *user); - -struct PacketPassFairQueueFlow_s; - -#include "PacketPassFairQueue_tree.h" -#include - -typedef struct PacketPassFairQueueFlow_s { - struct PacketPassFairQueue_s *m; - PacketPassFairQueue_handler_busy handler_busy; - void *user; - PacketPassInterface input; - uint64_t time; - LinkedList1Node list_node; - int is_queued; - struct { - PacketPassFairQueue__TreeNode tree_node; - uint8_t *data; - int data_len; - } queued; - DebugObject d_obj; -} PacketPassFairQueueFlow; - -/** - * Fair queue using {@link PacketPassInterface}. - */ -typedef struct PacketPassFairQueue_s { - PacketPassInterface *output; - BPendingGroup *pg; - int use_cancel; - int packet_weight; - struct PacketPassFairQueueFlow_s *sending_flow; - int sending_len; - struct PacketPassFairQueueFlow_s *previous_flow; - PacketPassFairQueue__Tree queued_tree; - LinkedList1 flows_list; - int freeing; - BPending schedule_job; - DebugObject d_obj; - DebugCounter d_ctr; -} PacketPassFairQueue; - -/** - * Initializes the queue. - * - * @param m the object - * @param output output interface - * @param pg pending group - * @param use_cancel whether cancel functionality is required. Must be 0 or 1. - * If 1, output must support cancel functionality. - * @param packet_weight additional weight a packet bears. Must be >0, to keep - * the queue fair for zero size packets. - * @return 1 on success, 0 on failure (because output MTU is too large) - */ -int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) WARN_UNUSED; - -/** - * Frees the queue. - * All flows must have been freed. - * - * @param m the object - */ -void PacketPassFairQueue_Free (PacketPassFairQueue *m); - -/** - * Prepares for freeing the entire queue. Must be called to allow freeing - * the flows in the process of freeing the entire queue. - * After this function is called, flows and the queue must be freed - * before any further I/O. - * May be called multiple times. - * The queue enters freeing state. - * - * @param m the object - */ -void PacketPassFairQueue_PrepareFree (PacketPassFairQueue *m); - -/** - * Returns the MTU of the queue. - * - * @param m the object - */ -int PacketPassFairQueue_GetMTU (PacketPassFairQueue *m); - -/** - * Initializes a queue flow. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param m queue to attach to - */ -void PacketPassFairQueueFlow_Init (PacketPassFairQueueFlow *flow, PacketPassFairQueue *m); - -/** - * Frees a queue flow. - * Unless the queue is in freeing state: - * - The flow must not be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * - Must not be called from queue calls to output. - * - * @param flow the object - */ -void PacketPassFairQueueFlow_Free (PacketPassFairQueueFlow *flow); - -/** - * Does nothing. - * It must be possible to free the flow (see {@link PacketPassFairQueueFlow_Free}). - * - * @param flow the object - */ -void PacketPassFairQueueFlow_AssertFree (PacketPassFairQueueFlow *flow); - -/** - * Determines if the flow is busy. If the flow is considered busy, it must not - * be freed. At any given time, at most one flow will be indicated as busy. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @return 0 if not busy, 1 is busy - */ -int PacketPassFairQueueFlow_IsBusy (PacketPassFairQueueFlow *flow); - -/** - * Requests the output to stop processing the current packet as soon as possible. - * Cancel functionality must be enabled for the queue. - * The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * - * @param flow the object - */ -void PacketPassFairQueueFlow_RequestCancel (PacketPassFairQueueFlow *flow); - -/** - * Sets up a callback to be called when the flow is no longer busy. - * The handler will be called as soon as the flow is no longer busy, i.e. it is not - * possible that this flow is no longer busy before the handler is called. - * The flow must be busy as indicated by {@link PacketPassFairQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param handler callback function. NULL to disable. - * @param user value passed to callback function. Ignored if handler is NULL. - */ -void PacketPassFairQueueFlow_SetBusyHandler (PacketPassFairQueueFlow *flow, PacketPassFairQueue_handler_busy handler, void *user); - -/** - * Returns the input interface of the flow. - * - * @param flow the object - * @return input interface - */ -PacketPassInterface * PacketPassFairQueueFlow_GetInput (PacketPassFairQueueFlow *flow); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassFairQueue_tree.h b/v2rayng/badvpn/flow/PacketPassFairQueue_tree.h deleted file mode 100644 index 5dd0a7d41d..0000000000 --- a/v2rayng/badvpn/flow/PacketPassFairQueue_tree.h +++ /dev/null @@ -1,7 +0,0 @@ -#define SAVL_PARAM_NAME PacketPassFairQueue__Tree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct PacketPassFairQueueFlow_s -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2)) -#define SAVL_PARAM_MEMBER_NODE queued.tree_node diff --git a/v2rayng/badvpn/flow/PacketPassFifoQueue.c b/v2rayng/badvpn/flow/PacketPassFifoQueue.c deleted file mode 100644 index 0395006533..0000000000 --- a/v2rayng/badvpn/flow/PacketPassFifoQueue.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * @file PacketPassFifoQueue.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "PacketPassFifoQueue.h" - -static void schedule (PacketPassFifoQueue *o) -{ - ASSERT(!o->freeing) - ASSERT(!o->sending_flow) - ASSERT(!LinkedList1_IsEmpty(&o->waiting_flows_list)) - ASSERT(!BPending_IsSet(&o->schedule_job)) - - // get first waiting flow - PacketPassFifoQueueFlow *flow = UPPER_OBJECT(LinkedList1_GetFirst(&o->waiting_flows_list), PacketPassFifoQueueFlow, waiting_flows_list_node); - ASSERT(flow->queue == o) - ASSERT(flow->is_waiting) - - // remove it from queue - LinkedList1_Remove(&o->waiting_flows_list, &flow->waiting_flows_list_node); - flow->is_waiting = 0; - - // send - PacketPassInterface_Sender_Send(o->output, flow->waiting_data, flow->waiting_len); - o->sending_flow = flow; -} - -static void schedule_job_handler (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(!o->freeing) - ASSERT(!o->sending_flow) - - if (!LinkedList1_IsEmpty(&o->waiting_flows_list)) { - schedule(o); - } -} - -static void input_handler_send (PacketPassFifoQueueFlow *o, uint8_t *data, int data_len) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Access(&o->d_obj); - ASSERT(!o->is_waiting) - ASSERT(o != queue->sending_flow) - ASSERT(!queue->freeing) - - // queue flow - o->waiting_data = data; - o->waiting_len = data_len; - LinkedList1_Append(&queue->waiting_flows_list, &o->waiting_flows_list_node); - o->is_waiting = 1; - - // schedule - if (!queue->sending_flow && !BPending_IsSet(&queue->schedule_job)) { - schedule(queue); - } -} - -static void output_handler_done (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - ASSERT(o->sending_flow) - ASSERT(!BPending_IsSet(&o->schedule_job)) - ASSERT(!o->freeing) - ASSERT(!o->sending_flow->is_waiting) - - PacketPassFifoQueueFlow *flow = o->sending_flow; - - // set no sending flow - o->sending_flow = NULL; - - // schedule schedule job - BPending_Set(&o->schedule_job); - - // done input - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassFifoQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -void PacketPassFifoQueue_Init (PacketPassFifoQueue *o, PacketPassInterface *output, BPendingGroup *pg) -{ - // init arguments - o->output = output; - o->pg = pg; - - // init output - PacketPassInterface_Sender_Init(output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init waiting flows list - LinkedList1_Init(&o->waiting_flows_list); - - // set no sending flow - o->sending_flow = NULL; - - // init schedule job - BPending_Init(&o->schedule_job, pg, (BPending_handler)schedule_job_handler, o); - - // set not freeing - o->freeing = 0; - - DebugCounter_Init(&o->d_flows_ctr); - DebugObject_Init(&o->d_obj); -} - -void PacketPassFifoQueue_Free (PacketPassFifoQueue *o) -{ - DebugObject_Free(&o->d_obj); - DebugCounter_Free(&o->d_flows_ctr); - ASSERT(LinkedList1_IsEmpty(&o->waiting_flows_list)) - ASSERT(!o->sending_flow) - - // free schedule job - BPending_Free(&o->schedule_job); -} - -void PacketPassFifoQueue_PrepareFree (PacketPassFifoQueue *o) -{ - DebugObject_Access(&o->d_obj); - - // set freeing - o->freeing = 1; -} - -void PacketPassFifoQueueFlow_Init (PacketPassFifoQueueFlow *o, PacketPassFifoQueue *queue) -{ - DebugObject_Access(&queue->d_obj); - ASSERT(!queue->freeing) - - // init arguments - o->queue = queue; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(queue->output), (PacketPassInterface_handler_send)input_handler_send, o, queue->pg); - - // set not waiting - o->is_waiting = 0; - - // set no busy handler - o->handler_busy = NULL; - - DebugCounter_Increment(&queue->d_flows_ctr); - DebugObject_Init(&o->d_obj); -} - -void PacketPassFifoQueueFlow_Free (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Free(&o->d_obj); - DebugCounter_Decrement(&queue->d_flows_ctr); - ASSERT(queue->freeing || o != queue->sending_flow) - - // remove from sending flow - if (o == queue->sending_flow) { - queue->sending_flow = NULL; - } - - // remove from waiting flows list - if (o->is_waiting) { - LinkedList1_Remove(&queue->waiting_flows_list, &o->waiting_flows_list_node); - } - - // free input - PacketPassInterface_Free(&o->input); -} - -void PacketPassFifoQueueFlow_AssertFree (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - B_USE(queue) - DebugObject_Access(&o->d_obj); - ASSERT(queue->freeing || o != queue->sending_flow) -} - -int PacketPassFifoQueueFlow_IsBusy (PacketPassFifoQueueFlow *o) -{ - PacketPassFifoQueue *queue = o->queue; - DebugObject_Access(&o->d_obj); - ASSERT(!queue->freeing) - - return (o == queue->sending_flow); -} - -void PacketPassFifoQueueFlow_SetBusyHandler (PacketPassFifoQueueFlow *o, PacketPassFifoQueue_handler_busy handler_busy, void *user) -{ - PacketPassFifoQueue *queue = o->queue; - B_USE(queue) - DebugObject_Access(&o->d_obj); - ASSERT(!queue->freeing) - ASSERT(o == queue->sending_flow) - - // set (or unset) busy handler - o->handler_busy = handler_busy; - o->user = user; -} - -PacketPassInterface * PacketPassFifoQueueFlow_GetInput (PacketPassFifoQueueFlow *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/v2rayng/badvpn/flow/PacketPassFifoQueue.h b/v2rayng/badvpn/flow/PacketPassFifoQueue.h deleted file mode 100644 index cefe79b646..0000000000 --- a/v2rayng/badvpn/flow/PacketPassFifoQueue.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file PacketPassFifoQueue.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_PACKETPASSFIFOQUEUE_H -#define BADVPN_PACKETPASSFIFOQUEUE_H - -#include -#include -#include -#include - -typedef void (*PacketPassFifoQueue_handler_busy) (void *user); - -struct PacketPassFifoQueueFlow_s; - -typedef struct { - PacketPassInterface *output; - BPendingGroup *pg; - LinkedList1 waiting_flows_list; - struct PacketPassFifoQueueFlow_s *sending_flow; - BPending schedule_job; - int freeing; - DebugCounter d_flows_ctr; - DebugObject d_obj; -} PacketPassFifoQueue; - -typedef struct PacketPassFifoQueueFlow_s { - PacketPassFifoQueue *queue; - PacketPassInterface input; - int is_waiting; - LinkedList1Node waiting_flows_list_node; - uint8_t *waiting_data; - int waiting_len; - PacketPassFifoQueue_handler_busy handler_busy; - void *user; - DebugObject d_obj; -} PacketPassFifoQueueFlow; - -void PacketPassFifoQueue_Init (PacketPassFifoQueue *o, PacketPassInterface *output, BPendingGroup *pg); -void PacketPassFifoQueue_Free (PacketPassFifoQueue *o); -void PacketPassFifoQueue_PrepareFree (PacketPassFifoQueue *o); - -void PacketPassFifoQueueFlow_Init (PacketPassFifoQueueFlow *o, PacketPassFifoQueue *queue); -void PacketPassFifoQueueFlow_Free (PacketPassFifoQueueFlow *o); -void PacketPassFifoQueueFlow_AssertFree (PacketPassFifoQueueFlow *o); -int PacketPassFifoQueueFlow_IsBusy (PacketPassFifoQueueFlow *o); -void PacketPassFifoQueueFlow_SetBusyHandler (PacketPassFifoQueueFlow *o, PacketPassFifoQueue_handler_busy handler_busy, void *user); -PacketPassInterface * PacketPassFifoQueueFlow_GetInput (PacketPassFifoQueueFlow *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassInterface.c b/v2rayng/badvpn/flow/PacketPassInterface.c deleted file mode 100644 index dfa6ed5583..0000000000 --- a/v2rayng/badvpn/flow/PacketPassInterface.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file PacketPassInterface.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -void _PacketPassInterface_job_operation (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PPI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _PacketPassInterface_job_requestcancel (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_BUSY) - ASSERT(i->cancel_requested) - ASSERT(i->handler_requestcancel) - DebugObject_Access(&i->d_obj); - - // call handler - i->handler_requestcancel(i->user_provider); - return; -} - -void _PacketPassInterface_job_done (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PPI_STATE_NONE; - - // call handler - i->handler_done(i->user_user); - return; -} diff --git a/v2rayng/badvpn/flow/PacketPassInterface.h b/v2rayng/badvpn/flow/PacketPassInterface.h deleted file mode 100644 index 0cc22748e2..0000000000 --- a/v2rayng/badvpn/flow/PacketPassInterface.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * @file PacketPassInterface.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a packet sender to pass data packets to a packet receiver. - */ - -#ifndef BADVPN_FLOW_PACKETPASSINTERFACE_H -#define BADVPN_FLOW_PACKETPASSINTERFACE_H - -#include -#include - -#include -#include -#include - -#define PPI_STATE_NONE 1 -#define PPI_STATE_OPERATION_PENDING 2 -#define PPI_STATE_BUSY 3 -#define PPI_STATE_DONE_PENDING 4 - -typedef void (*PacketPassInterface_handler_send) (void *user, uint8_t *data, int data_len); - -typedef void (*PacketPassInterface_handler_requestcancel) (void *user); - -typedef void (*PacketPassInterface_handler_done) (void *user); - -typedef struct { - // provider data - int mtu; - PacketPassInterface_handler_send handler_operation; - PacketPassInterface_handler_requestcancel handler_requestcancel; - void *user_provider; - - // user data - PacketPassInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // requestcancel job - BPending job_requestcancel; - - // done job - BPending job_done; - - // state - int state; - int cancel_requested; - - DebugObject d_obj; -} PacketPassInterface; - -static void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg); - -static void PacketPassInterface_Free (PacketPassInterface *i); - -static void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel); - -static void PacketPassInterface_Done (PacketPassInterface *i); - -static int PacketPassInterface_GetMTU (PacketPassInterface *i); - -static void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user); - -static void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len); - -static void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i); - -static int PacketPassInterface_HasCancel (PacketPassInterface *i); - -void _PacketPassInterface_job_operation (PacketPassInterface *i); -void _PacketPassInterface_job_requestcancel (PacketPassInterface *i); -void _PacketPassInterface_job_done (PacketPassInterface *i); - -void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - i->mtu = mtu; - i->handler_operation = handler_operation; - i->handler_requestcancel = NULL; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketPassInterface_job_operation, i); - BPending_Init(&i->job_requestcancel, pg, (BPending_handler)_PacketPassInterface_job_requestcancel, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_PacketPassInterface_job_done, i); - - // set state - i->state = PPI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void PacketPassInterface_Free (PacketPassInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_requestcancel); - BPending_Free(&i->job_operation); -} - -void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel) -{ - ASSERT(!i->handler_requestcancel) - ASSERT(!i->handler_done) - ASSERT(handler_requestcancel) - - i->handler_requestcancel = handler_requestcancel; -} - -void PacketPassInterface_Done (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_BUSY) - DebugObject_Access(&i->d_obj); - - // unset requestcancel job - BPending_Unset(&i->job_requestcancel); - - // schedule done - BPending_Set(&i->job_done); - - // set state - i->state = PPI_STATE_DONE_PENDING; -} - -int PacketPassInterface_GetMTU (PacketPassInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return i->mtu; -} - -void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= i->mtu) - ASSERT(!(data_len > 0) || data) - ASSERT(i->state == PPI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = PPI_STATE_OPERATION_PENDING; - i->cancel_requested = 0; -} - -void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i) -{ - ASSERT(i->state == PPI_STATE_OPERATION_PENDING || i->state == PPI_STATE_BUSY || i->state == PPI_STATE_DONE_PENDING) - ASSERT(i->handler_requestcancel) - DebugObject_Access(&i->d_obj); - - // ignore multiple cancel requests - if (i->cancel_requested) { - return; - } - - // remember we requested cancel - i->cancel_requested = 1; - - if (i->state == PPI_STATE_OPERATION_PENDING) { - // unset operation job - BPending_Unset(&i->job_operation); - - // set done job - BPending_Set(&i->job_done); - - // set state - i->state = PPI_STATE_DONE_PENDING; - } else if (i->state == PPI_STATE_BUSY) { - // set requestcancel job - BPending_Set(&i->job_requestcancel); - } -} - -int PacketPassInterface_HasCancel (PacketPassInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return !!i->handler_requestcancel; -} - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassNotifier.c b/v2rayng/badvpn/flow/PacketPassNotifier.c deleted file mode 100644 index 0132746987..0000000000 --- a/v2rayng/badvpn/flow/PacketPassNotifier.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file PacketPassNotifier.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -void input_handler_send (PacketPassNotifier *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // schedule send - PacketPassInterface_Sender_Send(o->output, data, data_len); - - // if we have a handler, call it - if (o->handler) { - o->handler(o->handler_user, data, data_len); - return; - } -} - -void input_handler_requestcancel (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Sender_RequestCancel(o->output); -} - -void output_handler_done (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Done(&o->input); -} - -void PacketPassNotifier_Init (PacketPassNotifier *o, PacketPassInterface *output, BPendingGroup *pg) -{ - // init arguments - o->output = output; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, pg); - if (PacketPassInterface_HasCancel(o->output)) { - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - } - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // set no handler - o->handler = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketPassNotifier_Free (PacketPassNotifier *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassNotifier_GetInput (PacketPassNotifier *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassNotifier_SetHandler (PacketPassNotifier *o, PacketPassNotifier_handler_notify handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->handler_user = user; -} diff --git a/v2rayng/badvpn/flow/PacketPassNotifier.h b/v2rayng/badvpn/flow/PacketPassNotifier.h deleted file mode 100644 index b2fab1313b..0000000000 --- a/v2rayng/badvpn/flow/PacketPassNotifier.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file PacketPassNotifier.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer which calles a handler function before - * passing a packet from input to output. - */ - -#ifndef BADVPN_FLOW_PACKETPASSNOTIFIER_H -#define BADVPN_FLOW_PACKETPASSNOTIFIER_H - -#include - -#include -#include - -/** - * Handler function called when input calls Send, but before the call is passed on to output. - * - * @param user value specified in {@link PacketPassNotifier_SetHandler} - * @param data packet provided by input - * @param data_len size of the packet - */ -typedef void (*PacketPassNotifier_handler_notify) (void *user, uint8_t *data, int data_len); - -/** - * A {@link PacketPassInterface} layer which calles a handler function before - * passing a packet from input to output. - */ -typedef struct { - PacketPassInterface input; - PacketPassInterface *output; - PacketPassNotifier_handler_notify handler; - void *handler_user; - DebugObject d_obj; -} PacketPassNotifier; - -/** - * Initializes the object. - * - * @param o the object - * @param output output interface - * @param pg pending group - */ -void PacketPassNotifier_Init (PacketPassNotifier *o, PacketPassInterface *output, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassNotifier_Free (PacketPassNotifier *o); - -/** - * Returns the input interface. - * The MTU of the interface will be the same as of the output interface. - * The interface supports cancel functionality if the output interface supports it. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassNotifier_GetInput (PacketPassNotifier *o); - -/** - * Configures a handler function to call before passing input packets to output. - * - * @param o the object - * @param handler handler function, or NULL to disable. - * @param user value to pass to handler function. Ignored if handler is NULL. - */ -void PacketPassNotifier_SetHandler (PacketPassNotifier *o, PacketPassNotifier_handler_notify handler, void *user); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassPriorityQueue.c b/v2rayng/badvpn/flow/PacketPassPriorityQueue.c deleted file mode 100644 index 9534f1b1c8..0000000000 --- a/v2rayng/badvpn/flow/PacketPassPriorityQueue.c +++ /dev/null @@ -1,283 +0,0 @@ -/** - * @file PacketPassPriorityQueue.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include - -static int compare_flows (PacketPassPriorityQueueFlow *f1, PacketPassPriorityQueueFlow *f2) -{ - int cmp = B_COMPARE(f1->priority, f2->priority); - if (cmp) { - return cmp; - } - - return B_COMPARE((uintptr_t)f1, (uintptr_t)f2); -} - -#include "PacketPassPriorityQueue_tree.h" -#include - -static void schedule (PacketPassPriorityQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - ASSERT(!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) - - // get first queued flow - PacketPassPriorityQueueFlow *qflow = PacketPassPriorityQueue__Tree_GetFirst(&m->queued_tree, 0); - ASSERT(qflow->is_queued) - - // remove flow from queue - PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, qflow); - qflow->is_queued = 0; - - // schedule send - PacketPassInterface_Sender_Send(m->output, qflow->queued.data, qflow->queued.data_len); - m->sending_flow = qflow; -} - -static void schedule_job_handler (PacketPassPriorityQueue *m) -{ - ASSERT(!m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - if (!PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) { - schedule(m); - } -} - -static void input_handler_send (PacketPassPriorityQueueFlow *flow, uint8_t *data, int data_len) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(flow != m->sending_flow) - ASSERT(!flow->is_queued) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // queue flow - flow->queued.data = data; - flow->queued.data_len = data_len; - int res = PacketPassPriorityQueue__Tree_Insert(&m->queued_tree, 0, flow, NULL); - ASSERT_EXECUTE(res) - flow->is_queued = 1; - - if (!m->sending_flow && !BPending_IsSet(&m->schedule_job)) { - schedule(m); - } -} - -static void output_handler_done (PacketPassPriorityQueue *m) -{ - ASSERT(m->sending_flow) - ASSERT(!BPending_IsSet(&m->schedule_job)) - ASSERT(!m->freeing) - ASSERT(!m->sending_flow->is_queued) - - PacketPassPriorityQueueFlow *flow = m->sending_flow; - - // sending finished - m->sending_flow = NULL; - - // schedule schedule - BPending_Set(&m->schedule_job); - - // finish flow packet - PacketPassInterface_Done(&flow->input); - - // call busy handler if set - if (flow->handler_busy) { - // handler is one-shot, unset it before calling - PacketPassPriorityQueue_handler_busy handler = flow->handler_busy; - flow->handler_busy = NULL; - - // call handler - handler(flow->user); - return; - } -} - -void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel) -{ - ASSERT(use_cancel == 0 || use_cancel == 1) - ASSERT(!use_cancel || PacketPassInterface_HasCancel(output)) - - // init arguments - m->output = output; - m->pg = pg; - m->use_cancel = use_cancel; - - // init output - PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m); - - // not sending - m->sending_flow = NULL; - - // init queued tree - PacketPassPriorityQueue__Tree_Init(&m->queued_tree); - - // not freeing - m->freeing = 0; - - // init schedule job - BPending_Init(&m->schedule_job, m->pg, (BPending_handler)schedule_job_handler, m); - - DebugObject_Init(&m->d_obj); - DebugCounter_Init(&m->d_ctr); -} - -void PacketPassPriorityQueue_Free (PacketPassPriorityQueue *m) -{ - ASSERT(PacketPassPriorityQueue__Tree_IsEmpty(&m->queued_tree)) - ASSERT(!m->sending_flow) - DebugCounter_Free(&m->d_ctr); - DebugObject_Free(&m->d_obj); - - // free schedule job - BPending_Free(&m->schedule_job); -} - -void PacketPassPriorityQueue_PrepareFree (PacketPassPriorityQueue *m) -{ - DebugObject_Access(&m->d_obj); - - // set freeing - m->freeing = 1; -} - -int PacketPassPriorityQueue_GetMTU (PacketPassPriorityQueue *m) -{ - DebugObject_Access(&m->d_obj); - - return PacketPassInterface_GetMTU(m->output); -} - -void PacketPassPriorityQueueFlow_Init (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue *m, int priority) -{ - ASSERT(!m->freeing) - DebugObject_Access(&m->d_obj); - - // init arguments - flow->m = m; - flow->priority = priority; - - // have no canfree handler - flow->handler_busy = NULL; - - // init input - PacketPassInterface_Init(&flow->input, PacketPassInterface_GetMTU(flow->m->output), (PacketPassInterface_handler_send)input_handler_send, flow, m->pg); - - // is not queued - flow->is_queued = 0; - - DebugObject_Init(&flow->d_obj); - DebugCounter_Increment(&m->d_ctr); -} - -void PacketPassPriorityQueueFlow_Free (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(m->freeing || flow != m->sending_flow) - DebugCounter_Decrement(&m->d_ctr); - DebugObject_Free(&flow->d_obj); - - // remove from current flow - if (flow == m->sending_flow) { - m->sending_flow = NULL; - } - - // remove from queue - if (flow->is_queued) { - PacketPassPriorityQueue__Tree_Remove(&m->queued_tree, 0, flow); - } - - // free input - PacketPassInterface_Free(&flow->input); -} - -void PacketPassPriorityQueueFlow_AssertFree (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - B_USE(m) - - ASSERT(m->freeing || flow != m->sending_flow) - DebugObject_Access(&flow->d_obj); -} - -int PacketPassPriorityQueueFlow_IsBusy (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - return (flow == m->sending_flow); -} - -void PacketPassPriorityQueueFlow_RequestCancel (PacketPassPriorityQueueFlow *flow) -{ - PacketPassPriorityQueue *m = flow->m; - - ASSERT(flow == m->sending_flow) - ASSERT(m->use_cancel) - ASSERT(!m->freeing) - ASSERT(!BPending_IsSet(&m->schedule_job)) - DebugObject_Access(&flow->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(m->output); -} - -void PacketPassPriorityQueueFlow_SetBusyHandler (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue_handler_busy handler, void *user) -{ - PacketPassPriorityQueue *m = flow->m; - B_USE(m) - - ASSERT(flow == m->sending_flow) - ASSERT(!m->freeing) - DebugObject_Access(&flow->d_obj); - - // set handler - flow->handler_busy = handler; - flow->user = user; -} - -PacketPassInterface * PacketPassPriorityQueueFlow_GetInput (PacketPassPriorityQueueFlow *flow) -{ - DebugObject_Access(&flow->d_obj); - - return &flow->input; -} diff --git a/v2rayng/badvpn/flow/PacketPassPriorityQueue.h b/v2rayng/badvpn/flow/PacketPassPriorityQueue.h deleted file mode 100644 index 3ac78eb537..0000000000 --- a/v2rayng/badvpn/flow/PacketPassPriorityQueue.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file PacketPassPriorityQueue.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Priority queue using {@link PacketPassInterface}. - */ - -#ifndef BADVPN_FLOW_PACKETPASSPRIORITYQUEUE_H -#define BADVPN_FLOW_PACKETPASSPRIORITYQUEUE_H - -#include - -#include -#include -#include -#include -#include - -typedef void (*PacketPassPriorityQueue_handler_busy) (void *user); - -struct PacketPassPriorityQueueFlow_s; - -#include "PacketPassPriorityQueue_tree.h" -#include - -typedef struct PacketPassPriorityQueueFlow_s { - struct PacketPassPriorityQueue_s *m; - int priority; - PacketPassPriorityQueue_handler_busy handler_busy; - void *user; - PacketPassInterface input; - int is_queued; - struct { - PacketPassPriorityQueue__TreeNode tree_node; - uint8_t *data; - int data_len; - } queued; - DebugObject d_obj; -} PacketPassPriorityQueueFlow; - -/** - * Priority queue using {@link PacketPassInterface}. - */ -typedef struct PacketPassPriorityQueue_s { - PacketPassInterface *output; - BPendingGroup *pg; - int use_cancel; - struct PacketPassPriorityQueueFlow_s *sending_flow; - PacketPassPriorityQueue__Tree queued_tree; - int freeing; - BPending schedule_job; - DebugObject d_obj; - DebugCounter d_ctr; -} PacketPassPriorityQueue; - -/** - * Initializes the queue. - * - * @param m the object - * @param output output interface - * @param pg pending group - * @param use_cancel whether cancel functionality is required. Must be 0 or 1. - * If 1, output must support cancel functionality. - */ -void PacketPassPriorityQueue_Init (PacketPassPriorityQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel); - -/** - * Frees the queue. - * All flows must have been freed. - * - * @param m the object - */ -void PacketPassPriorityQueue_Free (PacketPassPriorityQueue *m); - -/** - * Prepares for freeing the entire queue. Must be called to allow freeing - * the flows in the process of freeing the entire queue. - * After this function is called, flows and the queue must be freed - * before any further I/O. - * May be called multiple times. - * The queue enters freeing state. - * - * @param m the object - */ -void PacketPassPriorityQueue_PrepareFree (PacketPassPriorityQueue *m); - -/** - * Returns the MTU of the queue. - * - * @param m the object - */ -int PacketPassPriorityQueue_GetMTU (PacketPassPriorityQueue *m); - -/** - * Initializes a queue flow. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param m queue to attach to - * @param priority flow priority. Lower value means higher priority. - */ -void PacketPassPriorityQueueFlow_Init (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue *m, int priority); - -/** - * Frees a queue flow. - * Unless the queue is in freeing state: - * - The flow must not be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * - Must not be called from queue calls to output. - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_Free (PacketPassPriorityQueueFlow *flow); - -/** - * Does nothing. - * It must be possible to free the flow (see {@link PacketPassPriorityQueueFlow}). - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_AssertFree (PacketPassPriorityQueueFlow *flow); - -/** - * Determines if the flow is busy. If the flow is considered busy, it must not - * be freed. At any given time, at most one flow will be indicated as busy. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @return 0 if not busy, 1 is busy - */ -int PacketPassPriorityQueueFlow_IsBusy (PacketPassPriorityQueueFlow *flow); - -/** - * Requests the output to stop processing the current packet as soon as possible. - * Cancel functionality must be enabled for the queue. - * The flow must be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * - * @param flow the object - */ -void PacketPassPriorityQueueFlow_RequestCancel (PacketPassPriorityQueueFlow *flow); - -/** - * Sets up a callback to be called when the flow is no longer busy. - * The handler will be called as soon as the flow is no longer busy, i.e. it is not - * possible that this flow is no longer busy before the handler is called. - * The flow must be busy as indicated by {@link PacketPassPriorityQueueFlow_IsBusy}. - * Queue must not be in freeing state. - * Must not be called from queue calls to output. - * - * @param flow the object - * @param handler callback function. NULL to disable. - * @param user value passed to callback function. Ignored if handler is NULL. - */ -void PacketPassPriorityQueueFlow_SetBusyHandler (PacketPassPriorityQueueFlow *flow, PacketPassPriorityQueue_handler_busy handler, void *user); - -/** - * Returns the input interface of the flow. - * - * @param flow the object - * @return input interface - */ -PacketPassInterface * PacketPassPriorityQueueFlow_GetInput (PacketPassPriorityQueueFlow *flow); - -#endif diff --git a/v2rayng/badvpn/flow/PacketPassPriorityQueue_tree.h b/v2rayng/badvpn/flow/PacketPassPriorityQueue_tree.h deleted file mode 100644 index 0d8b2133fe..0000000000 --- a/v2rayng/badvpn/flow/PacketPassPriorityQueue_tree.h +++ /dev/null @@ -1,7 +0,0 @@ -#define SAVL_PARAM_NAME PacketPassPriorityQueue__Tree -#define SAVL_PARAM_FEATURE_COUNTS 0 -#define SAVL_PARAM_FEATURE_NOKEYS 1 -#define SAVL_PARAM_TYPE_ENTRY struct PacketPassPriorityQueueFlow_s -#define SAVL_PARAM_TYPE_ARG int -#define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_flows((entry1), (entry2)) -#define SAVL_PARAM_MEMBER_NODE queued.tree_node diff --git a/v2rayng/badvpn/flow/PacketProtoDecoder.c b/v2rayng/badvpn/flow/PacketProtoDecoder.c deleted file mode 100644 index 68d26c5b2d..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoDecoder.c +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file PacketProtoDecoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include - -#include - -#include - -static void process_data (PacketProtoDecoder *enc); -static void input_handler_done (PacketProtoDecoder *enc, int data_len); -static void output_handler_done (PacketProtoDecoder *enc); - -void process_data (PacketProtoDecoder *enc) -{ - int was_error = 0; - - do { - uint8_t *data = enc->buf + enc->buf_start; - int left = enc->buf_used; - - // check if header was received - if (left < sizeof(struct packetproto_header)) { - break; - } - struct packetproto_header header; - memcpy(&header, data, sizeof(header)); - data += sizeof(struct packetproto_header); - left -= sizeof(struct packetproto_header); - int data_len = ltoh16(header.len); - - // check data length - if (data_len > enc->output_mtu) { - BLog(BLOG_NOTICE, "error: packet too large"); - was_error = 1; - break; - } - - // check if whole packet was received - if (left < data_len) { - break; - } - - // update buffer - enc->buf_start += sizeof(struct packetproto_header) + data_len; - enc->buf_used -= sizeof(struct packetproto_header) + data_len; - - // submit packet - PacketPassInterface_Sender_Send(enc->output, data, data_len); - return; - } while (0); - - if (was_error) { - // reset buffer - enc->buf_start = 0; - enc->buf_used = 0; - } else { - // if we reached the end of the buffer, wrap around to allow more data to be received - if (enc->buf_start + enc->buf_used == enc->buf_size) { - memmove(enc->buf, enc->buf + enc->buf_start, enc->buf_used); - enc->buf_start = 0; - } - } - - // receive data - StreamRecvInterface_Receiver_Recv(enc->input, enc->buf + (enc->buf_start + enc->buf_used), enc->buf_size - (enc->buf_start + enc->buf_used)); - - // if we had error, report it - if (was_error) { - enc->handler_error(enc->user); - return; - } -} - -static void input_handler_done (PacketProtoDecoder *enc, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= enc->buf_size - (enc->buf_start + enc->buf_used)) - DebugObject_Access(&enc->d_obj); - - // update buffer - enc->buf_used += data_len; - - // process data - process_data(enc); - return; -} - -void output_handler_done (PacketProtoDecoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - // process data - process_data(enc); - return; -} - -int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) -{ - // init arguments - enc->input = input; - enc->output = output; - enc->user = user; - enc->handler_error = handler_error; - - // init input - StreamRecvInterface_Receiver_Init(enc->input, (StreamRecvInterface_handler_done)input_handler_done, enc); - - // init output - PacketPassInterface_Sender_Init(enc->output, (PacketPassInterface_handler_done)output_handler_done, enc); - - // set output MTU, limit by maximum payload size - enc->output_mtu = bmin_int(PacketPassInterface_GetMTU(enc->output), PACKETPROTO_MAXPAYLOAD); - - // init buffer state - enc->buf_size = PACKETPROTO_ENCLEN(enc->output_mtu); - enc->buf_start = 0; - enc->buf_used = 0; - - // allocate buffer - if (!(enc->buf = (uint8_t *)malloc(enc->buf_size))) { - goto fail0; - } - - // start receiving - StreamRecvInterface_Receiver_Recv(enc->input, enc->buf, enc->buf_size); - - DebugObject_Init(&enc->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketProtoDecoder_Free (PacketProtoDecoder *enc) -{ - DebugObject_Free(&enc->d_obj); - - // free buffer - free(enc->buf); -} - -void PacketProtoDecoder_Reset (PacketProtoDecoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - enc->buf_start += enc->buf_used; - enc->buf_used = 0; -} diff --git a/v2rayng/badvpn/flow/PacketProtoDecoder.h b/v2rayng/badvpn/flow/PacketProtoDecoder.h deleted file mode 100644 index 2c20694bcd..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoDecoder.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file PacketProtoDecoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which decodes a stream according to PacketProto. - */ - -#ifndef BADVPN_FLOW_PACKETPROTODECODER_H -#define BADVPN_FLOW_PACKETPROTODECODER_H - -#include - -#include -#include -#include -#include -#include - -/** - * Handler called when a protocol error occurs. - * When an error occurs, the decoder is reset to the initial state. - * - * @param user as in {@link PacketProtoDecoder_Init} - */ -typedef void (*PacketProtoDecoder_handler_error) (void *user); - -typedef struct { - StreamRecvInterface *input; - PacketPassInterface *output; - void *user; - PacketProtoDecoder_handler_error handler_error; - int output_mtu; - int buf_size; - int buf_start; - int buf_used; - uint8_t *buf; - DebugObject d_obj; -} PacketProtoDecoder; - -/** - * Initializes the object. - * - * @param enc the object - * @param input input interface. The decoder will accept packets with payload size up to its MTU - * (but the payload can never be more than PACKETPROTO_MAXPAYLOAD). - * @param output output interface - * @param pg pending group - * @param user argument to handlers - * @param handler_error error handler - * @return 1 on success, 0 on failure - */ -int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) WARN_UNUSED; - -/** - * Frees the object. - * - * @param enc the object - */ -void PacketProtoDecoder_Free (PacketProtoDecoder *enc); - -/** - * Clears the internal buffer. - * The next data received from the input will be treated as a new - * PacketProto stream. - * - * @param enc the object - */ -void PacketProtoDecoder_Reset (PacketProtoDecoder *enc); - -#endif diff --git a/v2rayng/badvpn/flow/PacketProtoEncoder.c b/v2rayng/badvpn/flow/PacketProtoEncoder.c deleted file mode 100644 index 00aaa9530f..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoEncoder.c +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file PacketProtoEncoder.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include - -#include - -static void output_handler_recv (PacketProtoEncoder *enc, uint8_t *data) -{ - ASSERT(!enc->output_packet) - ASSERT(data) - DebugObject_Access(&enc->d_obj); - - // schedule receive - enc->output_packet = data; - PacketRecvInterface_Receiver_Recv(enc->input, enc->output_packet + sizeof(struct packetproto_header)); -} - -static void input_handler_done (PacketProtoEncoder *enc, int in_len) -{ - ASSERT(enc->output_packet) - DebugObject_Access(&enc->d_obj); - - // write length - struct packetproto_header pp; - pp.len = htol16(in_len); - memcpy(enc->output_packet, &pp, sizeof(pp)); - - // finish output packet - enc->output_packet = NULL; - PacketRecvInterface_Done(&enc->output, PACKETPROTO_ENCLEN(in_len)); -} - -void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg) -{ - ASSERT(PacketRecvInterface_GetMTU(input) <= PACKETPROTO_MAXPAYLOAD) - - // init arguments - enc->input = input; - - // init input - PacketRecvInterface_Receiver_Init(enc->input, (PacketRecvInterface_handler_done)input_handler_done, enc); - - // init output - PacketRecvInterface_Init( - &enc->output, PACKETPROTO_ENCLEN(PacketRecvInterface_GetMTU(enc->input)), - (PacketRecvInterface_handler_recv)output_handler_recv, enc, pg - ); - - // set no output packet - enc->output_packet = NULL; - - DebugObject_Init(&enc->d_obj); -} - -void PacketProtoEncoder_Free (PacketProtoEncoder *enc) -{ - DebugObject_Free(&enc->d_obj); - - // free input - PacketRecvInterface_Free(&enc->output); -} - -PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc) -{ - DebugObject_Access(&enc->d_obj); - - return &enc->output; -} diff --git a/v2rayng/badvpn/flow/PacketProtoEncoder.h b/v2rayng/badvpn/flow/PacketProtoEncoder.h deleted file mode 100644 index 022aa008fd..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoEncoder.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file PacketProtoEncoder.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which encodes packets according to PacketProto. - */ - -#ifndef BADVPN_FLOW_PACKETPROTOENCODER_H -#define BADVPN_FLOW_PACKETPROTOENCODER_H - -#include - -#include -#include - -/** - * Object which encodes packets according to PacketProto. - * - * Input is with {@link PacketRecvInterface}. - * Output is with {@link PacketRecvInterface}. - */ -typedef struct { - PacketRecvInterface *input; - PacketRecvInterface output; - uint8_t *output_packet; - DebugObject d_obj; -} PacketProtoEncoder; - -/** - * Initializes the object. - * - * @param enc the object - * @param input input interface. Its MTU must be <=PACKETPROTO_MAXPAYLOAD. - * @param pg pending group - */ -void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param enc the object - */ -void PacketProtoEncoder_Free (PacketProtoEncoder *enc); - -/** - * Returns the output interface. - * The MTU of the output interface is PACKETPROTO_ENCLEN(MTU of input interface). - * - * @param enc the object - * @return output interface - */ -PacketRecvInterface * PacketProtoEncoder_GetOutput (PacketProtoEncoder *enc); - -#endif diff --git a/v2rayng/badvpn/flow/PacketProtoFlow.c b/v2rayng/badvpn/flow/PacketProtoFlow.c deleted file mode 100644 index 8fad8e2070..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoFlow.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file PacketProtoFlow.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include - -int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(input_mtu >= 0) - ASSERT(input_mtu <= PACKETPROTO_MAXPAYLOAD) - ASSERT(num_packets > 0) - ASSERT(PacketPassInterface_GetMTU(output) >= PACKETPROTO_ENCLEN(input_mtu)) - - // init async input - BufferWriter_Init(&o->ainput, input_mtu, pg); - - // init encoder - PacketProtoEncoder_Init(&o->encoder, BufferWriter_GetOutput(&o->ainput), pg); - - // init buffer - if (!PacketBuffer_Init(&o->buffer, PacketProtoEncoder_GetOutput(&o->encoder), output, num_packets, pg)) { - goto fail0; - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - PacketProtoEncoder_Free(&o->encoder); - BufferWriter_Free(&o->ainput); - return 0; -} - -void PacketProtoFlow_Free (PacketProtoFlow *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - PacketBuffer_Free(&o->buffer); - - // free encoder - PacketProtoEncoder_Free(&o->encoder); - - // free async input - BufferWriter_Free(&o->ainput); -} - -BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->ainput; -} diff --git a/v2rayng/badvpn/flow/PacketProtoFlow.h b/v2rayng/badvpn/flow/PacketProtoFlow.h deleted file mode 100644 index 05e123382e..0000000000 --- a/v2rayng/badvpn/flow/PacketProtoFlow.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file PacketProtoFlow.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Buffer which encodes packets with PacketProto, with {@link BufferWriter} - * input and {@link PacketPassInterface} output. - */ - -#ifndef BADVPN_FLOW_PACKETPROTOFLOW_H -#define BADVPN_FLOW_PACKETPROTOFLOW_H - -#include - -#include -#include -#include -#include - -/** - * Buffer which encodes packets with PacketProto, with {@link BufferWriter} - * input and {@link PacketPassInterface} output. - */ -typedef struct { - BufferWriter ainput; - PacketProtoEncoder encoder; - PacketBuffer buffer; - DebugObject d_obj; -} PacketProtoFlow; - -/** - * Initializes the object. - * - * @param o the object - * @param input_mtu maximum input packet size. Must be >=0 and <=PACKETPROTO_MAXPAYLOAD. - * @param num_packets minimum number of packets the buffer should hold. Must be >0. - * @param output output interface. Its MTU must be >=PACKETPROTO_ENCLEN(input_mtu). - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void PacketProtoFlow_Free (PacketProtoFlow *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -BufferWriter * PacketProtoFlow_GetInput (PacketProtoFlow *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketRecvBlocker.c b/v2rayng/badvpn/flow/PacketRecvBlocker.c deleted file mode 100644 index 7e679f8873..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvBlocker.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file PacketRecvBlocker.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -static void output_handler_recv (PacketRecvBlocker *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // remember packet - o->out_have = 1; - o->out = data; - o->out_input_blocking = 0; -} - -static void input_handler_done (PacketRecvBlocker *o, int data_len) -{ - ASSERT(o->out_have) - ASSERT(o->out_input_blocking) - DebugObject_Access(&o->d_obj); - - // schedule done - o->out_have = 0; - PacketRecvInterface_Done(&o->output, data_len); -} - -void PacketRecvBlocker_Init (PacketRecvBlocker *o, PacketRecvInterface *input, BPendingGroup *pg) -{ - // init arguments - o->input = input; - - // init output - PacketRecvInterface_Init(&o->output, PacketRecvInterface_GetMTU(o->input), (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_have = 0; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - DebugObject_Init(&o->d_obj); -} - -void PacketRecvBlocker_Free (PacketRecvBlocker *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * PacketRecvBlocker_GetOutput (PacketRecvBlocker *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void PacketRecvBlocker_AllowBlockedPacket (PacketRecvBlocker *o) -{ - DebugObject_Access(&o->d_obj); - - if (!o->out_have || o->out_input_blocking) { - return; - } - - // schedule receive - o->out_input_blocking = 1; - PacketRecvInterface_Receiver_Recv(o->input, o->out); -} diff --git a/v2rayng/badvpn/flow/PacketRecvBlocker.h b/v2rayng/badvpn/flow/PacketRecvBlocker.h deleted file mode 100644 index ba98d064ed..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvBlocker.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file PacketRecvBlocker.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link PacketRecvInterface} layer which blocks all output recv calls and only - * passes a single blocked call on to input when the user wants so. - */ - -#ifndef BADVPN_FLOW_PACKETRECVBLOCKER_H -#define BADVPN_FLOW_PACKETRECVBLOCKER_H - -#include - -#include -#include - -/** - * {@link PacketRecvInterface} layer which blocks all output recv calls and only - * passes a single blocked call on to input when the user wants so. - */ -typedef struct { - PacketRecvInterface output; - int out_have; - uint8_t *out; - int out_input_blocking; - PacketRecvInterface *input; - DebugObject d_obj; -} PacketRecvBlocker; - -/** - * Initializes the object. - * - * @param o the object - * @param input input interface - */ -void PacketRecvBlocker_Init (PacketRecvBlocker *o, PacketRecvInterface *input, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRecvBlocker_Free (PacketRecvBlocker *o); - -/** - * Returns the output interface. - * The MTU of the output interface will be the same as of the input interface. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * PacketRecvBlocker_GetOutput (PacketRecvBlocker *o); - -/** - * Passes a blocked output recv call to input if there is one and it has not - * been passed yet. Otherwise it does nothing. - * Must not be called from input Recv calls. - * This function may invoke I/O. - * - * @param o the object - */ -void PacketRecvBlocker_AllowBlockedPacket (PacketRecvBlocker *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketRecvConnector.c b/v2rayng/badvpn/flow/PacketRecvConnector.c deleted file mode 100644 index 455db23095..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvConnector.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file PacketRecvConnector.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void output_handler_recv (PacketRecvConnector *o, uint8_t *data) -{ - ASSERT(!o->out_have) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_have = 1; - o->out = data; - - if (o->input) { - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, o->out); - } -} - -static void input_handler_done (PacketRecvConnector *o, int data_len) -{ - ASSERT(o->out_have) - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // have no output packet - o->out_have = 0; - - // allow output to receive more packets - PacketRecvInterface_Done(&o->output, data_len); -} - -void PacketRecvConnector_Init (PacketRecvConnector *o, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - o->output_mtu = mtu; - - // init output - PacketRecvInterface_Init(&o->output, o->output_mtu, (PacketRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_have = 0; - - // have no input - o->input = NULL; - - DebugObject_Init(&o->d_obj); -} - -void PacketRecvConnector_Free (PacketRecvConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - PacketRecvInterface_Free(&o->output); -} - -PacketRecvInterface * PacketRecvConnector_GetOutput (PacketRecvConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void PacketRecvConnector_ConnectInput (PacketRecvConnector *o, PacketRecvInterface *input) -{ - ASSERT(!o->input) - ASSERT(PacketRecvInterface_GetMTU(input) <= o->output_mtu) - DebugObject_Access(&o->d_obj); - - // set input - o->input = input; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // if we have an output packet, schedule receive - if (o->out_have) { - PacketRecvInterface_Receiver_Recv(o->input, o->out); - } -} - -void PacketRecvConnector_DisconnectInput (PacketRecvConnector *o) -{ - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // set no input - o->input = NULL; -} diff --git a/v2rayng/badvpn/flow/PacketRecvConnector.h b/v2rayng/badvpn/flow/PacketRecvConnector.h deleted file mode 100644 index 25cf851df7..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvConnector.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file PacketRecvConnector.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_PACKETRECVCONNECTOR_H -#define BADVPN_FLOW_PACKETRECVCONNECTOR_H - -#include - -#include -#include - -/** - * A {@link PacketRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ -typedef struct { - PacketRecvInterface output; - int output_mtu; - int out_have; - uint8_t *out; - PacketRecvInterface *input; - DebugObject d_obj; -} PacketRecvConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param mtu maximum output packet size. Must be >=0. - * @param pg pending group - */ -void PacketRecvConnector_Init (PacketRecvConnector *o, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRecvConnector_Free (PacketRecvConnector *o); - -/** - * Returns the output interface. - * The MTU of the interface will be as in {@link PacketRecvConnector_Init}. - * - * @param o the object - * @return output interface - */ -PacketRecvInterface * PacketRecvConnector_GetOutput (PacketRecvConnector *o); - -/** - * Connects input. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output input to connect. Its MTU must be <= MTU specified in - * {@link PacketRecvConnector_Init}. - */ -void PacketRecvConnector_ConnectInput (PacketRecvConnector *o, PacketRecvInterface *input); - -/** - * Disconnects input. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void PacketRecvConnector_DisconnectInput (PacketRecvConnector *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketRecvInterface.c b/v2rayng/badvpn/flow/PacketRecvInterface.c deleted file mode 100644 index 40bb8c612d..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file PacketRecvInterface.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -void _PacketRecvInterface_job_operation (PacketRecvInterface *i) -{ - ASSERT(i->state == PRI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PRI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data); - return; -} - -void _PacketRecvInterface_job_done (PacketRecvInterface *i) -{ - ASSERT(i->state == PRI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = PRI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/v2rayng/badvpn/flow/PacketRecvInterface.h b/v2rayng/badvpn/flow/PacketRecvInterface.h deleted file mode 100644 index 6350ed2443..0000000000 --- a/v2rayng/badvpn/flow/PacketRecvInterface.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file PacketRecvInterface.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a packet receiver to receive data packets from a packet sender. - */ - -#ifndef BADVPN_FLOW_PACKETRECVINTERFACE_H -#define BADVPN_FLOW_PACKETRECVINTERFACE_H - -#include -#include - -#include -#include -#include - -#define PRI_STATE_NONE 1 -#define PRI_STATE_OPERATION_PENDING 2 -#define PRI_STATE_BUSY 3 -#define PRI_STATE_DONE_PENDING 4 - -typedef void (*PacketRecvInterface_handler_recv) (void *user, uint8_t *data); - -typedef void (*PacketRecvInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - int mtu; - PacketRecvInterface_handler_recv handler_operation; - void *user_provider; - - // user data - PacketRecvInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} PacketRecvInterface; - -static void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg); - -static void PacketRecvInterface_Free (PacketRecvInterface *i); - -static void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len); - -static int PacketRecvInterface_GetMTU (PacketRecvInterface *i); - -static void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user); - -static void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data); - -void _PacketRecvInterface_job_operation (PacketRecvInterface *i); -void _PacketRecvInterface_job_done (PacketRecvInterface *i); - -void PacketRecvInterface_Init (PacketRecvInterface *i, int mtu, PacketRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - i->mtu = mtu; - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketRecvInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_PacketRecvInterface_job_done, i); - - // set state - i->state = PRI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void PacketRecvInterface_Free (PacketRecvInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void PacketRecvInterface_Done (PacketRecvInterface *i, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= i->mtu) - ASSERT(i->state == PRI_STATE_BUSY) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = PRI_STATE_DONE_PENDING; -} - -int PacketRecvInterface_GetMTU (PacketRecvInterface *i) -{ - DebugObject_Access(&i->d_obj); - - return i->mtu; -} - -void PacketRecvInterface_Receiver_Init (PacketRecvInterface *i, PacketRecvInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void PacketRecvInterface_Receiver_Recv (PacketRecvInterface *i, uint8_t *data) -{ - ASSERT(!(i->mtu > 0) || data) - ASSERT(i->state == PRI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - BPending_Set(&i->job_operation); - - // set state - i->state = PRI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/v2rayng/badvpn/flow/PacketRouter.c b/v2rayng/badvpn/flow/PacketRouter.c deleted file mode 100644 index 7b9f5f9e79..0000000000 --- a/v2rayng/badvpn/flow/PacketRouter.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file PacketRouter.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -static void input_handler_done (PacketRouter *o, int data_len) -{ - ASSERT(data_len >= 0) - ASSERT(data_len <= o->mtu - o->recv_offset) - ASSERT(!BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); - - // set next job - BPending_Set(&o->next_job); - - // call handler - o->handler(o->user, RouteBufferSource_Pointer(&o->rbs), data_len); - return; -} - -static void next_job_handler (PacketRouter *o) -{ - DebugObject_Access(&o->d_obj); - - // receive - PacketRecvInterface_Receiver_Recv(o->input, RouteBufferSource_Pointer(&o->rbs) + o->recv_offset); -} - -int PacketRouter_Init (PacketRouter *o, int mtu, int recv_offset, PacketRecvInterface *input, PacketRouter_handler handler, void *user, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - ASSERT(recv_offset >= 0) - ASSERT(recv_offset <= mtu) - ASSERT(PacketRecvInterface_GetMTU(input) <= mtu - recv_offset) - - // init arguments - o->mtu = mtu; - o->recv_offset = recv_offset; - o->input = input; - o->handler = handler; - o->user = user; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init RouteBufferSource - if (!RouteBufferSource_Init(&o->rbs, mtu)) { - goto fail0; - } - - // init next job - BPending_Init(&o->next_job, pg, (BPending_handler)next_job_handler, o); - - // receive - PacketRecvInterface_Receiver_Recv(o->input, RouteBufferSource_Pointer(&o->rbs) + o->recv_offset); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - return 0; -} - -void PacketRouter_Free (PacketRouter *o) -{ - DebugObject_Free(&o->d_obj); - - // free next job - BPending_Free(&o->next_job); - - // free RouteBufferSource - RouteBufferSource_Free(&o->rbs); -} - -int PacketRouter_Route (PacketRouter *o, int len, RouteBuffer *output, uint8_t **next_buf, int copy_offset, int copy_len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->mtu) - ASSERT(RouteBuffer_GetMTU(output) == o->mtu) - ASSERT(copy_offset >= 0) - ASSERT(copy_offset <= o->mtu) - ASSERT(copy_len >= 0) - ASSERT(copy_len <= o->mtu - copy_offset) - ASSERT(BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); - - if (!RouteBufferSource_Route(&o->rbs, len, output, copy_offset, copy_len)) { - return 0; - } - - if (next_buf) { - *next_buf = RouteBufferSource_Pointer(&o->rbs); - } - - return 1; -} - -void PacketRouter_AssertRoute (PacketRouter *o) -{ - ASSERT(BPending_IsSet(&o->next_job)) - DebugObject_Access(&o->d_obj); -} diff --git a/v2rayng/badvpn/flow/PacketRouter.h b/v2rayng/badvpn/flow/PacketRouter.h deleted file mode 100644 index 3226078a41..0000000000 --- a/v2rayng/badvpn/flow/PacketRouter.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file PacketRouter.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which simplifies routing packets to {@link RouteBuffer}'s from a - * {@link PacketRecvInterface} input. - */ - -#ifndef BADVPN_FLOW_PACKETROUTER_H -#define BADVPN_FLOW_PACKETROUTER_H - -#include -#include -#include -#include - -/** - * Handler called when a packet is received, allowing the user to route it - * to one or more buffers using {@link PacketRouter_Route}. - * - * @param user as in {@link PacketRouter_Init} - * @param buf the buffer for the packet. May be modified by the user. - * Will have space for mtu bytes. Only valid in the job context of - * this handler, until {@link PacketRouter_Route} is called successfully. - * @param recv_len length of the input packet (located at recv_offset bytes offset) - */ -typedef void (*PacketRouter_handler) (void *user, uint8_t *buf, int recv_len); - -/** - * Object which simplifies routing packets to {@link RouteBuffer}'s from a - * {@link PacketRecvInterface} input. - * - * Packets are routed by calling {@link PacketRouter_Route} (possibly multiple times) - * from the job context of the {@link PacketRouter_handler} handler. - */ -typedef struct { - int mtu; - int recv_offset; - PacketRecvInterface *input; - PacketRouter_handler handler; - void *user; - RouteBufferSource rbs; - BPending next_job; - DebugObject d_obj; -} PacketRouter; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. It will only be possible to route packets to - * {@link RouteBuffer}'s with the same MTU. - * @param recv_offset offset from the beginning for receiving input packets. - * Must be >=0 and <=mtu. The leading space should be initialized - * by the user before routing a packet. - * @param input input interface. Its MTU must be <= mtu - recv_offset. - * @param handler handler called when a packet is received to allow the user to route it - * @param user value passed to handler - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int PacketRouter_Init (PacketRouter *o, int mtu, int recv_offset, PacketRecvInterface *input, PacketRouter_handler handler, void *user, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void PacketRouter_Free (PacketRouter *o); - -/** - * Routes the current packet to the given buffer. - * Must be called from the job context of the {@link PacketRouter_handler} handler. - * On success, copies part of the current packet to next one (regardless if next_buf - * is provided or not; if not, copies before receiving another packet). - * - * @param o the object - * @param len total packet length (e.g. recv_offset + (recv_len from handler)). - * Must be >=0 and <=mtu. - * @param output buffer to route to. Its MTU must be the same as of this object. - * @param next_buf if not NULL, on success, will be set to the address of a new current - * packet that can be routed. The pointer will be valid in the job context of - * the calling handler, until this function is called successfully again - * (as for the original pointer provided by the handler). - * @param copy_offset Offset from the beginning for copying to the next packet. - * Must be >=0 and <=mtu. - * @param copy_len Number of bytes to copy from the old current - * packet to the next one. Must be >=0 and <= mtu - copy_offset. - * @return 1 on success, 0 on failure (buffer full) - */ -int PacketRouter_Route (PacketRouter *o, int len, RouteBuffer *output, uint8_t **next_buf, int copy_offset, int copy_len); - -/** - * Asserts that {@link PacketRouter_Route} can be called. - * - * @param o the object - */ -void PacketRouter_AssertRoute (PacketRouter *o); - -#endif diff --git a/v2rayng/badvpn/flow/PacketStreamSender.c b/v2rayng/badvpn/flow/PacketStreamSender.c deleted file mode 100644 index 153a72b977..0000000000 --- a/v2rayng/badvpn/flow/PacketStreamSender.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file PacketStreamSender.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void send_data (PacketStreamSender *s) -{ - ASSERT(s->in_len >= 0) - - if (s->in_used < s->in_len) { - // send more data - StreamPassInterface_Sender_Send(s->output, s->in + s->in_used, s->in_len - s->in_used); - } else { - // finish input packet - s->in_len = -1; - PacketPassInterface_Done(&s->input); - } -} - -static void input_handler_send (PacketStreamSender *s, uint8_t *data, int data_len) -{ - ASSERT(s->in_len == -1) - ASSERT(data_len >= 0) - DebugObject_Access(&s->d_obj); - - // set input packet - s->in_len = data_len; - s->in = data; - s->in_used = 0; - - // send - send_data(s); -} - -static void output_handler_done (PacketStreamSender *s, int data_len) -{ - ASSERT(s->in_len >= 0) - ASSERT(data_len > 0) - ASSERT(data_len <= s->in_len - s->in_used) - DebugObject_Access(&s->d_obj); - - // update number of bytes sent - s->in_used += data_len; - - // send - send_data(s); -} - -void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg) -{ - ASSERT(mtu >= 0) - - // init arguments - s->output = output; - - // init input - PacketPassInterface_Init(&s->input, mtu, (PacketPassInterface_handler_send)input_handler_send, s, pg); - - // init output - StreamPassInterface_Sender_Init(s->output, (StreamPassInterface_handler_done)output_handler_done, s); - - // have no input packet - s->in_len = -1; - - DebugObject_Init(&s->d_obj); -} - -void PacketStreamSender_Free (PacketStreamSender *s) -{ - DebugObject_Free(&s->d_obj); - - // free input - PacketPassInterface_Free(&s->input); -} - -PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s) -{ - DebugObject_Access(&s->d_obj); - - return &s->input; -} diff --git a/v2rayng/badvpn/flow/PacketStreamSender.h b/v2rayng/badvpn/flow/PacketStreamSender.h deleted file mode 100644 index 735360c736..0000000000 --- a/v2rayng/badvpn/flow/PacketStreamSender.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @file PacketStreamSender.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Object which forwards packets obtained with {@link PacketPassInterface} - * as a stream with {@link StreamPassInterface} (i.e. it concatenates them). - */ - -#ifndef BADVPN_FLOW_PACKETSTREAMSENDER_H -#define BADVPN_FLOW_PACKETSTREAMSENDER_H - -#include - -#include -#include -#include - -/** - * Object which forwards packets obtained with {@link PacketPassInterface} - * as a stream with {@link StreamPassInterface} (i.e. it concatenates them). - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface input; - StreamPassInterface *output; - int in_len; - uint8_t *in; - int in_used; -} PacketStreamSender; - -/** - * Initializes the object. - * - * @param s the object - * @param output output interface - * @param mtu input MTU. Must be >=0. - * @param pg pending group - */ -void PacketStreamSender_Init (PacketStreamSender *s, StreamPassInterface *output, int mtu, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param s the object - */ -void PacketStreamSender_Free (PacketStreamSender *s); - -/** - * Returns the input interface. - * Its MTU will be as in {@link PacketStreamSender_Init}. - * - * @param s the object - * @return input interface - */ -PacketPassInterface * PacketStreamSender_GetInput (PacketStreamSender *s); - -#endif diff --git a/v2rayng/badvpn/flow/RouteBuffer.c b/v2rayng/badvpn/flow/RouteBuffer.c deleted file mode 100644 index dec7be4ca9..0000000000 --- a/v2rayng/badvpn/flow/RouteBuffer.c +++ /dev/null @@ -1,256 +0,0 @@ -/** - * @file RouteBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include - -#include - -static struct RouteBuffer_packet * alloc_packet (int mtu) -{ - if (mtu > SIZE_MAX - sizeof(struct RouteBuffer_packet)) { - return NULL; - } - - // allocate memory - struct RouteBuffer_packet *p = (struct RouteBuffer_packet *)malloc(sizeof(*p) + mtu); - if (!p) { - return NULL; - } - - return p; -} - -static int alloc_free_packet (RouteBuffer *o) -{ - struct RouteBuffer_packet *p = alloc_packet(o->mtu); - if (!p) { - return 0; - } - - // add to free packets list - LinkedList1_Append(&o->packets_free, &p->node); - - return 1; -} - -static void free_free_packets (RouteBuffer *o) -{ - while (!LinkedList1_IsEmpty(&o->packets_free)) { - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetLast(&o->packets_free), struct RouteBuffer_packet, node); - - // remove from free packets list - LinkedList1_Remove(&o->packets_free, &p->node); - - // free memory - free(p); - } -} - -static void release_used_packet (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetFirst(&o->packets_used), struct RouteBuffer_packet, node); - - // remove from used packets list - LinkedList1_Remove(&o->packets_used, &p->node); - - // add to free packets list - LinkedList1_Append(&o->packets_free, &p->node); -} - -static void send_used_packet (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - - // get packet - struct RouteBuffer_packet *p = UPPER_OBJECT(LinkedList1_GetFirst(&o->packets_used), struct RouteBuffer_packet, node); - - // send - PacketPassInterface_Sender_Send(o->output, (uint8_t *)(p + 1), p->len); -} - -static void output_handler_done (RouteBuffer *o) -{ - ASSERT(!LinkedList1_IsEmpty(&o->packets_used)) - DebugObject_Access(&o->d_obj); - - // release packet - release_used_packet(o); - - // send next packet if there is one - if (!LinkedList1_IsEmpty(&o->packets_used)) { - send_used_packet(o); - } -} - -int RouteBuffer_Init (RouteBuffer *o, int mtu, PacketPassInterface *output, int buf_size) -{ - ASSERT(mtu >= 0) - ASSERT(PacketPassInterface_GetMTU(output) >= mtu) - ASSERT(buf_size > 0) - - // init arguments - o->mtu = mtu; - o->output = output; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init free packets list - LinkedList1_Init(&o->packets_free); - - // init used packets list - LinkedList1_Init(&o->packets_used); - - // allocate packets - for (int i = 0; i < buf_size; i++) { - if (!alloc_free_packet(o)) { - goto fail1; - } - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - free_free_packets(o); - return 0; -} - -void RouteBuffer_Free (RouteBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // release packets so they can be freed - while (!LinkedList1_IsEmpty(&o->packets_used)) { - release_used_packet(o); - } - - // free packets - free_free_packets(o); -} - -int RouteBuffer_GetMTU (RouteBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - return o->mtu; -} - -int RouteBufferSource_Init (RouteBufferSource *o, int mtu) -{ - ASSERT(mtu >= 0) - - // init arguments - o->mtu = mtu; - - // allocate current packet - if (!(o->current_packet = alloc_packet(o->mtu))) { - goto fail0; - } - - DebugObject_Init(&o->d_obj); - - return 1; - -fail0: - return 0; -} - -void RouteBufferSource_Free (RouteBufferSource *o) -{ - DebugObject_Free(&o->d_obj); - - // free current packet - free(o->current_packet); -} - -uint8_t * RouteBufferSource_Pointer (RouteBufferSource *o) -{ - DebugObject_Access(&o->d_obj); - - return (uint8_t *)(o->current_packet + 1); -} - -int RouteBufferSource_Route (RouteBufferSource *o, int len, RouteBuffer *b, int copy_offset, int copy_len) -{ - ASSERT(len >= 0) - ASSERT(len <= o->mtu) - ASSERT(b->mtu == o->mtu) - ASSERT(copy_offset >= 0) - ASSERT(copy_offset <= o->mtu) - ASSERT(copy_len >= 0) - ASSERT(copy_len <= o->mtu - copy_offset) - DebugObject_Access(&b->d_obj); - DebugObject_Access(&o->d_obj); - - // check if there's space in the buffer - if (LinkedList1_IsEmpty(&b->packets_free)) { - return 0; - } - - int was_empty = LinkedList1_IsEmpty(&b->packets_used); - - struct RouteBuffer_packet *p = o->current_packet; - - // set packet length - p->len = len; - - // append packet to used packets list - LinkedList1_Append(&b->packets_used, &p->node); - - // get a free packet - struct RouteBuffer_packet *np = UPPER_OBJECT(LinkedList1_GetLast(&b->packets_free), struct RouteBuffer_packet, node); - - // remove it from free packets list - LinkedList1_Remove(&b->packets_free, &np->node); - - // make it the current packet - o->current_packet = np; - - // copy packet - if (copy_len > 0) { - memcpy((uint8_t *)(np + 1) + copy_offset, (uint8_t *)(p + 1) + copy_offset, copy_len); - } - - // start sending if required - if (was_empty) { - send_used_packet(b); - } - - return 1; -} diff --git a/v2rayng/badvpn/flow/RouteBuffer.h b/v2rayng/badvpn/flow/RouteBuffer.h deleted file mode 100644 index d0f7b4151b..0000000000 --- a/v2rayng/badvpn/flow/RouteBuffer.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file RouteBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer for zero-copy packet routing. - */ - -#ifndef BADVPN_FLOW_ROUTEBUFFER_H -#define BADVPN_FLOW_ROUTEBUFFER_H - -#include -#include -#include -#include - -struct RouteBuffer_packet { - LinkedList1Node node; - int len; -}; - -/** - * Packet buffer for zero-copy packet routing. - * - * Packets are buffered using {@link RouteBufferSource} objects. - */ -typedef struct { - int mtu; - PacketPassInterface *output; - LinkedList1 packets_free; - LinkedList1 packets_used; - DebugObject d_obj; -} RouteBuffer; - -/** - * Object through which packets are buffered into {@link RouteBuffer} objects. - * - * A packet is routed by calling {@link RouteBufferSource_Pointer}, writing it to - * the returned address, then calling {@link RouteBufferSource_Route}. - */ -typedef struct { - int mtu; - struct RouteBuffer_packet *current_packet; - DebugObject d_obj; -} RouteBufferSource; - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. It will only be possible to route packets to this buffer - * from {@link RouteBufferSource}.s with the same MTU. - * @param output output interface. Its MTU must be >=mtu. - * @param buf_size size of the buffer in number of packet. Must be >0. - * @return 1 on success, 0 on failure - */ -int RouteBuffer_Init (RouteBuffer *o, int mtu, PacketPassInterface *output, int buf_size) WARN_UNUSED; - -/** - * Frees the object. - */ -void RouteBuffer_Free (RouteBuffer *o); - -/** - * Retuns the buffer's MTU (mtu argument to {@link RouteBuffer_Init}). - * - * @return MTU - */ -int RouteBuffer_GetMTU (RouteBuffer *o); - -/** - * Initializes the object. - * - * @param o the object - * @param mtu maximum packet size. Must be >=0. The object will only be able to route packets - * to {@link RouteBuffer}'s with the same MTU. - * @return 1 on success, 0 on failure - */ -int RouteBufferSource_Init (RouteBufferSource *o, int mtu) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void RouteBufferSource_Free (RouteBufferSource *o); - -/** - * Returns a pointer to the current packet. - * The pointed to memory area will have space for MTU bytes. - * The pointer is only valid until {@link RouteBufferSource_Route} succeeds. - * - * @param o the object - * @return pointer to the current packet - */ -uint8_t * RouteBufferSource_Pointer (RouteBufferSource *o); - -/** - * Routes the current packet to a given buffer. - * On success, this invalidates the pointer previously returned from - * {@link RouteBufferSource_Pointer}. - * - * @param o the object - * @param len length of the packet. Must be >=0 and <=MTU. - * @param b buffer to route to. Its MTU must equal this object's MTU. - * @param copy_offset Offset from the beginning for copying. Must be >=0 and - * <=mtu. - * @param copy_len Number of bytes to copy from the old current packet to the new one. - * Must be >=0 and <= mtu - copy_offset. - * @return 1 on success, 0 on failure - */ -int RouteBufferSource_Route (RouteBufferSource *o, int len, RouteBuffer *b, int copy_offset, int copy_len); - -#endif diff --git a/v2rayng/badvpn/flow/SinglePacketBuffer.c b/v2rayng/badvpn/flow/SinglePacketBuffer.c deleted file mode 100644 index bbc72aedf9..0000000000 --- a/v2rayng/badvpn/flow/SinglePacketBuffer.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file SinglePacketBuffer.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include - -static void input_handler_done (SinglePacketBuffer *o, int in_len) -{ - DebugObject_Access(&o->d_obj); - - PacketPassInterface_Sender_Send(o->output, o->buf, in_len); -} - -static void output_handler_done (SinglePacketBuffer *o) -{ - DebugObject_Access(&o->d_obj); - - PacketRecvInterface_Receiver_Recv(o->input, o->buf); -} - -int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) >= PacketRecvInterface_GetMTU(input)) - - // init arguments - o->input = input; - o->output = output; - - // init input - PacketRecvInterface_Receiver_Init(o->input, (PacketRecvInterface_handler_done)input_handler_done, o); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init buffer - if (!(o->buf = (uint8_t *)BAlloc(PacketRecvInterface_GetMTU(o->input)))) { - goto fail1; - } - - // schedule receive - PacketRecvInterface_Receiver_Recv(o->input, o->buf); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - return 0; -} - -void SinglePacketBuffer_Free (SinglePacketBuffer *o) -{ - DebugObject_Free(&o->d_obj); - - // free buffer - BFree(o->buf); -} diff --git a/v2rayng/badvpn/flow/SinglePacketBuffer.h b/v2rayng/badvpn/flow/SinglePacketBuffer.h deleted file mode 100644 index 87314a5ce3..0000000000 --- a/v2rayng/badvpn/flow/SinglePacketBuffer.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file SinglePacketBuffer.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output - * than can store only a single packet. - */ - -#ifndef BADVPN_FLOW_SINGLEPACKETBUFFER_H -#define BADVPN_FLOW_SINGLEPACKETBUFFER_H - -#include - -#include -#include -#include -#include - -/** - * Packet buffer with {@link PacketRecvInterface} input and {@link PacketPassInterface} output - * than can store only a single packet. - */ -typedef struct { - DebugObject d_obj; - PacketRecvInterface *input; - PacketPassInterface *output; - uint8_t *buf; -} SinglePacketBuffer; - -/** - * Initializes the object. - * Output MTU must be >= input MTU. - * - * @param o the object - * @param input input interface - * @param output output interface - * @param pg pending group - * @return 1 on success, 0 on failure - */ -int SinglePacketBuffer_Init (SinglePacketBuffer *o, PacketRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg) WARN_UNUSED; - -/** - * Frees the object - * - * @param o the object - */ -void SinglePacketBuffer_Free (SinglePacketBuffer *o); - -#endif diff --git a/v2rayng/badvpn/flow/SinglePacketSender.c b/v2rayng/badvpn/flow/SinglePacketSender.c deleted file mode 100644 index b1f3ec7ea9..0000000000 --- a/v2rayng/badvpn/flow/SinglePacketSender.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file SinglePacketSender.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -static void call_handler (SinglePacketSender *o) -{ - DEBUGERROR(&o->d_err, o->handler(o->user)); -} - -static void output_handler_done (SinglePacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - // notify user - call_handler(o); - return; -} - -void SinglePacketSender_Init (SinglePacketSender *o, uint8_t *packet, int packet_len, PacketPassInterface *output, SinglePacketSender_handler handler, void *user, BPendingGroup *pg) -{ - ASSERT(packet_len >= 0) - ASSERT(packet_len <= PacketPassInterface_GetMTU(output)) - - // init arguments - o->output = output; - o->handler = handler; - o->user = user; - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // schedule send - PacketPassInterface_Sender_Send(o->output, packet, packet_len); - - DebugObject_Init(&o->d_obj); - DebugError_Init(&o->d_err, pg); -} - -void SinglePacketSender_Free (SinglePacketSender *o) -{ - DebugError_Free(&o->d_err); - DebugObject_Free(&o->d_obj); -} diff --git a/v2rayng/badvpn/flow/SinglePacketSender.h b/v2rayng/badvpn/flow/SinglePacketSender.h deleted file mode 100644 index c9289d8f8b..0000000000 --- a/v2rayng/badvpn/flow/SinglePacketSender.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SinglePacketSender.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} source which sends a single packet. - */ - -#ifndef BADVPN_FLOW_SINGLEPACKETSENDER_H -#define BADVPN_FLOW_SINGLEPACKETSENDER_H - -#include - -#include -#include -#include - -/** - * Handler function called after the packet is sent. - * The object must be freed from within this handler. - * - * @param user as in {@link SinglePacketSender_Init}. - */ -typedef void (*SinglePacketSender_handler) (void *user); - -/** - * A {@link PacketPassInterface} source which sends a single packet. - */ -typedef struct { - PacketPassInterface *output; - SinglePacketSender_handler handler; - void *user; - DebugObject d_obj; - DebugError d_err; -} SinglePacketSender; - -/** - * Initializes the object. - * - * @param o the object - * @param packet packet to be sent. Must be available as long as the object exists. - * @param packet_len length of the packet. Must be >=0 and <=(MTU of output). - * @param output output interface - * @param handler handler to call when the packet is sent - * @param user value to pass to handler - * @param pg pending group - */ -void SinglePacketSender_Init (SinglePacketSender *o, uint8_t *packet, int packet_len, PacketPassInterface *output, SinglePacketSender_handler handler, void *user, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void SinglePacketSender_Free (SinglePacketSender *o); - -#endif diff --git a/v2rayng/badvpn/flow/SingleStreamReceiver.c b/v2rayng/badvpn/flow/SingleStreamReceiver.c deleted file mode 100644 index b4632908cb..0000000000 --- a/v2rayng/badvpn/flow/SingleStreamReceiver.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SingleStreamReceiver.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "SingleStreamReceiver.h" - -static void input_handler_done (SingleStreamReceiver *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->packet_len - o->pos) - - // update position - o->pos += data_len; - - // if everything was received, notify user - if (o->pos == o->packet_len) { - DEBUGERROR(&o->d_err, o->handler(o->user)); - return; - } - - // receive more - StreamRecvInterface_Receiver_Recv(o->input, o->packet + o->pos, o->packet_len - o->pos); -} - -void SingleStreamReceiver_Init (SingleStreamReceiver *o, uint8_t *packet, int packet_len, StreamRecvInterface *input, BPendingGroup *pg, void *user, SingleStreamReceiver_handler handler) -{ - ASSERT(packet_len > 0) - ASSERT(handler) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - o->input = input; - o->user = user; - o->handler = handler; - - // set position zero - o->pos = 0; - - // init output - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // start receiving - StreamRecvInterface_Receiver_Recv(o->input, o->packet + o->pos, o->packet_len - o->pos); - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); -} - -void SingleStreamReceiver_Free (SingleStreamReceiver *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); -} diff --git a/v2rayng/badvpn/flow/SingleStreamReceiver.h b/v2rayng/badvpn/flow/SingleStreamReceiver.h deleted file mode 100644 index c9c6219eca..0000000000 --- a/v2rayng/badvpn/flow/SingleStreamReceiver.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file SingleStreamReceiver.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLESTREAMRECEIVER_H -#define BADVPN_SINGLESTREAMRECEIVER_H - -#include -#include -#include - -typedef void (*SingleStreamReceiver_handler) (void *user); - -typedef struct { - uint8_t *packet; - int packet_len; - StreamRecvInterface *input; - void *user; - SingleStreamReceiver_handler handler; - int pos; - DebugError d_err; - DebugObject d_obj; -} SingleStreamReceiver; - -void SingleStreamReceiver_Init (SingleStreamReceiver *o, uint8_t *packet, int packet_len, StreamRecvInterface *input, BPendingGroup *pg, void *user, SingleStreamReceiver_handler handler); -void SingleStreamReceiver_Free (SingleStreamReceiver *o); - -#endif diff --git a/v2rayng/badvpn/flow/SingleStreamSender.c b/v2rayng/badvpn/flow/SingleStreamSender.c deleted file mode 100644 index eb333069bb..0000000000 --- a/v2rayng/badvpn/flow/SingleStreamSender.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file SingleStreamSender.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "SingleStreamSender.h" - -static void output_handler_done (SingleStreamSender *o, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - ASSERT(data_len <= o->packet_len - o->pos) - - // update position - o->pos += data_len; - - // if everything was sent, notify user - if (o->pos == o->packet_len) { - DEBUGERROR(&o->d_err, o->handler(o->user)); - return; - } - - // send more - StreamPassInterface_Sender_Send(o->output, o->packet + o->pos, o->packet_len - o->pos); -} - -void SingleStreamSender_Init (SingleStreamSender *o, uint8_t *packet, int packet_len, StreamPassInterface *output, BPendingGroup *pg, void *user, SingleStreamSender_handler handler) -{ - ASSERT(packet_len > 0) - ASSERT(handler) - - // init arguments - o->packet = packet; - o->packet_len = packet_len; - o->output = output; - o->user = user; - o->handler = handler; - - // set position zero - o->pos = 0; - - // init output - StreamPassInterface_Sender_Init(o->output, (StreamPassInterface_handler_done)output_handler_done, o); - - // start sending - StreamPassInterface_Sender_Send(o->output, o->packet + o->pos, o->packet_len - o->pos); - - DebugError_Init(&o->d_err, pg); - DebugObject_Init(&o->d_obj); -} - -void SingleStreamSender_Free (SingleStreamSender *o) -{ - DebugObject_Free(&o->d_obj); - DebugError_Free(&o->d_err); -} diff --git a/v2rayng/badvpn/flow/SingleStreamSender.h b/v2rayng/badvpn/flow/SingleStreamSender.h deleted file mode 100644 index 180a9bfa6b..0000000000 --- a/v2rayng/badvpn/flow/SingleStreamSender.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file SingleStreamSender.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_SINGLESTREAMSENDER_H -#define BADVPN_SINGLESTREAMSENDER_H - -#include -#include -#include - -typedef void (*SingleStreamSender_handler) (void *user); - -typedef struct { - uint8_t *packet; - int packet_len; - StreamPassInterface *output; - void *user; - SingleStreamSender_handler handler; - int pos; - DebugError d_err; - DebugObject d_obj; -} SingleStreamSender; - -void SingleStreamSender_Init (SingleStreamSender *o, uint8_t *packet, int packet_len, StreamPassInterface *output, BPendingGroup *pg, void *user, SingleStreamSender_handler handler); -void SingleStreamSender_Free (SingleStreamSender *o); - -#endif diff --git a/v2rayng/badvpn/flow/StreamPacketSender.c b/v2rayng/badvpn/flow/StreamPacketSender.c deleted file mode 100644 index 1e0a949b56..0000000000 --- a/v2rayng/badvpn/flow/StreamPacketSender.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file StreamPacketSender.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "StreamPacketSender.h" - -static void input_handler_send (StreamPacketSender *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - ASSERT(data_len > 0) - - // limit length to MTU and remember - if (data_len > o->output_mtu) { - o->sending_len = o->output_mtu; - } else { - o->sending_len = data_len; - } - - // send - PacketPassInterface_Sender_Send(o->output, data, o->sending_len); -} - -static void output_handler_done (StreamPacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - // done - StreamPassInterface_Done(&o->input, o->sending_len); -} - -void StreamPacketSender_Init (StreamPacketSender *o, PacketPassInterface *output, BPendingGroup *pg) -{ - ASSERT(PacketPassInterface_GetMTU(output) > 0) - - // init arguments - o->output = output; - - // remember output MTU - o->output_mtu = PacketPassInterface_GetMTU(output); - - // init input - StreamPassInterface_Init(&o->input, (StreamPassInterface_handler_send)input_handler_send, o, pg); - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - DebugObject_Init(&o->d_obj); -} - -void StreamPacketSender_Free (StreamPacketSender *o) -{ - DebugObject_Free(&o->d_obj); - - // free input - StreamPassInterface_Free(&o->input); -} - -StreamPassInterface * StreamPacketSender_GetInput (StreamPacketSender *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} diff --git a/v2rayng/badvpn/flow/StreamPacketSender.h b/v2rayng/badvpn/flow/StreamPacketSender.h deleted file mode 100644 index 19bda5ee8a..0000000000 --- a/v2rayng/badvpn/flow/StreamPacketSender.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file StreamPacketSender.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BADVPN_STREAMPACKETSENDER_H -#define BADVPN_STREAMPACKETSENDER_H - -#include -#include -#include - -/** - * Object which breaks an input stream into output packets. The resulting - * packets will have positive length, and, when concatenated, will form the - * original stream. - * - * Input is with {@link StreamPassInterface}. - * Output is with {@link PacketPassInterface}. - */ -typedef struct { - PacketPassInterface *output; - int output_mtu; - StreamPassInterface input; - int sending_len; - DebugObject d_obj; -} StreamPacketSender; - -/** - * Initializes the object. - * - * @param o the object - * @param output output interface. Its MTU must be >0. - * @param pg pending group we live in - */ -void StreamPacketSender_Init (StreamPacketSender *o, PacketPassInterface *output, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamPacketSender_Free (StreamPacketSender *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -StreamPassInterface * StreamPacketSender_GetInput (StreamPacketSender *o); - -#endif diff --git a/v2rayng/badvpn/flow/StreamPassConnector.c b/v2rayng/badvpn/flow/StreamPassConnector.c deleted file mode 100644 index d3075c733b..0000000000 --- a/v2rayng/badvpn/flow/StreamPassConnector.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file StreamPassConnector.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void input_handler_send (StreamPassConnector *o, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(o->in_len == -1) - DebugObject_Access(&o->d_obj); - - // remember input packet - o->in_len = data_len; - o->in = data; - - if (o->output) { - // schedule send - StreamPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -static void output_handler_done (StreamPassConnector *o, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= o->in_len) - ASSERT(o->in_len > 0) - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // have no input packet - o->in_len = -1; - - // allow input to send more packets - StreamPassInterface_Done(&o->input, data_len); -} - -void StreamPassConnector_Init (StreamPassConnector *o, BPendingGroup *pg) -{ - // init output - StreamPassInterface_Init(&o->input, (StreamPassInterface_handler_send)input_handler_send, o, pg); - - // have no input packet - o->in_len = -1; - - // have no output - o->output = NULL; - - DebugObject_Init(&o->d_obj); -} - -void StreamPassConnector_Free (StreamPassConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - StreamPassInterface_Free(&o->input); -} - -StreamPassInterface * StreamPassConnector_GetInput (StreamPassConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void StreamPassConnector_ConnectOutput (StreamPassConnector *o, StreamPassInterface *output) -{ - ASSERT(!o->output) - DebugObject_Access(&o->d_obj); - - // set output - o->output = output; - - // init output - StreamPassInterface_Sender_Init(o->output, (StreamPassInterface_handler_done)output_handler_done, o); - - // if we have an input packet, schedule send - if (o->in_len > 0) { - StreamPassInterface_Sender_Send(o->output, o->in, o->in_len); - } -} - -void StreamPassConnector_DisconnectOutput (StreamPassConnector *o) -{ - ASSERT(o->output) - DebugObject_Access(&o->d_obj); - - // set no output - o->output = NULL; -} diff --git a/v2rayng/badvpn/flow/StreamPassConnector.h b/v2rayng/badvpn/flow/StreamPassConnector.h deleted file mode 100644 index aa791957c4..0000000000 --- a/v2rayng/badvpn/flow/StreamPassConnector.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file StreamPassConnector.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link StreamPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_STREAMPASSCONNECTOR_H -#define BADVPN_FLOW_STREAMPASSCONNECTOR_H - -#include - -#include -#include - -/** - * A {@link StreamPassInterface} layer which allows the output to be - * connected and disconnected on the fly. - */ -typedef struct { - StreamPassInterface input; - int in_len; - uint8_t *in; - StreamPassInterface *output; - DebugObject d_obj; -} StreamPassConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param pg pending group - */ -void StreamPassConnector_Init (StreamPassConnector *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamPassConnector_Free (StreamPassConnector *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -StreamPassInterface * StreamPassConnector_GetInput (StreamPassConnector *o); - -/** - * Connects output. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output output to connect - */ -void StreamPassConnector_ConnectOutput (StreamPassConnector *o, StreamPassInterface *output); - -/** - * Disconnects output. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void StreamPassConnector_DisconnectOutput (StreamPassConnector *o); - -#endif diff --git a/v2rayng/badvpn/flow/StreamPassInterface.c b/v2rayng/badvpn/flow/StreamPassInterface.c deleted file mode 100644 index f0dc547801..0000000000 --- a/v2rayng/badvpn/flow/StreamPassInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StreamPassInterface.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -void _StreamPassInterface_job_operation (StreamPassInterface *i) -{ - ASSERT(i->state == SPI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SPI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _StreamPassInterface_job_done (StreamPassInterface *i) -{ - ASSERT(i->state == SPI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SPI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/v2rayng/badvpn/flow/StreamPassInterface.h b/v2rayng/badvpn/flow/StreamPassInterface.h deleted file mode 100644 index 1fe650e229..0000000000 --- a/v2rayng/badvpn/flow/StreamPassInterface.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file StreamPassInterface.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a stream sender to pass stream data to a stream receiver. - * - * Note that this interface behaves exactly the same and has the same code as - * {@link StreamRecvInterface} if names and its external semantics are disregarded. - * If you modify this file, you should probably modify {@link StreamRecvInterface} - * too. - */ - -#ifndef BADVPN_FLOW_STREAMPASSINTERFACE_H -#define BADVPN_FLOW_STREAMPASSINTERFACE_H - -#include -#include - -#include -#include -#include - -#define SPI_STATE_NONE 1 -#define SPI_STATE_OPERATION_PENDING 2 -#define SPI_STATE_BUSY 3 -#define SPI_STATE_DONE_PENDING 4 - -typedef void (*StreamPassInterface_handler_send) (void *user, uint8_t *data, int data_len); - -typedef void (*StreamPassInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - StreamPassInterface_handler_send handler_operation; - void *user_provider; - - // user data - StreamPassInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} StreamPassInterface; - -static void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg); - -static void StreamPassInterface_Free (StreamPassInterface *i); - -static void StreamPassInterface_Done (StreamPassInterface *i, int data_len); - -static void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user); - -static void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len); - -void _StreamPassInterface_job_operation (StreamPassInterface *i); -void _StreamPassInterface_job_done (StreamPassInterface *i); - -void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg) -{ - // init arguments - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamPassInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_StreamPassInterface_job_done, i); - - // set state - i->state = SPI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void StreamPassInterface_Free (StreamPassInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void StreamPassInterface_Done (StreamPassInterface *i, int data_len) -{ - ASSERT(i->state == SPI_STATE_BUSY) - ASSERT(data_len > 0) - ASSERT(data_len <= i->job_operation_len) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = SPI_STATE_DONE_PENDING; -} - -void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data) - ASSERT(i->state == SPI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = SPI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/v2rayng/badvpn/flow/StreamRecvConnector.c b/v2rayng/badvpn/flow/StreamRecvConnector.c deleted file mode 100644 index beb6a8821a..0000000000 --- a/v2rayng/badvpn/flow/StreamRecvConnector.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file StreamRecvConnector.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include - -static void output_handler_recv (StreamRecvConnector *o, uint8_t *data, int data_avail) -{ - ASSERT(data_avail > 0) - ASSERT(o->out_avail == -1) - DebugObject_Access(&o->d_obj); - - // remember output packet - o->out_avail = data_avail; - o->out = data; - - if (o->input) { - // schedule receive - StreamRecvInterface_Receiver_Recv(o->input, o->out, o->out_avail); - } -} - -static void input_handler_done (StreamRecvConnector *o, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data_len <= o->out_avail) - ASSERT(o->out_avail > 0) - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // have no output packet - o->out_avail = -1; - - // allow output to receive more packets - StreamRecvInterface_Done(&o->output, data_len); -} - -void StreamRecvConnector_Init (StreamRecvConnector *o, BPendingGroup *pg) -{ - // init output - StreamRecvInterface_Init(&o->output, (StreamRecvInterface_handler_recv)output_handler_recv, o, pg); - - // have no output packet - o->out_avail = -1; - - // have no input - o->input = NULL; - - DebugObject_Init(&o->d_obj); -} - -void StreamRecvConnector_Free (StreamRecvConnector *o) -{ - DebugObject_Free(&o->d_obj); - - // free output - StreamRecvInterface_Free(&o->output); -} - -StreamRecvInterface * StreamRecvConnector_GetOutput (StreamRecvConnector *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->output; -} - -void StreamRecvConnector_ConnectInput (StreamRecvConnector *o, StreamRecvInterface *input) -{ - ASSERT(!o->input) - DebugObject_Access(&o->d_obj); - - // set input - o->input = input; - - // init input - StreamRecvInterface_Receiver_Init(o->input, (StreamRecvInterface_handler_done)input_handler_done, o); - - // if we have an output packet, schedule receive - if (o->out_avail > 0) { - StreamRecvInterface_Receiver_Recv(o->input, o->out, o->out_avail); - } -} - -void StreamRecvConnector_DisconnectInput (StreamRecvConnector *o) -{ - ASSERT(o->input) - DebugObject_Access(&o->d_obj); - - // set no input - o->input = NULL; -} diff --git a/v2rayng/badvpn/flow/StreamRecvConnector.h b/v2rayng/badvpn/flow/StreamRecvConnector.h deleted file mode 100644 index ed111ce3ea..0000000000 --- a/v2rayng/badvpn/flow/StreamRecvConnector.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file StreamRecvConnector.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link StreamRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ - -#ifndef BADVPN_FLOW_STREAMRECVCONNECTOR_H -#define BADVPN_FLOW_STREAMRECVCONNECTOR_H - -#include - -#include -#include - -/** - * A {@link StreamRecvInterface} layer which allows the input to be - * connected and disconnected on the fly. - */ -typedef struct { - StreamRecvInterface output; - int out_avail; - uint8_t *out; - StreamRecvInterface *input; - DebugObject d_obj; -} StreamRecvConnector; - -/** - * Initializes the object. - * The object is initialized in not connected state. - * - * @param o the object - * @param pg pending group - */ -void StreamRecvConnector_Init (StreamRecvConnector *o, BPendingGroup *pg); - -/** - * Frees the object. - * - * @param o the object - */ -void StreamRecvConnector_Free (StreamRecvConnector *o); - -/** - * Returns the output interface. - * - * @param o the object - * @return output interface - */ -StreamRecvInterface * StreamRecvConnector_GetOutput (StreamRecvConnector *o); - -/** - * Connects input. - * The object must be in not connected state. - * The object enters connected state. - * - * @param o the object - * @param output input to connect - */ -void StreamRecvConnector_ConnectInput (StreamRecvConnector *o, StreamRecvInterface *input); - -/** - * Disconnects input. - * The object must be in connected state. - * The object enters not connected state. - * - * @param o the object - */ -void StreamRecvConnector_DisconnectInput (StreamRecvConnector *o); - -#endif diff --git a/v2rayng/badvpn/flow/StreamRecvInterface.c b/v2rayng/badvpn/flow/StreamRecvInterface.c deleted file mode 100644 index 697e1ae607..0000000000 --- a/v2rayng/badvpn/flow/StreamRecvInterface.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StreamRecvInterface.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -void _StreamRecvInterface_job_operation (StreamRecvInterface *i) -{ - ASSERT(i->state == SRI_STATE_OPERATION_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SRI_STATE_BUSY; - - // call handler - i->handler_operation(i->user_provider, i->job_operation_data, i->job_operation_len); - return; -} - -void _StreamRecvInterface_job_done (StreamRecvInterface *i) -{ - ASSERT(i->state == SRI_STATE_DONE_PENDING) - DebugObject_Access(&i->d_obj); - - // set state - i->state = SRI_STATE_NONE; - - // call handler - i->handler_done(i->user_user, i->job_done_len); - return; -} diff --git a/v2rayng/badvpn/flow/StreamRecvInterface.h b/v2rayng/badvpn/flow/StreamRecvInterface.h deleted file mode 100644 index cd4a18138c..0000000000 --- a/v2rayng/badvpn/flow/StreamRecvInterface.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file StreamRecvInterface.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * Interface allowing a stream receiver to receive stream data from a stream sender. - * - * Note that this interface behaves exactly the same and has the same code as - * {@link StreamPassInterface} if names and its external semantics are disregarded. - * If you modify this file, you should probably modify {@link StreamPassInterface} - * too. - */ - -#ifndef BADVPN_FLOW_STREAMRECVINTERFACE_H -#define BADVPN_FLOW_STREAMRECVINTERFACE_H - -#include -#include - -#include -#include -#include - -#define SRI_STATE_NONE 1 -#define SRI_STATE_OPERATION_PENDING 2 -#define SRI_STATE_BUSY 3 -#define SRI_STATE_DONE_PENDING 4 - -typedef void (*StreamRecvInterface_handler_recv) (void *user, uint8_t *data, int data_len); - -typedef void (*StreamRecvInterface_handler_done) (void *user, int data_len); - -typedef struct { - // provider data - StreamRecvInterface_handler_recv handler_operation; - void *user_provider; - - // user data - StreamRecvInterface_handler_done handler_done; - void *user_user; - - // operation job - BPending job_operation; - uint8_t *job_operation_data; - int job_operation_len; - - // done job - BPending job_done; - int job_done_len; - - // state - int state; - - DebugObject d_obj; -} StreamRecvInterface; - -static void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg); - -static void StreamRecvInterface_Free (StreamRecvInterface *i); - -static void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len); - -static void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user); - -static void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len); - -void _StreamRecvInterface_job_operation (StreamRecvInterface *i); -void _StreamRecvInterface_job_done (StreamRecvInterface *i); - -void StreamRecvInterface_Init (StreamRecvInterface *i, StreamRecvInterface_handler_recv handler_operation, void *user, BPendingGroup *pg) -{ - // init arguments - i->handler_operation = handler_operation; - i->user_provider = user; - - // set no user - i->handler_done = NULL; - - // init jobs - BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamRecvInterface_job_operation, i); - BPending_Init(&i->job_done, pg, (BPending_handler)_StreamRecvInterface_job_done, i); - - // set state - i->state = SRI_STATE_NONE; - - DebugObject_Init(&i->d_obj); -} - -void StreamRecvInterface_Free (StreamRecvInterface *i) -{ - DebugObject_Free(&i->d_obj); - - // free jobs - BPending_Free(&i->job_done); - BPending_Free(&i->job_operation); -} - -void StreamRecvInterface_Done (StreamRecvInterface *i, int data_len) -{ - ASSERT(i->state == SRI_STATE_BUSY) - ASSERT(data_len > 0) - ASSERT(data_len <= i->job_operation_len) - DebugObject_Access(&i->d_obj); - - // schedule done - i->job_done_len = data_len; - BPending_Set(&i->job_done); - - // set state - i->state = SRI_STATE_DONE_PENDING; -} - -void StreamRecvInterface_Receiver_Init (StreamRecvInterface *i, StreamRecvInterface_handler_done handler_done, void *user) -{ - ASSERT(handler_done) - ASSERT(!i->handler_done) - DebugObject_Access(&i->d_obj); - - i->handler_done = handler_done; - i->user_user = user; -} - -void StreamRecvInterface_Receiver_Recv (StreamRecvInterface *i, uint8_t *data, int data_len) -{ - ASSERT(data_len > 0) - ASSERT(data) - ASSERT(i->state == SRI_STATE_NONE) - ASSERT(i->handler_done) - DebugObject_Access(&i->d_obj); - - // schedule operation - i->job_operation_data = data; - i->job_operation_len = data_len; - BPending_Set(&i->job_operation); - - // set state - i->state = SRI_STATE_OPERATION_PENDING; -} - -#endif diff --git a/v2rayng/badvpn/flowextra/CMakeLists.txt b/v2rayng/badvpn/flowextra/CMakeLists.txt deleted file mode 100644 index 6ceb1c0a2e..0000000000 --- a/v2rayng/badvpn/flowextra/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(FLOWEXTRA_SOURCES - PacketPassInactivityMonitor.c - KeepaliveIO.c -) -badvpn_add_library(flowextra "flow;system" "" "${FLOWEXTRA_SOURCES}") diff --git a/v2rayng/badvpn/flowextra/KeepaliveIO.c b/v2rayng/badvpn/flowextra/KeepaliveIO.c deleted file mode 100644 index 4e80366355..0000000000 --- a/v2rayng/badvpn/flowextra/KeepaliveIO.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file KeepaliveIO.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "KeepaliveIO.h" - -static void keepalive_handler (KeepaliveIO *o) -{ - DebugObject_Access(&o->d_obj); - - PacketRecvBlocker_AllowBlockedPacket(&o->ka_blocker); -} - -int KeepaliveIO_Init (KeepaliveIO *o, BReactor *reactor, PacketPassInterface *output, PacketRecvInterface *keepalive_input, btime_t keepalive_interval_ms) -{ - ASSERT(PacketRecvInterface_GetMTU(keepalive_input) <= PacketPassInterface_GetMTU(output)) - ASSERT(keepalive_interval_ms > 0) - - // set arguments - o->reactor = reactor; - - // init keep-alive sender - PacketPassInactivityMonitor_Init(&o->kasender, output, o->reactor, keepalive_interval_ms, (PacketPassInactivityMonitor_handler)keepalive_handler, o); - - // init queue - PacketPassPriorityQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->kasender), BReactor_PendingGroup(o->reactor), 0); - - // init keepalive flow - PacketPassPriorityQueueFlow_Init(&o->ka_qflow, &o->queue, -1); - - // init keepalive blocker - PacketRecvBlocker_Init(&o->ka_blocker, keepalive_input, BReactor_PendingGroup(reactor)); - - // init keepalive buffer - if (!SinglePacketBuffer_Init(&o->ka_buffer, PacketRecvBlocker_GetOutput(&o->ka_blocker), PacketPassPriorityQueueFlow_GetInput(&o->ka_qflow), BReactor_PendingGroup(o->reactor))) { - goto fail1; - } - - // init user flow - PacketPassPriorityQueueFlow_Init(&o->user_qflow, &o->queue, 0); - - DebugObject_Init(&o->d_obj); - - return 1; - -fail1: - PacketRecvBlocker_Free(&o->ka_blocker); - PacketPassPriorityQueueFlow_Free(&o->ka_qflow); - PacketPassPriorityQueue_Free(&o->queue); - PacketPassInactivityMonitor_Free(&o->kasender); - return 0; -} - -void KeepaliveIO_Free (KeepaliveIO *o) -{ - DebugObject_Free(&o->d_obj); - - // allow freeing queue flows - PacketPassPriorityQueue_PrepareFree(&o->queue); - - // free user flow - PacketPassPriorityQueueFlow_Free(&o->user_qflow); - - // free keepalive buffer - SinglePacketBuffer_Free(&o->ka_buffer); - - // free keepalive blocker - PacketRecvBlocker_Free(&o->ka_blocker); - - // free keepalive flow - PacketPassPriorityQueueFlow_Free(&o->ka_qflow); - - // free queue - PacketPassPriorityQueue_Free(&o->queue); - - // free keep-alive sender - PacketPassInactivityMonitor_Free(&o->kasender); -} - -PacketPassInterface * KeepaliveIO_GetInput (KeepaliveIO *o) -{ - DebugObject_Access(&o->d_obj); - - return PacketPassPriorityQueueFlow_GetInput(&o->user_qflow); -} diff --git a/v2rayng/badvpn/flowextra/KeepaliveIO.h b/v2rayng/badvpn/flowextra/KeepaliveIO.h deleted file mode 100644 index d89321cd0d..0000000000 --- a/v2rayng/badvpn/flowextra/KeepaliveIO.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file KeepaliveIO.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer for sending keep-alive packets. - */ - -#ifndef BADVPN_KEEPALIVEIO -#define BADVPN_KEEPALIVEIO - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * A {@link PacketPassInterface} layer for sending keep-alive packets. - */ -typedef struct { - BReactor *reactor; - PacketPassInactivityMonitor kasender; - PacketPassPriorityQueue queue; - PacketPassPriorityQueueFlow user_qflow; - PacketPassPriorityQueueFlow ka_qflow; - SinglePacketBuffer ka_buffer; - PacketRecvBlocker ka_blocker; - DebugObject d_obj; -} KeepaliveIO; - -/** - * Initializes the object. - * - * @param o the object - * @param reactor reactor we live in - * @param output output interface - * @param keepalive_input keepalive input interface. Its MTU must be <= MTU of output. - * @param keepalive_interval_ms keepalive interval in milliseconds. Must be >0. - * @return 1 on success, 0 on failure - */ -int KeepaliveIO_Init (KeepaliveIO *o, BReactor *reactor, PacketPassInterface *output, PacketRecvInterface *keepalive_input, btime_t keepalive_interval_ms) WARN_UNUSED; - -/** - * Frees the object. - * - * @param o the object - */ -void KeepaliveIO_Free (KeepaliveIO *o); - -/** - * Returns the input interface. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * KeepaliveIO_GetInput (KeepaliveIO *o); - -#endif diff --git a/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.c b/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.c deleted file mode 100644 index 6531fe012e..0000000000 --- a/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file PacketPassInactivityMonitor.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "PacketPassInactivityMonitor.h" - -static void input_handler_send (PacketPassInactivityMonitor *o, uint8_t *data, int data_len) -{ - DebugObject_Access(&o->d_obj); - - // schedule send - PacketPassInterface_Sender_Send(o->output, data, data_len); - - // stop timer - BReactor_RemoveTimer(o->reactor, &o->timer); -} - -static void input_handler_requestcancel (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // request cancel - PacketPassInterface_Sender_RequestCancel(o->output); -} - -static void output_handler_done (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // output no longer busy, restart timer - BReactor_SetTimer(o->reactor, &o->timer); - - // call done - PacketPassInterface_Done(&o->input); -} - -static void timer_handler (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - // restart timer - BReactor_SetTimer(o->reactor, &o->timer); - - // call handler - if (o->handler) { - o->handler(o->user); - return; - } -} - -void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user) -{ - // init arguments - o->output = output; - o->reactor = reactor; - o->handler = handler; - o->user = user; - - // init input - PacketPassInterface_Init(&o->input, PacketPassInterface_GetMTU(o->output), (PacketPassInterface_handler_send)input_handler_send, o, BReactor_PendingGroup(o->reactor)); - if (PacketPassInterface_HasCancel(o->output)) { - PacketPassInterface_EnableCancel(&o->input, (PacketPassInterface_handler_requestcancel)input_handler_requestcancel); - } - - // init output - PacketPassInterface_Sender_Init(o->output, (PacketPassInterface_handler_done)output_handler_done, o); - - // init timer - BTimer_Init(&o->timer, interval, (BTimer_handler)timer_handler, o); - BReactor_SetTimer(o->reactor, &o->timer); - - DebugObject_Init(&o->d_obj); -} - -void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o) -{ - DebugObject_Free(&o->d_obj); - - // free timer - BReactor_RemoveTimer(o->reactor, &o->timer); - - // free input - PacketPassInterface_Free(&o->input); -} - -PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - return &o->input; -} - -void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user) -{ - DebugObject_Access(&o->d_obj); - - o->handler = handler; - o->user = user; -} - -void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o) -{ - DebugObject_Access(&o->d_obj); - - BReactor_SetTimerAfter(o->reactor, &o->timer, 0); -} diff --git a/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.h b/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.h deleted file mode 100644 index 58576180dc..0000000000 --- a/v2rayng/badvpn/flowextra/PacketPassInactivityMonitor.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @file PacketPassInactivityMonitor.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * A {@link PacketPassInterface} layer for detecting inactivity. - */ - -#ifndef BADVPN_PACKETPASSINACTIVITYMONITOR_H -#define BADVPN_PACKETPASSINACTIVITYMONITOR_H - -#include -#include -#include - -/** - * Handler function invoked when inactivity is detected. - * It is guaranteed that the interfaces are in not sending state. - * - * @param user value given to {@link PacketPassInactivityMonitor_Init} - */ -typedef void (*PacketPassInactivityMonitor_handler) (void *user); - -/** - * A {@link PacketPassInterface} layer for detecting inactivity. - * It reports inactivity to a user provided handler function. - * - * The object behaves like that: - * ("timer set" means started with the given timeout whether if was running or not, - * "timer unset" means stopped if it was running) - * - There is a timer. - * - The timer is set when the object is initialized. - * - When the input calls Send, the call is passed on to the output. - * If the output accepted the packet, the timer is set. If the output - * blocked the packet, the timer is unset. - * - When the output calls Done, the timer is set, and the call is - * passed on to the input. - * - When the input calls Cancel, the timer is set, and the call is - * passed on to the output. - * - When the timer expires, the timer is set, ant the user's handler - * function is invoked. - */ -typedef struct { - DebugObject d_obj; - PacketPassInterface *output; - BReactor *reactor; - PacketPassInactivityMonitor_handler handler; - void *user; - PacketPassInterface input; - BTimer timer; -} PacketPassInactivityMonitor; - -/** - * Initializes the object. - * See {@link PacketPassInactivityMonitor} for details. - * - * @param o the object - * @param output output interface - * @param reactor reactor we live in - * @param interval timer value in milliseconds - * @param handler handler function for reporting inactivity, or NULL to disable - * @param user value passed to handler functions - */ -void PacketPassInactivityMonitor_Init (PacketPassInactivityMonitor *o, PacketPassInterface *output, BReactor *reactor, btime_t interval, PacketPassInactivityMonitor_handler handler, void *user); - -/** - * Frees the object. - * - * @param o the object - */ -void PacketPassInactivityMonitor_Free (PacketPassInactivityMonitor *o); - -/** - * Returns the input interface. - * The MTU of the interface will be the same as of the output interface. - * The interface supports cancel functionality if the output interface supports it. - * - * @param o the object - * @return input interface - */ -PacketPassInterface * PacketPassInactivityMonitor_GetInput (PacketPassInactivityMonitor *o); - -/** - * Sets or removes the inactivity handler. - * - * @param o the object - * @param handler handler function for reporting inactivity, or NULL to disable - * @param user value passed to handler functions - */ -void PacketPassInactivityMonitor_SetHandler (PacketPassInactivityMonitor *o, PacketPassInactivityMonitor_handler handler, void *user); - -/** - * Sets the timer to expire immediately in order to force an inactivity report. - * - * @param o the object - */ -void PacketPassInactivityMonitor_Force (PacketPassInactivityMonitor *o); - -#endif diff --git a/v2rayng/badvpn/generate_files b/v2rayng/badvpn/generate_files deleted file mode 100755 index f473369f64..0000000000 --- a/v2rayng/badvpn/generate_files +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -e - -PHP_CMD=( php ) -FLEX_CMD=( flex ) -BISON_CMD=( bison ) - -OUT_DIR="generated/" - -function bproto() { - local input="$1" - local name="$2" - "${PHP_CMD[@]}" bproto_generator/bproto.php --input-file "${input}" --output-dir "${OUT_DIR}" --name "bproto_${name}" -} - -function do_flex() { - local input="$1" - local name="$2" - "${FLEX_CMD[@]}" -o "${OUT_DIR}/flex_${name}.c" --header-file="${OUT_DIR}/flex_${name}.h" "${input}" - "${PHP_CMD[@]}" fix_flex.php "${OUT_DIR}/flex_${name}.c" - "${PHP_CMD[@]}" fix_flex.php "${OUT_DIR}/flex_${name}.h" -} - -function do_bison() { - local input="$1" - local name="$2" - "${BISON_CMD[@]}" -d -o "${OUT_DIR}/bison_${name}.c" "${input}" -} - -function do_lemon() { - local input="$1" - local name=$(basename "${input}") - ( - cd generated && - rm -f "${name}" && - cp ../"${input}" "${name}" && - ../lemon/lemon "${name}" - ) -} - -mkdir -p generated - -bproto tests/bproto_test.bproto bproto_test -bproto protocol/msgproto.bproto msgproto -bproto protocol/addr.bproto addr -do_flex predicate/BPredicate.l BPredicate -do_bison predicate/BPredicate.y BPredicate -"${PHP_CMD[@]}" blog_generator/blog.php --input-file blog_channels.txt --output-dir "${OUT_DIR}" -do_lemon ncd/NCDConfigParser_parse.y -do_lemon ncd/NCDValParser_parse.y diff --git a/v2rayng/badvpn/generated/NCDConfigParser_parse.c b/v2rayng/badvpn/generated/NCDConfigParser_parse.c deleted file mode 100644 index f46757d199..0000000000 --- a/v2rayng/badvpn/generated/NCDConfigParser_parse.c +++ /dev/null @@ -1,2167 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include -#line 30 "NCDConfigParser_parse.y" - - -#include -#include - -#include -#include -#include - -struct parser_out { - int out_of_memory; - int syntax_error; - int have_ast; - NCDProgram ast; -}; - -struct token { - char *str; - size_t len; -}; - -struct program { - int have; - NCDProgram v; -}; - -struct block { - int have; - NCDBlock v; -}; - -struct statement { - int have; - NCDStatement v; -}; - -struct ifblock { - int have; - NCDIfBlock v; -}; - -struct value { - int have; - NCDValue v; -}; - -static void free_token (struct token o) { free(o.str); } -static void free_program (struct program o) { if (o.have) NCDProgram_Free(&o.v); } -static void free_block (struct block o) { if (o.have) NCDBlock_Free(&o.v); } -static void free_statement (struct statement o) { if (o.have) NCDStatement_Free(&o.v); } -static void free_ifblock (struct ifblock o) { if (o.have) NCDIfBlock_Free(&o.v); } -static void free_value (struct value o) { if (o.have) NCDValue_Free(&o.v); } - -#line 62 "NCDConfigParser_parse.c" -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 49 -#define YYACTIONTYPE unsigned char -#define ParseTOKENTYPE struct token -typedef union { - int yyinit; - ParseTOKENTYPE yy0; - struct program yy6; - struct value yy19; - int yy28; - struct ifblock yy44; - struct statement yy47; - char * yy49; - struct block yy69; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 0 -#endif -#define ParseARG_SDECL struct parser_out *parser_out ; -#define ParseARG_PDECL , struct parser_out *parser_out -#define ParseARG_FETCH struct parser_out *parser_out = yypParser->parser_out -#define ParseARG_STORE yypParser->parser_out = parser_out -#define YYNSTATE 130 -#define YYNRULE 49 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 107, 51, 59, 4, 104, 9, 107, 2, 59, 4, - /* 10 */ 94, 9, 107, 58, 59, 4, 54, 9, 95, 180, - /* 20 */ 5, 6, 29, 30, 100, 54, 5, 117, 29, 30, - /* 30 */ 34, 128, 5, 54, 29, 30, 111, 57, 102, 112, - /* 40 */ 59, 113, 115, 43, 111, 62, 102, 112, 96, 113, - /* 50 */ 115, 43, 2, 111, 65, 102, 112, 91, 113, 115, - /* 60 */ 43, 101, 111, 54, 60, 112, 7, 113, 115, 43, - /* 70 */ 111, 61, 2, 112, 63, 113, 115, 44, 111, 8, - /* 80 */ 103, 112, 108, 113, 115, 43, 111, 2, 116, 112, - /* 90 */ 106, 113, 115, 44, 111, 2, 68, 112, 2, 113, - /* 100 */ 115, 45, 1, 111, 73, 32, 112, 110, 113, 115, - /* 110 */ 46, 111, 64, 52, 112, 53, 113, 115, 47, 111, - /* 120 */ 109, 66, 112, 71, 113, 115, 48, 111, 70, 59, - /* 130 */ 112, 35, 113, 115, 50, 39, 67, 72, 97, 98, - /* 140 */ 76, 20, 77, 79, 80, 56, 42, 20, 82, 20, - /* 150 */ 129, 69, 42, 90, 42, 130, 20, 84, 20, 89, - /* 160 */ 75, 42, 78, 42, 20, 23, 24, 20, 81, 42, - /* 170 */ 20, 83, 42, 20, 124, 42, 20, 88, 42, 74, - /* 180 */ 93, 42, 2, 92, 55, 85, 13, 27, 25, 28, - /* 190 */ 105, 118, 99, 31, 114, 3, 119, 33, 10, 14, - /* 200 */ 49, 26, 120, 15, 11, 16, 86, 36, 121, 17, - /* 210 */ 181, 37, 122, 18, 87, 38, 123, 19, 181, 21, - /* 220 */ 181, 40, 125, 127, 41, 126, 181, 12, 22, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 2, 29, 4, 5, 6, 7, 2, 7, 4, 5, - /* 10 */ 29, 7, 2, 43, 4, 5, 44, 7, 29, 47, - /* 20 */ 22, 21, 24, 25, 4, 44, 22, 23, 24, 25, - /* 30 */ 31, 32, 22, 44, 24, 25, 35, 36, 37, 38, - /* 40 */ 4, 40, 41, 42, 35, 36, 37, 38, 29, 40, - /* 50 */ 41, 42, 7, 35, 36, 37, 38, 15, 40, 41, - /* 60 */ 42, 35, 35, 44, 37, 38, 21, 40, 41, 42, - /* 70 */ 35, 4, 7, 38, 39, 40, 41, 42, 35, 14, - /* 80 */ 37, 38, 35, 40, 41, 42, 35, 7, 8, 38, - /* 90 */ 39, 40, 41, 42, 35, 7, 8, 38, 7, 40, - /* 100 */ 41, 42, 7, 35, 13, 10, 38, 45, 40, 41, - /* 110 */ 42, 35, 35, 1, 38, 3, 40, 41, 42, 35, - /* 120 */ 45, 43, 38, 16, 40, 41, 42, 35, 43, 4, - /* 130 */ 38, 33, 40, 41, 42, 46, 11, 12, 26, 27, - /* 140 */ 43, 30, 17, 43, 19, 34, 35, 30, 18, 30, - /* 150 */ 32, 34, 35, 34, 35, 0, 30, 43, 30, 43, - /* 160 */ 34, 35, 34, 35, 30, 2, 2, 30, 34, 35, - /* 170 */ 30, 34, 35, 30, 34, 35, 30, 34, 35, 8, - /* 180 */ 34, 35, 7, 8, 4, 14, 5, 8, 6, 20, - /* 190 */ 6, 23, 9, 20, 8, 7, 9, 8, 7, 5, - /* 200 */ 4, 6, 9, 5, 7, 5, 4, 6, 9, 5, - /* 210 */ 48, 6, 9, 5, 8, 6, 6, 5, 48, 5, - /* 220 */ 48, 6, 9, 6, 6, 9, 48, 7, 5, -}; -#define YY_SHIFT_USE_DFLT (-3) -#define YY_SHIFT_MAX 93 -static const short yy_shift_ofst[] = { - /* 0 */ 112, 10, 10, 10, -2, 4, 10, 10, 10, 10, - /* 10 */ 10, 10, 10, 125, 125, 125, 125, 125, 125, 125, - /* 20 */ 125, 125, 125, 112, 112, 112, 42, 20, 36, 36, - /* 30 */ 67, 67, 36, 20, 107, 20, 20, 20, 130, 20, - /* 40 */ 20, 42, 95, 0, 65, 45, 80, 88, 91, 171, - /* 50 */ 175, 155, 163, 164, 180, 181, 182, 179, 183, 169, - /* 60 */ 184, 173, 186, 168, 188, 189, 187, 191, 194, 195, - /* 70 */ 193, 198, 197, 196, 200, 201, 199, 204, 205, 203, - /* 80 */ 208, 209, 212, 210, 213, 202, 206, 214, 215, 216, - /* 90 */ 217, 220, 223, 218, -}; -#define YY_REDUCE_USE_DFLT (-31) -#define YY_REDUCE_MAX 41 -static const short yy_reduce_ofst[] = { - /* 0 */ -28, 1, 9, 18, 27, 35, 43, 51, 59, 68, - /* 10 */ 76, 84, 92, 111, 117, 119, 126, 128, 134, 137, - /* 20 */ 140, 143, 146, -19, -11, 19, -1, -30, 26, 47, - /* 30 */ 62, 75, 77, 78, 98, 85, 97, 100, 89, 114, - /* 40 */ 116, 118, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 131, 156, 156, 156, 179, 179, 179, 179, 179, 179, - /* 10 */ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - /* 20 */ 150, 179, 179, 131, 131, 131, 140, 175, 179, 179, - /* 30 */ 179, 179, 179, 175, 144, 175, 175, 175, 147, 175, - /* 40 */ 175, 142, 179, 158, 179, 162, 179, 179, 179, 179, - /* 50 */ 179, 179, 179, 179, 179, 179, 179, 179, 179, 152, - /* 60 */ 179, 154, 179, 179, 179, 179, 179, 179, 179, 179, - /* 70 */ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - /* 80 */ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - /* 90 */ 179, 179, 179, 179, 132, 133, 134, 177, 178, 135, - /* 100 */ 176, 153, 157, 159, 160, 161, 163, 167, 168, 155, - /* 110 */ 169, 170, 171, 172, 166, 174, 173, 164, 165, 136, - /* 120 */ 137, 138, 146, 148, 151, 149, 139, 145, 141, 143, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "INCLUDE", "STRING", "INCLUDE_GUARD", - "NAME", "CURLY_OPEN", "CURLY_CLOSE", "ROUND_OPEN", - "ROUND_CLOSE", "SEMICOLON", "ARROW", "IF", - "FOREACH", "AS", "COLON", "ELIF", - "ELSE", "BLOCK", "TOKEN_INTERRUPT", "TOKEN_DO", - "DOT", "COMMA", "BRACKET_OPEN", "BRACKET_CLOSE", - "AT_SIGN", "CARET", "PROCESS", "TEMPLATE", - "error", "processes", "statement", "elif_maybe", - "elif", "else_maybe", "statements", "dotted_name", - "list_contents_maybe", "list_contents", "list", "map_contents", - "map", "invoc", "value", "name_maybe", - "process_or_template", "name_list", "interrupt_maybe", "input", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "input ::= processes", - /* 1 */ "processes ::=", - /* 2 */ "processes ::= INCLUDE STRING processes", - /* 3 */ "processes ::= INCLUDE_GUARD STRING processes", - /* 4 */ "processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes", - /* 5 */ "statement ::= dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON", - /* 6 */ "statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON", - /* 7 */ "statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON", - /* 8 */ "statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON", - /* 9 */ "statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON", - /* 10 */ "elif_maybe ::=", - /* 11 */ "elif_maybe ::= elif", - /* 12 */ "elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE", - /* 13 */ "elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif", - /* 14 */ "else_maybe ::=", - /* 15 */ "else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE", - /* 16 */ "statement ::= BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON", - /* 17 */ "interrupt_maybe ::=", - /* 18 */ "interrupt_maybe ::= TOKEN_INTERRUPT CURLY_OPEN statements CURLY_CLOSE", - /* 19 */ "statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON", - /* 20 */ "statements ::= statement", - /* 21 */ "statements ::= statement statements", - /* 22 */ "dotted_name ::= NAME", - /* 23 */ "dotted_name ::= NAME DOT dotted_name", - /* 24 */ "name_list ::= NAME", - /* 25 */ "name_list ::= NAME DOT name_list", - /* 26 */ "list_contents_maybe ::=", - /* 27 */ "list_contents_maybe ::= list_contents", - /* 28 */ "list_contents ::= value", - /* 29 */ "list_contents ::= value COMMA list_contents", - /* 30 */ "list ::= CURLY_OPEN CURLY_CLOSE", - /* 31 */ "list ::= CURLY_OPEN list_contents CURLY_CLOSE", - /* 32 */ "map_contents ::= value COLON value", - /* 33 */ "map_contents ::= value COLON value COMMA map_contents", - /* 34 */ "map ::= BRACKET_OPEN BRACKET_CLOSE", - /* 35 */ "map ::= BRACKET_OPEN map_contents BRACKET_CLOSE", - /* 36 */ "invoc ::= value ROUND_OPEN list_contents_maybe ROUND_CLOSE", - /* 37 */ "value ::= STRING", - /* 38 */ "value ::= AT_SIGN dotted_name", - /* 39 */ "value ::= CARET name_list", - /* 40 */ "value ::= dotted_name", - /* 41 */ "value ::= list", - /* 42 */ "value ::= map", - /* 43 */ "value ::= ROUND_OPEN value ROUND_CLOSE", - /* 44 */ "value ::= invoc", - /* 45 */ "name_maybe ::=", - /* 46 */ "name_maybe ::= NAME", - /* 47 */ "process_or_template ::= PROCESS", - /* 48 */ "process_or_template ::= TEMPLATE", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - /* TERMINAL Destructor */ - case 1: /* INCLUDE */ - case 2: /* STRING */ - case 3: /* INCLUDE_GUARD */ - case 4: /* NAME */ - case 5: /* CURLY_OPEN */ - case 6: /* CURLY_CLOSE */ - case 7: /* ROUND_OPEN */ - case 8: /* ROUND_CLOSE */ - case 9: /* SEMICOLON */ - case 10: /* ARROW */ - case 11: /* IF */ - case 12: /* FOREACH */ - case 13: /* AS */ - case 14: /* COLON */ - case 15: /* ELIF */ - case 16: /* ELSE */ - case 17: /* BLOCK */ - case 18: /* TOKEN_INTERRUPT */ - case 19: /* TOKEN_DO */ - case 20: /* DOT */ - case 21: /* COMMA */ - case 22: /* BRACKET_OPEN */ - case 23: /* BRACKET_CLOSE */ - case 24: /* AT_SIGN */ - case 25: /* CARET */ - case 26: /* PROCESS */ - case 27: /* TEMPLATE */ -{ -#line 89 "NCDConfigParser_parse.y" - free_token((yypminor->yy0)); -#line 561 "NCDConfigParser_parse.c" -} - break; - case 29: /* processes */ -{ -#line 111 "NCDConfigParser_parse.y" - (void)parser_out; free_program((yypminor->yy6)); -#line 568 "NCDConfigParser_parse.c" -} - break; - case 30: /* statement */ -{ -#line 112 "NCDConfigParser_parse.y" - free_statement((yypminor->yy47)); -#line 575 "NCDConfigParser_parse.c" -} - break; - case 31: /* elif_maybe */ - case 32: /* elif */ -{ -#line 113 "NCDConfigParser_parse.y" - free_ifblock((yypminor->yy44)); -#line 583 "NCDConfigParser_parse.c" -} - break; - case 33: /* else_maybe */ - case 34: /* statements */ - case 46: /* interrupt_maybe */ -{ -#line 115 "NCDConfigParser_parse.y" - free_block((yypminor->yy69)); -#line 592 "NCDConfigParser_parse.c" -} - break; - case 35: /* dotted_name */ - case 43: /* name_maybe */ -{ -#line 117 "NCDConfigParser_parse.y" - free((yypminor->yy49)); -#line 600 "NCDConfigParser_parse.c" -} - break; - case 36: /* list_contents_maybe */ - case 37: /* list_contents */ - case 38: /* list */ - case 39: /* map_contents */ - case 40: /* map */ - case 41: /* invoc */ - case 42: /* value */ - case 45: /* name_list */ -{ -#line 118 "NCDConfigParser_parse.y" - free_value((yypminor->yy19)); -#line 614 "NCDConfigParser_parse.c" -} - break; - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && iyyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -#line 136 "NCDConfigParser_parse.y" - - if (yypMinor) { - free_token(yypMinor->yy0); - } -#line 792 "NCDConfigParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 47, 1 }, - { 29, 0 }, - { 29, 3 }, - { 29, 3 }, - { 29, 6 }, - { 30, 6 }, - { 30, 8 }, - { 30, 11 }, - { 30, 11 }, - { 30, 13 }, - { 31, 0 }, - { 31, 1 }, - { 32, 7 }, - { 32, 8 }, - { 33, 0 }, - { 33, 4 }, - { 30, 6 }, - { 46, 0 }, - { 46, 4 }, - { 30, 7 }, - { 34, 1 }, - { 34, 2 }, - { 35, 1 }, - { 35, 3 }, - { 45, 1 }, - { 45, 3 }, - { 36, 0 }, - { 36, 1 }, - { 37, 1 }, - { 37, 3 }, - { 38, 2 }, - { 38, 3 }, - { 39, 3 }, - { 39, 5 }, - { 40, 2 }, - { 40, 3 }, - { 41, 4 }, - { 42, 1 }, - { 42, 2 }, - { 42, 2 }, - { 42, 1 }, - { 42, 1 }, - { 42, 1 }, - { 42, 3 }, - { 42, 1 }, - { 43, 0 }, - { 43, 1 }, - { 44, 1 }, - { 44, 1 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ - case 0: /* input ::= processes */ -#line 142 "NCDConfigParser_parse.y" -{ - ASSERT(!parser_out->have_ast) - - if (yymsp[0].minor.yy6.have) { - parser_out->have_ast = 1; - parser_out->ast = yymsp[0].minor.yy6.v; - } -} -#line 962 "NCDConfigParser_parse.c" - break; - case 1: /* processes ::= */ -#line 151 "NCDConfigParser_parse.y" -{ - NCDProgram prog; - NCDProgram_Init(&prog); - - yygotominor.yy6.have = 1; - yygotominor.yy6.v = prog; -} -#line 973 "NCDConfigParser_parse.c" - break; - case 2: /* processes ::= INCLUDE STRING processes */ -#line 159 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-1].minor.yy0.str) - if (!yymsp[0].minor.yy6.have) { - goto failA0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitInclude(&elem, yymsp[-1].minor.yy0.str, yymsp[-1].minor.yy0.len)) { - goto failA0; - } - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy6.v, elem)) { - goto failA1; - } - - yygotominor.yy6.have = 1; - yygotominor.yy6.v = yymsp[0].minor.yy6.v; - yymsp[0].minor.yy6.have = 0; - goto doneA; - -failA1: - NCDProgramElem_Free(&elem); -failA0: - yygotominor.yy6.have = 0; - parser_out->out_of_memory = 1; -doneA: - free_token(yymsp[-1].minor.yy0); - free_program(yymsp[0].minor.yy6); - yy_destructor(yypParser,1,&yymsp[-2].minor); -} -#line 1007 "NCDConfigParser_parse.c" - break; - case 3: /* processes ::= INCLUDE_GUARD STRING processes */ -#line 189 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-1].minor.yy0.str) - if (!yymsp[0].minor.yy6.have) { - goto failZ0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitIncludeGuard(&elem, yymsp[-1].minor.yy0.str, yymsp[-1].minor.yy0.len)) { - goto failZ0; - } - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy6.v, elem)) { - goto failZ1; - } - - yygotominor.yy6.have = 1; - yygotominor.yy6.v = yymsp[0].minor.yy6.v; - yymsp[0].minor.yy6.have = 0; - goto doneZ; - -failZ1: - NCDProgramElem_Free(&elem); -failZ0: - yygotominor.yy6.have = 0; - parser_out->out_of_memory = 1; -doneZ: - free_token(yymsp[-1].minor.yy0); - free_program(yymsp[0].minor.yy6); - yy_destructor(yypParser,3,&yymsp[-2].minor); -} -#line 1041 "NCDConfigParser_parse.c" - break; - case 4: /* processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes */ -#line 219 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-4].minor.yy0.str) - if (!yymsp[-2].minor.yy69.have || !yymsp[0].minor.yy6.have) { - goto failB0; - } - - NCDProcess proc; - if (!NCDProcess_Init(&proc, yymsp[-5].minor.yy28, yymsp[-4].minor.yy0.str, yymsp[-2].minor.yy69.v)) { - goto failB0; - } - yymsp[-2].minor.yy69.have = 0; - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc); - - if (!NCDProgram_PrependElem(&yymsp[0].minor.yy6.v, elem)) { - goto failB1; - } - - yygotominor.yy6.have = 1; - yygotominor.yy6.v = yymsp[0].minor.yy6.v; - yymsp[0].minor.yy6.have = 0; - goto doneB; - -failB1: - NCDProgramElem_Free(&elem); -failB0: - yygotominor.yy6.have = 0; - parser_out->out_of_memory = 1; -doneB: - free_token(yymsp[-4].minor.yy0); - free_block(yymsp[-2].minor.yy69); - free_program(yymsp[0].minor.yy6); - yy_destructor(yypParser,5,&yymsp[-3].minor); - yy_destructor(yypParser,6,&yymsp[-1].minor); -} -#line 1081 "NCDConfigParser_parse.c" - break; - case 5: /* statement ::= dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON */ -#line 254 "NCDConfigParser_parse.y" -{ - if (!yymsp[-5].minor.yy49 || !yymsp[-3].minor.yy19.have) { - goto failC0; - } - - if (!NCDStatement_InitReg(&yygotominor.yy47.v, yymsp[-1].minor.yy49, NULL, yymsp[-5].minor.yy49, yymsp[-3].minor.yy19.v)) { - goto failC0; - } - yymsp[-3].minor.yy19.have = 0; - - yygotominor.yy47.have = 1; - goto doneC; - -failC0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneC: - free(yymsp[-5].minor.yy49); - free_value(yymsp[-3].minor.yy19); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,7,&yymsp[-4].minor); - yy_destructor(yypParser,8,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1109 "NCDConfigParser_parse.c" - break; - case 6: /* statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON */ -#line 276 "NCDConfigParser_parse.y" -{ - if (!yymsp[-7].minor.yy49 || !yymsp[-5].minor.yy49 || !yymsp[-3].minor.yy19.have) { - goto failD0; - } - - if (!NCDStatement_InitReg(&yygotominor.yy47.v, yymsp[-1].minor.yy49, yymsp[-7].minor.yy49, yymsp[-5].minor.yy49, yymsp[-3].minor.yy19.v)) { - goto failD0; - } - yymsp[-3].minor.yy19.have = 0; - - yygotominor.yy47.have = 1; - goto doneD; - -failD0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneD: - free(yymsp[-7].minor.yy49); - free(yymsp[-5].minor.yy49); - free_value(yymsp[-3].minor.yy19); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,10,&yymsp[-6].minor); - yy_destructor(yypParser,7,&yymsp[-4].minor); - yy_destructor(yypParser,8,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1139 "NCDConfigParser_parse.c" - break; - case 7: /* statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON */ -#line 299 "NCDConfigParser_parse.y" -{ - if (!yymsp[-8].minor.yy19.have || !yymsp[-5].minor.yy69.have || !yymsp[-3].minor.yy44.have) { - goto failE0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-8].minor.yy19.v, yymsp[-5].minor.yy69.v); - yymsp[-8].minor.yy19.have = 0; - yymsp[-5].minor.yy69.have = 0; - - if (!NCDIfBlock_PrependIf(&yymsp[-3].minor.yy44.v, ifc)) { - NCDIf_Free(&ifc); - goto failE0; - } - - if (!NCDStatement_InitIf(&yygotominor.yy47.v, yymsp[-1].minor.yy49, yymsp[-3].minor.yy44.v, NCDIFTYPE_IF)) { - goto failE0; - } - yymsp[-3].minor.yy44.have = 0; - - if (yymsp[-2].minor.yy69.have) { - NCDStatement_IfAddElse(&yygotominor.yy47.v, yymsp[-2].minor.yy69.v); - yymsp[-2].minor.yy69.have = 0; - } - - yygotominor.yy47.have = 1; - goto doneE; - -failE0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneE: - free_value(yymsp[-8].minor.yy19); - free_block(yymsp[-5].minor.yy69); - free_ifblock(yymsp[-3].minor.yy44); - free_block(yymsp[-2].minor.yy69); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,11,&yymsp[-10].minor); - yy_destructor(yypParser,7,&yymsp[-9].minor); - yy_destructor(yypParser,8,&yymsp[-7].minor); - yy_destructor(yypParser,5,&yymsp[-6].minor); - yy_destructor(yypParser,6,&yymsp[-4].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1187 "NCDConfigParser_parse.c" - break; - case 8: /* statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON */ -#line 338 "NCDConfigParser_parse.y" -{ - if (!yymsp[-8].minor.yy19.have || !yymsp[-6].minor.yy0.str || !yymsp[-3].minor.yy69.have) { - goto failEA0; - } - - if (!NCDStatement_InitForeach(&yygotominor.yy47.v, yymsp[-1].minor.yy49, yymsp[-8].minor.yy19.v, yymsp[-6].minor.yy0.str, NULL, yymsp[-3].minor.yy69.v)) { - goto failEA0; - } - yymsp[-8].minor.yy19.have = 0; - yymsp[-3].minor.yy69.have = 0; - - yygotominor.yy47.have = 1; - goto doneEA0; - -failEA0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneEA0: - free_value(yymsp[-8].minor.yy19); - free_token(yymsp[-6].minor.yy0); - free_block(yymsp[-3].minor.yy69); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,12,&yymsp[-10].minor); - yy_destructor(yypParser,7,&yymsp[-9].minor); - yy_destructor(yypParser,13,&yymsp[-7].minor); - yy_destructor(yypParser,8,&yymsp[-5].minor); - yy_destructor(yypParser,5,&yymsp[-4].minor); - yy_destructor(yypParser,6,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1221 "NCDConfigParser_parse.c" - break; - case 9: /* statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON */ -#line 362 "NCDConfigParser_parse.y" -{ - if (!yymsp[-10].minor.yy19.have || !yymsp[-8].minor.yy0.str || !yymsp[-6].minor.yy0.str || !yymsp[-3].minor.yy69.have) { - goto failEB0; - } - - if (!NCDStatement_InitForeach(&yygotominor.yy47.v, yymsp[-1].minor.yy49, yymsp[-10].minor.yy19.v, yymsp[-8].minor.yy0.str, yymsp[-6].minor.yy0.str, yymsp[-3].minor.yy69.v)) { - goto failEB0; - } - yymsp[-10].minor.yy19.have = 0; - yymsp[-3].minor.yy69.have = 0; - - yygotominor.yy47.have = 1; - goto doneEB0; - -failEB0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneEB0: - free_value(yymsp[-10].minor.yy19); - free_token(yymsp[-8].minor.yy0); - free_token(yymsp[-6].minor.yy0); - free_block(yymsp[-3].minor.yy69); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,12,&yymsp[-12].minor); - yy_destructor(yypParser,7,&yymsp[-11].minor); - yy_destructor(yypParser,13,&yymsp[-9].minor); - yy_destructor(yypParser,14,&yymsp[-7].minor); - yy_destructor(yypParser,8,&yymsp[-5].minor); - yy_destructor(yypParser,5,&yymsp[-4].minor); - yy_destructor(yypParser,6,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1257 "NCDConfigParser_parse.c" - break; - case 10: /* elif_maybe ::= */ -#line 387 "NCDConfigParser_parse.y" -{ - NCDIfBlock_Init(&yygotominor.yy44.v); - yygotominor.yy44.have = 1; -} -#line 1265 "NCDConfigParser_parse.c" - break; - case 11: /* elif_maybe ::= elif */ -#line 392 "NCDConfigParser_parse.y" -{ - yygotominor.yy44 = yymsp[0].minor.yy44; -} -#line 1272 "NCDConfigParser_parse.c" - break; - case 12: /* elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE */ -#line 396 "NCDConfigParser_parse.y" -{ - if (!yymsp[-4].minor.yy19.have || !yymsp[-1].minor.yy69.have) { - goto failF0; - } - - NCDIfBlock_Init(&yygotominor.yy44.v); - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-4].minor.yy19.v, yymsp[-1].minor.yy69.v); - yymsp[-4].minor.yy19.have = 0; - yymsp[-1].minor.yy69.have = 0; - - if (!NCDIfBlock_PrependIf(&yygotominor.yy44.v, ifc)) { - goto failF1; - } - - yygotominor.yy44.have = 1; - goto doneF0; - -failF1: - NCDIf_Free(&ifc); - NCDIfBlock_Free(&yygotominor.yy44.v); -failF0: - yygotominor.yy44.have = 0; - parser_out->out_of_memory = 1; -doneF0: - free_value(yymsp[-4].minor.yy19); - free_block(yymsp[-1].minor.yy69); - yy_destructor(yypParser,15,&yymsp[-6].minor); - yy_destructor(yypParser,7,&yymsp[-5].minor); - yy_destructor(yypParser,8,&yymsp[-3].minor); - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1310 "NCDConfigParser_parse.c" - break; - case 13: /* elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif */ -#line 426 "NCDConfigParser_parse.y" -{ - if (!yymsp[-5].minor.yy19.have || !yymsp[-2].minor.yy69.have || !yymsp[0].minor.yy44.have) { - goto failG0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, yymsp[-5].minor.yy19.v, yymsp[-2].minor.yy69.v); - yymsp[-5].minor.yy19.have = 0; - yymsp[-2].minor.yy69.have = 0; - - if (!NCDIfBlock_PrependIf(&yymsp[0].minor.yy44.v, ifc)) { - goto failG1; - } - - yygotominor.yy44.have = 1; - yygotominor.yy44.v = yymsp[0].minor.yy44.v; - yymsp[0].minor.yy44.have = 0; - goto doneG0; - -failG1: - NCDIf_Free(&ifc); -failG0: - yygotominor.yy44.have = 0; - parser_out->out_of_memory = 1; -doneG0: - free_value(yymsp[-5].minor.yy19); - free_block(yymsp[-2].minor.yy69); - free_ifblock(yymsp[0].minor.yy44); - yy_destructor(yypParser,15,&yymsp[-7].minor); - yy_destructor(yypParser,7,&yymsp[-6].minor); - yy_destructor(yypParser,8,&yymsp[-4].minor); - yy_destructor(yypParser,5,&yymsp[-3].minor); - yy_destructor(yypParser,6,&yymsp[-1].minor); -} -#line 1348 "NCDConfigParser_parse.c" - break; - case 14: /* else_maybe ::= */ - case 17: /* interrupt_maybe ::= */ yytestcase(yyruleno==17); -#line 456 "NCDConfigParser_parse.y" -{ - yygotominor.yy69.have = 0; -} -#line 1356 "NCDConfigParser_parse.c" - break; - case 15: /* else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE */ -#line 460 "NCDConfigParser_parse.y" -{ - yygotominor.yy69 = yymsp[-1].minor.yy69; - yy_destructor(yypParser,16,&yymsp[-3].minor); - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1366 "NCDConfigParser_parse.c" - break; - case 16: /* statement ::= BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON */ -#line 464 "NCDConfigParser_parse.y" -{ - if (!yymsp[-3].minor.yy69.have) { - goto failGA0; - } - - if (!NCDStatement_InitBlock(&yygotominor.yy47.v, yymsp[-1].minor.yy49, yymsp[-3].minor.yy69.v)) { - goto failGA0; - } - yymsp[-3].minor.yy69.have = 0; - - yygotominor.yy47.have = 1; - goto doneGA0; - -failGA0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneGA0: - free_block(yymsp[-3].minor.yy69); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,17,&yymsp[-5].minor); - yy_destructor(yypParser,5,&yymsp[-4].minor); - yy_destructor(yypParser,6,&yymsp[-2].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1394 "NCDConfigParser_parse.c" - break; - case 18: /* interrupt_maybe ::= TOKEN_INTERRUPT CURLY_OPEN statements CURLY_CLOSE */ -#line 489 "NCDConfigParser_parse.y" -{ - yygotominor.yy69 = yymsp[-1].minor.yy69; - yy_destructor(yypParser,18,&yymsp[-3].minor); - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1404 "NCDConfigParser_parse.c" - break; - case 19: /* statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON */ -#line 493 "NCDConfigParser_parse.y" -{ - if (!yymsp[-4].minor.yy69.have) { - goto failGB0; - } - - NCDIfBlock if_block; - NCDIfBlock_Init(&if_block); - - if (yymsp[-2].minor.yy69.have) { - NCDIf int_if; - NCDIf_InitBlock(&int_if, yymsp[-2].minor.yy69.v); - yymsp[-2].minor.yy69.have = 0; - - if (!NCDIfBlock_PrependIf(&if_block, int_if)) { - NCDIf_Free(&int_if); - goto failGB1; - } - } - - NCDIf the_if; - NCDIf_InitBlock(&the_if, yymsp[-4].minor.yy69.v); - yymsp[-4].minor.yy69.have = 0; - - if (!NCDIfBlock_PrependIf(&if_block, the_if)) { - NCDIf_Free(&the_if); - goto failGB1; - } - - if (!NCDStatement_InitIf(&yygotominor.yy47.v, yymsp[-1].minor.yy49, if_block, NCDIFTYPE_DO)) { - goto failGB1; - } - - yygotominor.yy47.have = 1; - goto doneGB0; - -failGB1: - NCDIfBlock_Free(&if_block); -failGB0: - yygotominor.yy47.have = 0; - parser_out->out_of_memory = 1; -doneGB0: - free_block(yymsp[-4].minor.yy69); - free_block(yymsp[-2].minor.yy69); - free(yymsp[-1].minor.yy49); - yy_destructor(yypParser,19,&yymsp[-6].minor); - yy_destructor(yypParser,5,&yymsp[-5].minor); - yy_destructor(yypParser,6,&yymsp[-3].minor); - yy_destructor(yypParser,9,&yymsp[0].minor); -} -#line 1457 "NCDConfigParser_parse.c" - break; - case 20: /* statements ::= statement */ -#line 539 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy47.have) { - goto failH0; - } - - NCDBlock_Init(&yygotominor.yy69.v); - - if (!NCDBlock_PrependStatement(&yygotominor.yy69.v, yymsp[0].minor.yy47.v)) { - goto failH1; - } - yymsp[0].minor.yy47.have = 0; - - yygotominor.yy69.have = 1; - goto doneH; - -failH1: - NCDBlock_Free(&yygotominor.yy69.v); -failH0: - yygotominor.yy69.have = 0; - parser_out->out_of_memory = 1; -doneH: - free_statement(yymsp[0].minor.yy47); -} -#line 1484 "NCDConfigParser_parse.c" - break; - case 21: /* statements ::= statement statements */ -#line 563 "NCDConfigParser_parse.y" -{ - if (!yymsp[-1].minor.yy47.have || !yymsp[0].minor.yy69.have) { - goto failI0; - } - - if (!NCDBlock_PrependStatement(&yymsp[0].minor.yy69.v, yymsp[-1].minor.yy47.v)) { - goto failI1; - } - yymsp[-1].minor.yy47.have = 0; - - yygotominor.yy69.have = 1; - yygotominor.yy69.v = yymsp[0].minor.yy69.v; - yymsp[0].minor.yy69.have = 0; - goto doneI; - -failI1: - NCDBlock_Free(&yygotominor.yy69.v); -failI0: - yygotominor.yy69.have = 0; - parser_out->out_of_memory = 1; -doneI: - free_statement(yymsp[-1].minor.yy47); - free_block(yymsp[0].minor.yy69); -} -#line 1512 "NCDConfigParser_parse.c" - break; - case 22: /* dotted_name ::= NAME */ - case 46: /* name_maybe ::= NAME */ yytestcase(yyruleno==46); -#line 588 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - yygotominor.yy49 = yymsp[0].minor.yy0.str; -} -#line 1522 "NCDConfigParser_parse.c" - break; - case 23: /* dotted_name ::= NAME DOT dotted_name */ -#line 594 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[-2].minor.yy0.str) - if (!yymsp[0].minor.yy49) { - goto failJ0; - } - - if (!(yygotominor.yy49 = concat_strings(3, yymsp[-2].minor.yy0.str, ".", yymsp[0].minor.yy49))) { - goto failJ0; - } - - goto doneJ; - -failJ0: - yygotominor.yy49 = NULL; - parser_out->out_of_memory = 1; -doneJ: - free_token(yymsp[-2].minor.yy0); - free(yymsp[0].minor.yy49); - yy_destructor(yypParser,20,&yymsp[-1].minor); -} -#line 1546 "NCDConfigParser_parse.c" - break; - case 24: /* name_list ::= NAME */ -#line 614 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy0.str) { - goto failK0; - } - - NCDValue_InitList(&yygotominor.yy19.v); - - NCDValue this_string; - if (!NCDValue_InitString(&this_string, yymsp[0].minor.yy0.str)) { - goto failK1; - } - - if (!NCDValue_ListPrepend(&yygotominor.yy19.v, this_string)) { - goto failK2; - } - - yygotominor.yy19.have = 1; - goto doneK; - -failK2: - NCDValue_Free(&this_string); -failK1: - NCDValue_Free(&yygotominor.yy19.v); -failK0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneK: - free_token(yymsp[0].minor.yy0); -} -#line 1579 "NCDConfigParser_parse.c" - break; - case 25: /* name_list ::= NAME DOT name_list */ -#line 644 "NCDConfigParser_parse.y" -{ - if (!yymsp[-2].minor.yy0.str || !yymsp[0].minor.yy19.have) { - goto failKA0; - } - - NCDValue this_string; - if (!NCDValue_InitString(&this_string, yymsp[-2].minor.yy0.str)) { - goto failKA0; - } - - if (!NCDValue_ListPrepend(&yymsp[0].minor.yy19.v, this_string)) { - goto failKA1; - } - - yygotominor.yy19.have = 1; - yygotominor.yy19.v = yymsp[0].minor.yy19.v; - yymsp[0].minor.yy19.have = 0; - goto doneKA; - -failKA1: - NCDValue_Free(&this_string); -failKA0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneKA: - free_token(yymsp[-2].minor.yy0); - free_value(yymsp[0].minor.yy19); - yy_destructor(yypParser,20,&yymsp[-1].minor); -} -#line 1612 "NCDConfigParser_parse.c" - break; - case 26: /* list_contents_maybe ::= */ -#line 673 "NCDConfigParser_parse.y" -{ - yygotominor.yy19.have = 1; - NCDValue_InitList(&yygotominor.yy19.v); -} -#line 1620 "NCDConfigParser_parse.c" - break; - case 27: /* list_contents_maybe ::= list_contents */ - case 41: /* value ::= list */ yytestcase(yyruleno==41); - case 42: /* value ::= map */ yytestcase(yyruleno==42); - case 44: /* value ::= invoc */ yytestcase(yyruleno==44); -#line 678 "NCDConfigParser_parse.y" -{ - yygotominor.yy19 = yymsp[0].minor.yy19; -} -#line 1630 "NCDConfigParser_parse.c" - break; - case 28: /* list_contents ::= value */ -#line 682 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy19.have) { - goto failL0; - } - - NCDValue_InitList(&yygotominor.yy19.v); - - if (!NCDValue_ListPrepend(&yygotominor.yy19.v, yymsp[0].minor.yy19.v)) { - goto failL1; - } - yymsp[0].minor.yy19.have = 0; - - yygotominor.yy19.have = 1; - goto doneL; - -failL1: - NCDValue_Free(&yygotominor.yy19.v); -failL0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneL: - free_value(yymsp[0].minor.yy19); -} -#line 1657 "NCDConfigParser_parse.c" - break; - case 29: /* list_contents ::= value COMMA list_contents */ -#line 706 "NCDConfigParser_parse.y" -{ - if (!yymsp[-2].minor.yy19.have || !yymsp[0].minor.yy19.have) { - goto failM0; - } - - if (!NCDValue_ListPrepend(&yymsp[0].minor.yy19.v, yymsp[-2].minor.yy19.v)) { - goto failM0; - } - yymsp[-2].minor.yy19.have = 0; - - yygotominor.yy19.have = 1; - yygotominor.yy19.v = yymsp[0].minor.yy19.v; - yymsp[0].minor.yy19.have = 0; - goto doneM; - -failM0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneM: - free_value(yymsp[-2].minor.yy19); - free_value(yymsp[0].minor.yy19); - yy_destructor(yypParser,21,&yymsp[-1].minor); -} -#line 1684 "NCDConfigParser_parse.c" - break; - case 30: /* list ::= CURLY_OPEN CURLY_CLOSE */ -#line 729 "NCDConfigParser_parse.y" -{ - yygotominor.yy19.have = 1; - NCDValue_InitList(&yygotominor.yy19.v); - yy_destructor(yypParser,5,&yymsp[-1].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1694 "NCDConfigParser_parse.c" - break; - case 31: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */ -#line 734 "NCDConfigParser_parse.y" -{ - yygotominor.yy19 = yymsp[-1].minor.yy19; - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 1703 "NCDConfigParser_parse.c" - break; - case 32: /* map_contents ::= value COLON value */ -#line 738 "NCDConfigParser_parse.y" -{ - if (!yymsp[-2].minor.yy19.have || !yymsp[0].minor.yy19.have) { - goto failS0; - } - - NCDValue_InitMap(&yygotominor.yy19.v); - - if (!NCDValue_MapPrepend(&yygotominor.yy19.v, yymsp[-2].minor.yy19.v, yymsp[0].minor.yy19.v)) { - goto failS1; - } - yymsp[-2].minor.yy19.have = 0; - yymsp[0].minor.yy19.have = 0; - - yygotominor.yy19.have = 1; - goto doneS; - -failS1: - NCDValue_Free(&yygotominor.yy19.v); -failS0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneS: - free_value(yymsp[-2].minor.yy19); - free_value(yymsp[0].minor.yy19); - yy_destructor(yypParser,14,&yymsp[-1].minor); -} -#line 1733 "NCDConfigParser_parse.c" - break; - case 33: /* map_contents ::= value COLON value COMMA map_contents */ -#line 764 "NCDConfigParser_parse.y" -{ - if (!yymsp[-4].minor.yy19.have || !yymsp[-2].minor.yy19.have || !yymsp[0].minor.yy19.have) { - goto failT0; - } - - if (!NCDValue_MapPrepend(&yymsp[0].minor.yy19.v, yymsp[-4].minor.yy19.v, yymsp[-2].minor.yy19.v)) { - goto failT0; - } - yymsp[-4].minor.yy19.have = 0; - yymsp[-2].minor.yy19.have = 0; - - yygotominor.yy19.have = 1; - yygotominor.yy19.v = yymsp[0].minor.yy19.v; - yymsp[0].minor.yy19.have = 0; - goto doneT; - -failT0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneT: - free_value(yymsp[-4].minor.yy19); - free_value(yymsp[-2].minor.yy19); - free_value(yymsp[0].minor.yy19); - yy_destructor(yypParser,14,&yymsp[-3].minor); - yy_destructor(yypParser,21,&yymsp[-1].minor); -} -#line 1763 "NCDConfigParser_parse.c" - break; - case 34: /* map ::= BRACKET_OPEN BRACKET_CLOSE */ -#line 789 "NCDConfigParser_parse.y" -{ - yygotominor.yy19.have = 1; - NCDValue_InitMap(&yygotominor.yy19.v); - yy_destructor(yypParser,22,&yymsp[-1].minor); - yy_destructor(yypParser,23,&yymsp[0].minor); -} -#line 1773 "NCDConfigParser_parse.c" - break; - case 35: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */ -#line 794 "NCDConfigParser_parse.y" -{ - yygotominor.yy19 = yymsp[-1].minor.yy19; - yy_destructor(yypParser,22,&yymsp[-2].minor); - yy_destructor(yypParser,23,&yymsp[0].minor); -} -#line 1782 "NCDConfigParser_parse.c" - break; - case 36: /* invoc ::= value ROUND_OPEN list_contents_maybe ROUND_CLOSE */ -#line 798 "NCDConfigParser_parse.y" -{ - if (!yymsp[-3].minor.yy19.have || !yymsp[-1].minor.yy19.have) { - goto failQ0; - } - - if (!NCDValue_InitInvoc(&yygotominor.yy19.v, yymsp[-3].minor.yy19.v, yymsp[-1].minor.yy19.v)) { - goto failQ0; - } - yymsp[-3].minor.yy19.have = 0; - yymsp[-1].minor.yy19.have = 0; - yygotominor.yy19.have = 1; - goto doneQ; - -failQ0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneQ: - free_value(yymsp[-3].minor.yy19); - free_value(yymsp[-1].minor.yy19); - yy_destructor(yypParser,7,&yymsp[-2].minor); - yy_destructor(yypParser,8,&yymsp[0].minor); -} -#line 1808 "NCDConfigParser_parse.c" - break; - case 37: /* value ::= STRING */ -#line 819 "NCDConfigParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - if (!NCDValue_InitStringBin(&yygotominor.yy19.v, (uint8_t *)yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len)) { - goto failU0; - } - - yygotominor.yy19.have = 1; - goto doneU; - -failU0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneU: - free_token(yymsp[0].minor.yy0); -} -#line 1828 "NCDConfigParser_parse.c" - break; - case 38: /* value ::= AT_SIGN dotted_name */ -#line 836 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy49) { - goto failUA0; - } - - if (!NCDValue_InitString(&yygotominor.yy19.v, yymsp[0].minor.yy49)) { - goto failUA0; - } - - yygotominor.yy19.have = 1; - goto doneUA0; - -failUA0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneUA0: - free(yymsp[0].minor.yy49); - yy_destructor(yypParser,24,&yymsp[-1].minor); -} -#line 1851 "NCDConfigParser_parse.c" - break; - case 39: /* value ::= CARET name_list */ -#line 855 "NCDConfigParser_parse.y" -{ - yygotominor.yy19 = yymsp[0].minor.yy19; - yy_destructor(yypParser,25,&yymsp[-1].minor); -} -#line 1859 "NCDConfigParser_parse.c" - break; - case 40: /* value ::= dotted_name */ -#line 859 "NCDConfigParser_parse.y" -{ - if (!yymsp[0].minor.yy49) { - goto failV0; - } - - if (!NCDValue_InitVar(&yygotominor.yy19.v, yymsp[0].minor.yy49)) { - goto failV0; - } - - yygotominor.yy19.have = 1; - goto doneV; - -failV0: - yygotominor.yy19.have = 0; - parser_out->out_of_memory = 1; -doneV: - free(yymsp[0].minor.yy49); -} -#line 1881 "NCDConfigParser_parse.c" - break; - case 43: /* value ::= ROUND_OPEN value ROUND_CLOSE */ -#line 886 "NCDConfigParser_parse.y" -{ - yygotominor.yy19 = yymsp[-1].minor.yy19; - yy_destructor(yypParser,7,&yymsp[-2].minor); - yy_destructor(yypParser,8,&yymsp[0].minor); -} -#line 1890 "NCDConfigParser_parse.c" - break; - case 45: /* name_maybe ::= */ -#line 894 "NCDConfigParser_parse.y" -{ - yygotominor.yy49 = NULL; -} -#line 1897 "NCDConfigParser_parse.c" - break; - case 47: /* process_or_template ::= PROCESS */ -#line 904 "NCDConfigParser_parse.y" -{ - yygotominor.yy28 = 0; - yy_destructor(yypParser,26,&yymsp[0].minor); -} -#line 1905 "NCDConfigParser_parse.c" - break; - case 48: /* process_or_template ::= TEMPLATE */ -#line 908 "NCDConfigParser_parse.y" -{ - yygotominor.yy28 = 1; - yy_destructor(yypParser,27,&yymsp[0].minor); -} -#line 1913 "NCDConfigParser_parse.c" - break; - default: - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 131 "NCDConfigParser_parse.y" - - parser_out->syntax_error = 1; -#line 1978 "NCDConfigParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyactyyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/v2rayng/badvpn/generated/NCDConfigParser_parse.h b/v2rayng/badvpn/generated/NCDConfigParser_parse.h deleted file mode 100644 index fe4310d970..0000000000 --- a/v2rayng/badvpn/generated/NCDConfigParser_parse.h +++ /dev/null @@ -1,27 +0,0 @@ -#define INCLUDE 1 -#define STRING 2 -#define INCLUDE_GUARD 3 -#define NAME 4 -#define CURLY_OPEN 5 -#define CURLY_CLOSE 6 -#define ROUND_OPEN 7 -#define ROUND_CLOSE 8 -#define SEMICOLON 9 -#define ARROW 10 -#define IF 11 -#define FOREACH 12 -#define AS 13 -#define COLON 14 -#define ELIF 15 -#define ELSE 16 -#define BLOCK 17 -#define TOKEN_INTERRUPT 18 -#define TOKEN_DO 19 -#define DOT 20 -#define COMMA 21 -#define BRACKET_OPEN 22 -#define BRACKET_CLOSE 23 -#define AT_SIGN 24 -#define CARET 25 -#define PROCESS 26 -#define TEMPLATE 27 diff --git a/v2rayng/badvpn/generated/NCDConfigParser_parse.out b/v2rayng/badvpn/generated/NCDConfigParser_parse.out deleted file mode 100644 index 4381763247..0000000000 --- a/v2rayng/badvpn/generated/NCDConfigParser_parse.out +++ /dev/null @@ -1,1381 +0,0 @@ -State 0: - input ::= * processes - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 52 - INCLUDE_GUARD shift 53 - PROCESS shift 97 - TEMPLATE shift 98 - processes shift 51 - process_or_template shift 54 - input accept - {default} reduce 1 - -State 1: - statement ::= dotted_name ROUND_OPEN * list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - (26) list_contents_maybe ::= * - list_contents_maybe ::= * list_contents - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list_contents_maybe shift 57 - list_contents shift 102 - list shift 112 - map shift 113 - invoc shift 115 - value shift 43 - {default} reduce 26 - -State 2: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - (26) list_contents_maybe ::= * - list_contents_maybe ::= * list_contents - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - invoc ::= value ROUND_OPEN * list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list_contents_maybe shift 62 - list_contents shift 102 - list shift 112 - map shift 113 - invoc shift 115 - value shift 43 - {default} reduce 26 - -State 3: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN * list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - (26) list_contents_maybe ::= * - list_contents_maybe ::= * list_contents - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list_contents_maybe shift 65 - list_contents shift 102 - list shift 112 - map shift 113 - invoc shift 115 - value shift 43 - {default} reduce 26 - -State 4: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= CURLY_OPEN * CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - list ::= CURLY_OPEN * list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - CURLY_CLOSE shift 104 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list_contents shift 60 - list shift 112 - map shift 113 - invoc shift 115 - value shift 43 - -State 5: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= BRACKET_OPEN * BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - map ::= BRACKET_OPEN * map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - BRACKET_CLOSE shift 117 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map_contents shift 63 - map shift 113 - invoc shift 115 - value shift 44 - -State 6: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list_contents ::= value COMMA * list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list_contents shift 103 - list shift 112 - map shift 113 - invoc shift 115 - value shift 43 - -State 7: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map_contents ::= value COLON value COMMA * map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map_contents shift 106 - map shift 113 - invoc shift 115 - value shift 44 - -State 8: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= value COLON * value - map_contents ::= value COLON * value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map shift 113 - invoc shift 115 - value shift 45 - -State 9: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= ROUND_OPEN * value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map shift 113 - invoc shift 115 - value shift 46 - -State 10: - statement ::= IF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map shift 113 - invoc shift 115 - value shift 47 - -State 11: - statement ::= FOREACH ROUND_OPEN * value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN * value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map shift 113 - invoc shift 115 - value shift 48 - -State 12: - elif ::= ELIF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN * value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - invoc ::= * value ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= * STRING - value ::= * AT_SIGN dotted_name - value ::= * CARET name_list - value ::= * dotted_name - value ::= * list - value ::= * map - value ::= * ROUND_OPEN value ROUND_CLOSE - value ::= * invoc - - STRING shift 107 - NAME shift 59 - CURLY_OPEN shift 4 - ROUND_OPEN shift 9 - BRACKET_OPEN shift 5 - AT_SIGN shift 29 - CARET shift 30 - dotted_name shift 111 - list shift 112 - map shift 113 - invoc shift 115 - value shift 50 - -State 13: - processes ::= process_or_template NAME CURLY_OPEN * statements CURLY_CLOSE processes - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 56 - dotted_name shift 42 - -State 14: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 69 - dotted_name shift 42 - -State 15: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - else_maybe ::= ELSE CURLY_OPEN * statements CURLY_CLOSE - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 90 - dotted_name shift 42 - -State 16: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 75 - dotted_name shift 42 - -State 17: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= BLOCK CURLY_OPEN * statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 78 - dotted_name shift 42 - -State 18: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statement ::= TOKEN_DO CURLY_OPEN * statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 81 - dotted_name shift 42 - -State 19: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - interrupt_maybe ::= TOKEN_INTERRUPT CURLY_OPEN * statements CURLY_CLOSE - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 83 - dotted_name shift 42 - -State 20: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - (20) statements ::= statement * - statements ::= * statement statements - statements ::= statement * statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 124 - dotted_name shift 42 - {default} reduce 20 - -State 21: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 88 - dotted_name shift 42 - -State 22: - statement ::= * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= * IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN * statements CURLY_CLOSE elif - statement ::= * BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= * TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - statements ::= * statement - statements ::= * statement statements - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - IF shift 67 - FOREACH shift 72 - BLOCK shift 77 - TOKEN_DO shift 80 - statement shift 20 - statements shift 93 - dotted_name shift 42 - -State 23: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= INCLUDE STRING * processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 52 - INCLUDE_GUARD shift 53 - PROCESS shift 97 - TEMPLATE shift 98 - processes shift 94 - process_or_template shift 54 - {default} reduce 1 - -State 24: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= INCLUDE_GUARD STRING * processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 52 - INCLUDE_GUARD shift 53 - PROCESS shift 97 - TEMPLATE shift 98 - processes shift 95 - process_or_template shift 54 - {default} reduce 1 - -State 25: - (1) processes ::= * - processes ::= * INCLUDE STRING processes - processes ::= * INCLUDE_GUARD STRING processes - processes ::= * process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes - processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE * processes - process_or_template ::= * PROCESS - process_or_template ::= * TEMPLATE - - INCLUDE shift 52 - INCLUDE_GUARD shift 53 - PROCESS shift 97 - TEMPLATE shift 98 - processes shift 96 - process_or_template shift 54 - {default} reduce 1 - -State 26: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * elif_maybe else_maybe name_maybe SEMICOLON - (10) elif_maybe ::= * - elif_maybe ::= * elif - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - - ELIF shift 91 - elif_maybe shift 34 - elif shift 128 - {default} reduce 10 - -State 27: - statement ::= dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 58 - {default} reduce 45 - -State 28: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - dotted_name ::= NAME DOT * dotted_name - - NAME shift 59 - dotted_name shift 101 - -State 29: - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - value ::= AT_SIGN * dotted_name - - NAME shift 59 - dotted_name shift 108 - -State 30: - name_list ::= * NAME - name_list ::= * NAME DOT name_list - value ::= CARET * name_list - - NAME shift 61 - name_list shift 110 - -State 31: - name_list ::= * NAME - name_list ::= * NAME DOT name_list - name_list ::= NAME DOT * name_list - - NAME shift 61 - name_list shift 109 - -State 32: - statement ::= dotted_name ARROW * dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - dotted_name ::= * NAME - dotted_name ::= * NAME DOT dotted_name - - NAME shift 59 - dotted_name shift 64 - -State 33: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 66 - {default} reduce 45 - -State 34: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe * else_maybe name_maybe SEMICOLON - (14) else_maybe ::= * - else_maybe ::= * ELSE CURLY_OPEN statements CURLY_CLOSE - - ELSE shift 71 - else_maybe shift 35 - {default} reduce 14 - -State 35: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 70 - {default} reduce 45 - -State 36: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 76 - {default} reduce 45 - -State 37: - statement ::= BLOCK CURLY_OPEN statements CURLY_CLOSE * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 79 - {default} reduce 45 - -State 38: - (17) interrupt_maybe ::= * - interrupt_maybe ::= * TOKEN_INTERRUPT CURLY_OPEN statements CURLY_CLOSE - statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE * interrupt_maybe name_maybe SEMICOLON - - TOKEN_INTERRUPT shift 82 - interrupt_maybe shift 39 - {default} reduce 17 - -State 39: - statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 84 - {default} reduce 45 - -State 40: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * name_maybe SEMICOLON - (45) name_maybe ::= * - name_maybe ::= * NAME - - NAME shift 100 - name_maybe shift 89 - {default} reduce 45 - -State 41: - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - (12) elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * - elif ::= * ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE * elif - - ELIF shift 91 - elif shift 129 - {default} reduce 12 - -State 42: - statement ::= dotted_name * ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - statement ::= dotted_name * ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 1 - ARROW shift 32 - -State 43: - (28) list_contents ::= value * - list_contents ::= value * COMMA list_contents - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - COMMA shift 6 - {default} reduce 28 - -State 44: - map_contents ::= value * COLON value - map_contents ::= value * COLON value COMMA map_contents - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - COLON shift 8 - -State 45: - (32) map_contents ::= value COLON value * - map_contents ::= value COLON value * COMMA map_contents - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - COMMA shift 7 - {default} reduce 32 - -State 46: - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - value ::= ROUND_OPEN value * ROUND_CLOSE - - ROUND_OPEN shift 2 - ROUND_CLOSE shift 116 - -State 47: - statement ::= IF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - ROUND_CLOSE shift 68 - -State 48: - statement ::= FOREACH ROUND_OPEN value * AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value * AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - AS shift 73 - -State 49: - statement ::= FOREACH ROUND_OPEN value AS NAME * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS NAME * COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 74 - COLON shift 85 - -State 50: - elif ::= ELIF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - invoc ::= value * ROUND_OPEN list_contents_maybe ROUND_CLOSE - - ROUND_OPEN shift 2 - ROUND_CLOSE shift 92 - -State 51: - (0) input ::= processes * - - $ reduce 0 - -State 52: - processes ::= INCLUDE * STRING processes - - STRING shift 23 - -State 53: - processes ::= INCLUDE_GUARD * STRING processes - - STRING shift 24 - -State 54: - processes ::= process_or_template * NAME CURLY_OPEN statements CURLY_CLOSE processes - - NAME shift 55 - -State 55: - processes ::= process_or_template NAME * CURLY_OPEN statements CURLY_CLOSE processes - - CURLY_OPEN shift 13 - -State 56: - processes ::= process_or_template NAME CURLY_OPEN statements * CURLY_CLOSE processes - - CURLY_CLOSE shift 25 - -State 57: - statement ::= dotted_name ROUND_OPEN list_contents_maybe * ROUND_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 27 - -State 58: - statement ::= dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 99 - -State 59: - (22) dotted_name ::= NAME * - dotted_name ::= NAME * DOT dotted_name - - DOT shift 28 - {default} reduce 22 - -State 60: - list ::= CURLY_OPEN list_contents * CURLY_CLOSE - - CURLY_CLOSE shift 105 - -State 61: - (24) name_list ::= NAME * - name_list ::= NAME * DOT name_list - - DOT shift 31 - {default} reduce 24 - -State 62: - invoc ::= value ROUND_OPEN list_contents_maybe * ROUND_CLOSE - - ROUND_CLOSE shift 114 - -State 63: - map ::= BRACKET_OPEN map_contents * BRACKET_CLOSE - - BRACKET_CLOSE shift 118 - -State 64: - statement ::= dotted_name ARROW dotted_name * ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 3 - -State 65: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe * ROUND_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 33 - -State 66: - statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 119 - -State 67: - statement ::= IF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - ROUND_OPEN shift 10 - -State 68: - statement ::= IF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - CURLY_OPEN shift 14 - -State 69: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON - - CURLY_CLOSE shift 26 - -State 70: - statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe * SEMICOLON - - SEMICOLON shift 120 - -State 71: - else_maybe ::= ELSE * CURLY_OPEN statements CURLY_CLOSE - - CURLY_OPEN shift 15 - -State 72: - statement ::= FOREACH * ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH * ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_OPEN shift 11 - -State 73: - statement ::= FOREACH ROUND_OPEN value AS * NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - statement ::= FOREACH ROUND_OPEN value AS * NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - NAME shift 49 - -State 74: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - CURLY_OPEN shift 16 - -State 75: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE name_maybe SEMICOLON - - CURLY_CLOSE shift 36 - -State 76: - statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 121 - -State 77: - statement ::= BLOCK * CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - CURLY_OPEN shift 17 - -State 78: - statement ::= BLOCK CURLY_OPEN statements * CURLY_CLOSE name_maybe SEMICOLON - - CURLY_CLOSE shift 37 - -State 79: - statement ::= BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 122 - -State 80: - statement ::= TOKEN_DO * CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - - CURLY_OPEN shift 18 - -State 81: - statement ::= TOKEN_DO CURLY_OPEN statements * CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON - - CURLY_CLOSE shift 38 - -State 82: - interrupt_maybe ::= TOKEN_INTERRUPT * CURLY_OPEN statements CURLY_CLOSE - - CURLY_OPEN shift 19 - -State 83: - interrupt_maybe ::= TOKEN_INTERRUPT CURLY_OPEN statements * CURLY_CLOSE - - CURLY_CLOSE shift 123 - -State 84: - statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe * SEMICOLON - - SEMICOLON shift 125 - -State 85: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON * NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - NAME shift 86 - -State 86: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME * ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - ROUND_CLOSE shift 87 - -State 87: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON - - CURLY_OPEN shift 21 - -State 88: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE name_maybe SEMICOLON - - CURLY_CLOSE shift 40 - -State 89: - statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe * SEMICOLON - - SEMICOLON shift 126 - -State 90: - else_maybe ::= ELSE CURLY_OPEN statements * CURLY_CLOSE - - CURLY_CLOSE shift 127 - -State 91: - elif ::= ELIF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF * ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif - - ROUND_OPEN shift 12 - -State 92: - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE * CURLY_OPEN statements CURLY_CLOSE elif - - CURLY_OPEN shift 22 - -State 93: - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE - elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements * CURLY_CLOSE elif - - CURLY_CLOSE shift 41 - -State 94: - (2) processes ::= INCLUDE STRING processes * - - {default} reduce 2 - -State 95: - (3) processes ::= INCLUDE_GUARD STRING processes * - - {default} reduce 3 - -State 96: - (4) processes ::= process_or_template NAME CURLY_OPEN statements CURLY_CLOSE processes * - - {default} reduce 4 - -State 97: - (47) process_or_template ::= PROCESS * - - {default} reduce 47 - -State 98: - (48) process_or_template ::= TEMPLATE * - - {default} reduce 48 - -State 99: - (5) statement ::= dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON * - - {default} reduce 5 - -State 100: - (46) name_maybe ::= NAME * - - {default} reduce 46 - -State 101: - (23) dotted_name ::= NAME DOT dotted_name * - - {default} reduce 23 - -State 102: - (27) list_contents_maybe ::= list_contents * - - {default} reduce 27 - -State 103: - (29) list_contents ::= value COMMA list_contents * - - {default} reduce 29 - -State 104: - (30) list ::= CURLY_OPEN CURLY_CLOSE * - - {default} reduce 30 - -State 105: - (31) list ::= CURLY_OPEN list_contents CURLY_CLOSE * - - {default} reduce 31 - -State 106: - (33) map_contents ::= value COLON value COMMA map_contents * - - {default} reduce 33 - -State 107: - (37) value ::= STRING * - - {default} reduce 37 - -State 108: - (38) value ::= AT_SIGN dotted_name * - - {default} reduce 38 - -State 109: - (25) name_list ::= NAME DOT name_list * - - {default} reduce 25 - -State 110: - (39) value ::= CARET name_list * - - {default} reduce 39 - -State 111: - (40) value ::= dotted_name * - - {default} reduce 40 - -State 112: - (41) value ::= list * - - {default} reduce 41 - -State 113: - (42) value ::= map * - - {default} reduce 42 - -State 114: - (36) invoc ::= value ROUND_OPEN list_contents_maybe ROUND_CLOSE * - - {default} reduce 36 - -State 115: - (44) value ::= invoc * - - {default} reduce 44 - -State 116: - (43) value ::= ROUND_OPEN value ROUND_CLOSE * - - {default} reduce 43 - -State 117: - (34) map ::= BRACKET_OPEN BRACKET_CLOSE * - - {default} reduce 34 - -State 118: - (35) map ::= BRACKET_OPEN map_contents BRACKET_CLOSE * - - {default} reduce 35 - -State 119: - (6) statement ::= dotted_name ARROW dotted_name ROUND_OPEN list_contents_maybe ROUND_CLOSE name_maybe SEMICOLON * - - {default} reduce 6 - -State 120: - (7) statement ::= IF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif_maybe else_maybe name_maybe SEMICOLON * - - {default} reduce 7 - -State 121: - (8) statement ::= FOREACH ROUND_OPEN value AS NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON * - - {default} reduce 8 - -State 122: - (16) statement ::= BLOCK CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON * - - {default} reduce 16 - -State 123: - (18) interrupt_maybe ::= TOKEN_INTERRUPT CURLY_OPEN statements CURLY_CLOSE * - - {default} reduce 18 - -State 124: - (21) statements ::= statement statements * - - {default} reduce 21 - -State 125: - (19) statement ::= TOKEN_DO CURLY_OPEN statements CURLY_CLOSE interrupt_maybe name_maybe SEMICOLON * - - {default} reduce 19 - -State 126: - (9) statement ::= FOREACH ROUND_OPEN value AS NAME COLON NAME ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE name_maybe SEMICOLON * - - {default} reduce 9 - -State 127: - (15) else_maybe ::= ELSE CURLY_OPEN statements CURLY_CLOSE * - - {default} reduce 15 - -State 128: - (11) elif_maybe ::= elif * - - {default} reduce 11 - -State 129: - (13) elif ::= ELIF ROUND_OPEN value ROUND_CLOSE CURLY_OPEN statements CURLY_CLOSE elif * - - {default} reduce 13 - ----------------------------------------------------- -Symbols: - 0: $: - 1: INCLUDE - 2: STRING - 3: INCLUDE_GUARD - 4: NAME - 5: CURLY_OPEN - 6: CURLY_CLOSE - 7: ROUND_OPEN - 8: ROUND_CLOSE - 9: SEMICOLON - 10: ARROW - 11: IF - 12: FOREACH - 13: AS - 14: COLON - 15: ELIF - 16: ELSE - 17: BLOCK - 18: TOKEN_INTERRUPT - 19: TOKEN_DO - 20: DOT - 21: COMMA - 22: BRACKET_OPEN - 23: BRACKET_CLOSE - 24: AT_SIGN - 25: CARET - 26: PROCESS - 27: TEMPLATE - 28: error: - 29: processes: INCLUDE INCLUDE_GUARD PROCESS TEMPLATE - 30: statement: NAME IF FOREACH BLOCK TOKEN_DO - 31: elif_maybe: ELIF - 32: elif: ELIF - 33: else_maybe: ELSE - 34: statements: NAME IF FOREACH BLOCK TOKEN_DO - 35: dotted_name: NAME - 36: list_contents_maybe: STRING NAME CURLY_OPEN ROUND_OPEN BRACKET_OPEN AT_SIGN CARET - 37: list_contents: STRING NAME CURLY_OPEN ROUND_OPEN BRACKET_OPEN AT_SIGN CARET - 38: list: CURLY_OPEN - 39: map_contents: STRING NAME CURLY_OPEN ROUND_OPEN BRACKET_OPEN AT_SIGN CARET - 40: map: BRACKET_OPEN - 41: invoc: STRING NAME CURLY_OPEN ROUND_OPEN BRACKET_OPEN AT_SIGN CARET - 42: value: STRING NAME CURLY_OPEN ROUND_OPEN BRACKET_OPEN AT_SIGN CARET - 43: name_maybe: NAME - 44: process_or_template: PROCESS TEMPLATE - 45: name_list: NAME - 46: interrupt_maybe: TOKEN_INTERRUPT - 47: input: INCLUDE INCLUDE_GUARD PROCESS TEMPLATE diff --git a/v2rayng/badvpn/generated/NCDConfigParser_parse.y b/v2rayng/badvpn/generated/NCDConfigParser_parse.y deleted file mode 100644 index 17e86fd15e..0000000000 --- a/v2rayng/badvpn/generated/NCDConfigParser_parse.y +++ /dev/null @@ -1,910 +0,0 @@ -/** - * @file NCDConfigParser.y - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -%include { - -#include -#include - -#include -#include -#include - -struct parser_out { - int out_of_memory; - int syntax_error; - int have_ast; - NCDProgram ast; -}; - -struct token { - char *str; - size_t len; -}; - -struct program { - int have; - NCDProgram v; -}; - -struct block { - int have; - NCDBlock v; -}; - -struct statement { - int have; - NCDStatement v; -}; - -struct ifblock { - int have; - NCDIfBlock v; -}; - -struct value { - int have; - NCDValue v; -}; - -static void free_token (struct token o) { free(o.str); } -static void free_program (struct program o) { if (o.have) NCDProgram_Free(&o.v); } -static void free_block (struct block o) { if (o.have) NCDBlock_Free(&o.v); } -static void free_statement (struct statement o) { if (o.have) NCDStatement_Free(&o.v); } -static void free_ifblock (struct ifblock o) { if (o.have) NCDIfBlock_Free(&o.v); } -static void free_value (struct value o) { if (o.have) NCDValue_Free(&o.v); } - -} - -%extra_argument { struct parser_out *parser_out } - -%token_type { struct token } - -%token_destructor { free_token($$); } - -%type processes { struct program } -%type statement { struct statement } -%type elif_maybe { struct ifblock } -%type elif { struct ifblock } -%type else_maybe { struct block } -%type statements { struct block } -%type dotted_name { char * } -%type list_contents_maybe { struct value } -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type invoc { struct value } -%type value { struct value } -%type name_maybe { char * } -%type process_or_template { int } -%type name_list { struct value } -%type interrupt_maybe { struct block } - -// mention parser_out in some destructor to avoid an unused-variable warning -%destructor processes { (void)parser_out; free_program($$); } -%destructor statement { free_statement($$); } -%destructor elif_maybe { free_ifblock($$); } -%destructor elif { free_ifblock($$); } -%destructor else_maybe { free_block($$); } -%destructor statements { free_block($$); } -%destructor dotted_name { free($$); } -%destructor list_contents_maybe { free_value($$); } -%destructor list_contents { free_value($$); } -%destructor list { free_value($$); } -%destructor map_contents { free_value($$); } -%destructor map { free_value($$); } -%destructor invoc { free_value($$); } -%destructor value { free_value($$); } -%destructor name_maybe { free($$); } -%destructor name_list { free_value($$); } -%destructor interrupt_maybe { free_block($$); } - -%stack_size 0 - -%syntax_error { - parser_out->syntax_error = 1; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= processes(A). { - ASSERT(!parser_out->have_ast) - - if (A.have) { - parser_out->have_ast = 1; - parser_out->ast = A.v; - } -} - -processes(R) ::= . { - NCDProgram prog; - NCDProgram_Init(&prog); - - R.have = 1; - R.v = prog; -} - -processes(R) ::= INCLUDE STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failA0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitInclude(&elem, A.str, A.len)) { - goto failA0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failA1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneA; - -failA1: - NCDProgramElem_Free(&elem); -failA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneA: - free_token(A); - free_program(N); -} - -processes(R) ::= INCLUDE_GUARD STRING(A) processes(N). { - ASSERT(A.str) - if (!N.have) { - goto failZ0; - } - - NCDProgramElem elem; - if (!NCDProgramElem_InitIncludeGuard(&elem, A.str, A.len)) { - goto failZ0; - } - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failZ1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneZ; - -failZ1: - NCDProgramElem_Free(&elem); -failZ0: - R.have = 0; - parser_out->out_of_memory = 1; -doneZ: - free_token(A); - free_program(N); -} - -processes(R) ::= process_or_template(T) NAME(A) CURLY_OPEN statements(B) CURLY_CLOSE processes(N). { - ASSERT(A.str) - if (!B.have || !N.have) { - goto failB0; - } - - NCDProcess proc; - if (!NCDProcess_Init(&proc, T, A.str, B.v)) { - goto failB0; - } - B.have = 0; - - NCDProgramElem elem; - NCDProgramElem_InitProcess(&elem, proc); - - if (!NCDProgram_PrependElem(&N.v, elem)) { - goto failB1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneB; - -failB1: - NCDProgramElem_Free(&elem); -failB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneB: - free_token(A); - free_block(B); - free_program(N); -} - -statement(R) ::= dotted_name(A) ROUND_OPEN list_contents_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!A || !B.have) { - goto failC0; - } - - if (!NCDStatement_InitReg(&R.v, C, NULL, A, B.v)) { - goto failC0; - } - B.have = 0; - - R.have = 1; - goto doneC; - -failC0: - R.have = 0; - parser_out->out_of_memory = 1; -doneC: - free(A); - free_value(B); - free(C); -} - -statement(R) ::= dotted_name(M) ARROW dotted_name(A) ROUND_OPEN list_contents_maybe(B) ROUND_CLOSE name_maybe(C) SEMICOLON. { - if (!M || !A || !B.have) { - goto failD0; - } - - if (!NCDStatement_InitReg(&R.v, C, M, A, B.v)) { - goto failD0; - } - B.have = 0; - - R.have = 1; - goto doneD; - -failD0: - R.have = 0; - parser_out->out_of_memory = 1; -doneD: - free(M); - free(A); - free_value(B); - free(C); -} - -statement(R) ::= IF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif_maybe(I) else_maybe(E) name_maybe(C) SEMICOLON. { - if (!A.have || !B.have || !I.have) { - goto failE0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&I.v, ifc)) { - NCDIf_Free(&ifc); - goto failE0; - } - - if (!NCDStatement_InitIf(&R.v, C, I.v, NCDIFTYPE_IF)) { - goto failE0; - } - I.have = 0; - - if (E.have) { - NCDStatement_IfAddElse(&R.v, E.v); - E.have = 0; - } - - R.have = 1; - goto doneE; - -failE0: - R.have = 0; - parser_out->out_of_memory = 1; -doneE: - free_value(A); - free_block(B); - free_ifblock(I); - free_block(E); - free(C); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !S.have) { - goto failEA0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, NULL, S.v)) { - goto failEA0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEA0; - -failEA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEA0: - free_value(A); - free_token(B); - free_block(S); - free(N); -} - -statement(R) ::= FOREACH ROUND_OPEN value(A) AS NAME(B) COLON NAME(C) ROUND_CLOSE CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!A.have || !B.str || !C.str || !S.have) { - goto failEB0; - } - - if (!NCDStatement_InitForeach(&R.v, N, A.v, B.str, C.str, S.v)) { - goto failEB0; - } - A.have = 0; - S.have = 0; - - R.have = 1; - goto doneEB0; - -failEB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneEB0: - free_value(A); - free_token(B); - free_token(C); - free_block(S); - free(N); -} - -elif_maybe(R) ::= . { - NCDIfBlock_Init(&R.v); - R.have = 1; -} - -elif_maybe(R) ::= elif(A). { - R = A; -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE. { - if (!A.have || !B.have) { - goto failF0; - } - - NCDIfBlock_Init(&R.v); - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&R.v, ifc)) { - goto failF1; - } - - R.have = 1; - goto doneF0; - -failF1: - NCDIf_Free(&ifc); - NCDIfBlock_Free(&R.v); -failF0: - R.have = 0; - parser_out->out_of_memory = 1; -doneF0: - free_value(A); - free_block(B); -} - -elif(R) ::= ELIF ROUND_OPEN value(A) ROUND_CLOSE CURLY_OPEN statements(B) CURLY_CLOSE elif(N). { - if (!A.have || !B.have || !N.have) { - goto failG0; - } - - NCDIf ifc; - NCDIf_Init(&ifc, A.v, B.v); - A.have = 0; - B.have = 0; - - if (!NCDIfBlock_PrependIf(&N.v, ifc)) { - goto failG1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneG0; - -failG1: - NCDIf_Free(&ifc); -failG0: - R.have = 0; - parser_out->out_of_memory = 1; -doneG0: - free_value(A); - free_block(B); - free_ifblock(N); -} - -else_maybe(R) ::= . { - R.have = 0; -} - -else_maybe(R) ::= ELSE CURLY_OPEN statements(B) CURLY_CLOSE. { - R = B; -} - -statement(R) ::= BLOCK CURLY_OPEN statements(S) CURLY_CLOSE name_maybe(N) SEMICOLON. { - if (!S.have) { - goto failGA0; - } - - if (!NCDStatement_InitBlock(&R.v, N, S.v)) { - goto failGA0; - } - S.have = 0; - - R.have = 1; - goto doneGA0; - -failGA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneGA0: - free_block(S); - free(N); -} - -interrupt_maybe(R) ::= . { - R.have = 0; -} - -interrupt_maybe(R) ::= TOKEN_INTERRUPT CURLY_OPEN statements(S) CURLY_CLOSE. { - R = S; -} - -statement(R) ::= TOKEN_DO CURLY_OPEN statements(S) CURLY_CLOSE interrupt_maybe(I) name_maybe(N) SEMICOLON. { - if (!S.have) { - goto failGB0; - } - - NCDIfBlock if_block; - NCDIfBlock_Init(&if_block); - - if (I.have) { - NCDIf int_if; - NCDIf_InitBlock(&int_if, I.v); - I.have = 0; - - if (!NCDIfBlock_PrependIf(&if_block, int_if)) { - NCDIf_Free(&int_if); - goto failGB1; - } - } - - NCDIf the_if; - NCDIf_InitBlock(&the_if, S.v); - S.have = 0; - - if (!NCDIfBlock_PrependIf(&if_block, the_if)) { - NCDIf_Free(&the_if); - goto failGB1; - } - - if (!NCDStatement_InitIf(&R.v, N, if_block, NCDIFTYPE_DO)) { - goto failGB1; - } - - R.have = 1; - goto doneGB0; - -failGB1: - NCDIfBlock_Free(&if_block); -failGB0: - R.have = 0; - parser_out->out_of_memory = 1; -doneGB0: - free_block(S); - free_block(I); - free(N); -} - -statements(R) ::= statement(A). { - if (!A.have) { - goto failH0; - } - - NCDBlock_Init(&R.v); - - if (!NCDBlock_PrependStatement(&R.v, A.v)) { - goto failH1; - } - A.have = 0; - - R.have = 1; - goto doneH; - -failH1: - NCDBlock_Free(&R.v); -failH0: - R.have = 0; - parser_out->out_of_memory = 1; -doneH: - free_statement(A); -} - -statements(R) ::= statement(A) statements(N). { - if (!A.have || !N.have) { - goto failI0; - } - - if (!NCDBlock_PrependStatement(&N.v, A.v)) { - goto failI1; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneI; - -failI1: - NCDBlock_Free(&R.v); -failI0: - R.have = 0; - parser_out->out_of_memory = 1; -doneI: - free_statement(A); - free_block(N); -} - -dotted_name(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -dotted_name(R) ::= NAME(A) DOT dotted_name(N). { - ASSERT(A.str) - if (!N) { - goto failJ0; - } - - if (!(R = concat_strings(3, A.str, ".", N))) { - goto failJ0; - } - - goto doneJ; - -failJ0: - R = NULL; - parser_out->out_of_memory = 1; -doneJ: - free_token(A); - free(N); -} - -name_list(R) ::= NAME(A). { - if (!A.str) { - goto failK0; - } - - NCDValue_InitList(&R.v); - - NCDValue this_string; - if (!NCDValue_InitString(&this_string, A.str)) { - goto failK1; - } - - if (!NCDValue_ListPrepend(&R.v, this_string)) { - goto failK2; - } - - R.have = 1; - goto doneK; - -failK2: - NCDValue_Free(&this_string); -failK1: - NCDValue_Free(&R.v); -failK0: - R.have = 0; - parser_out->out_of_memory = 1; -doneK: - free_token(A); -} - -name_list(R) ::= NAME(A) DOT name_list(N). { - if (!A.str || !N.have) { - goto failKA0; - } - - NCDValue this_string; - if (!NCDValue_InitString(&this_string, A.str)) { - goto failKA0; - } - - if (!NCDValue_ListPrepend(&N.v, this_string)) { - goto failKA1; - } - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneKA; - -failKA1: - NCDValue_Free(&this_string); -failKA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneKA: - free_token(A); - free_value(N); -} - -list_contents_maybe(R) ::= . { - R.have = 1; - NCDValue_InitList(&R.v); -} - -list_contents_maybe(R) ::= list_contents(A). { - R = A; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValue_InitList(&R.v); - - if (!NCDValue_ListPrepend(&R.v, A.v)) { - goto failL1; - } - A.have = 0; - - R.have = 1; - goto doneL; - -failL1: - NCDValue_Free(&R.v); -failL0: - R.have = 0; - parser_out->out_of_memory = 1; -doneL: - free_value(A); -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValue_ListPrepend(&N.v, A.v)) { - goto failM0; - } - A.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneM; - -failM0: - R.have = 0; - parser_out->out_of_memory = 1; -doneM: - free_value(A); - free_value(N); -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - R.have = 1; - NCDValue_InitList(&R.v); -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValue_InitMap(&R.v); - - if (!NCDValue_MapPrepend(&R.v, A.v, B.v)) { - goto failS1; - } - A.have = 0; - B.have = 0; - - R.have = 1; - goto doneS; - -failS1: - NCDValue_Free(&R.v); -failS0: - R.have = 0; - parser_out->out_of_memory = 1; -doneS: - free_value(A); - free_value(B); -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValue_MapPrepend(&N.v, A.v, B.v)) { - goto failT0; - } - A.have = 0; - B.have = 0; - - R.have = 1; - R.v = N.v; - N.have = 0; - goto doneT; - -failT0: - R.have = 0; - parser_out->out_of_memory = 1; -doneT: - free_value(A); - free_value(B); - free_value(N); -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - R.have = 1; - NCDValue_InitMap(&R.v); -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -invoc(R) ::= value(F) ROUND_OPEN list_contents_maybe(A) ROUND_CLOSE. { - if (!F.have || !A.have) { - goto failQ0; - } - - if (!NCDValue_InitInvoc(&R.v, F.v, A.v)) { - goto failQ0; - } - F.have = 0; - A.have = 0; - R.have = 1; - goto doneQ; - -failQ0: - R.have = 0; - parser_out->out_of_memory = 1; -doneQ: - free_value(F); - free_value(A); -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValue_InitStringBin(&R.v, (uint8_t *)A.str, A.len)) { - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; - parser_out->out_of_memory = 1; -doneU: - free_token(A); -} - -value(R) ::= AT_SIGN dotted_name(A). { - if (!A) { - goto failUA0; - } - - if (!NCDValue_InitString(&R.v, A)) { - goto failUA0; - } - - R.have = 1; - goto doneUA0; - -failUA0: - R.have = 0; - parser_out->out_of_memory = 1; -doneUA0: - free(A); -} - -value(R) ::= CARET name_list(A). { - R = A; -} - -value(R) ::= dotted_name(A). { - if (!A) { - goto failV0; - } - - if (!NCDValue_InitVar(&R.v, A)) { - goto failV0; - } - - R.have = 1; - goto doneV; - -failV0: - R.have = 0; - parser_out->out_of_memory = 1; -doneV: - free(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} - -value(R) ::= ROUND_OPEN value(A) ROUND_CLOSE. { - R = A; -} - -value(R) ::= invoc(A). { - R = A; -} - -name_maybe(R) ::= . { - R = NULL; -} - -name_maybe(R) ::= NAME(A). { - ASSERT(A.str) - - R = A.str; -} - -process_or_template(R) ::= PROCESS. { - R = 0; -} - -process_or_template(R) ::= TEMPLATE. { - R = 1; -} diff --git a/v2rayng/badvpn/generated/NCDValParser_parse.c b/v2rayng/badvpn/generated/NCDValParser_parse.c deleted file mode 100644 index f7039cca5d..0000000000 --- a/v2rayng/badvpn/generated/NCDValParser_parse.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 16 -#define YYACTIONTYPE unsigned char -#define ParseTOKENTYPE struct token -typedef union { - int yyinit; - ParseTOKENTYPE yy0; - struct value yy1; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 0 -#endif -#define ParseARG_SDECL struct parser_state *parser_out ; -#define ParseARG_PDECL , struct parser_state *parser_out -#define ParseARG_FETCH struct parser_state *parser_out = yypParser->parser_out -#define ParseARG_STORE yypParser->parser_out = parser_out -#define YYNSTATE 21 -#define YYNRULE 12 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 15, 21, 16, 6, 34, 1, 19, 3, 2, 15, - /* 10 */ 14, 16, 9, 11, 15, 5, 16, 7, 18, 1, - /* 20 */ 35, 20, 2, 17, 14, 15, 10, 16, 8, 12, - /* 30 */ 15, 4, 16, 7, 15, 13, 16, 8, 1, 35, - /* 40 */ 35, 2, 35, 14, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 10, 0, 12, 13, 14, 2, 3, 1, 5, 10, - /* 10 */ 7, 12, 13, 9, 10, 4, 12, 13, 6, 2, - /* 20 */ 15, 3, 5, 6, 7, 10, 11, 12, 13, 9, - /* 30 */ 10, 1, 12, 13, 10, 11, 12, 13, 2, 15, - /* 40 */ 15, 5, 15, 7, -}; -#define YY_SHIFT_USE_DFLT (-1) -#define YY_SHIFT_MAX 11 -static const signed char yy_shift_ofst[] = { - /* 0 */ 36, 3, 17, 36, 36, 36, 1, 6, 11, 30, - /* 10 */ 12, 18, -}; -#define YY_REDUCE_USE_DFLT (-11) -#define YY_REDUCE_MAX 5 -static const signed char yy_reduce_ofst[] = { - /* 0 */ -10, 4, 15, 20, 24, -1, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 33, 33, 33, 33, 33, 33, 33, 22, 33, 26, - /* 10 */ 33, 33, 23, 27, 30, 31, 32, 28, 29, 24, - /* 20 */ 25, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "COMMA", "CURLY_OPEN", "CURLY_CLOSE", - "COLON", "BRACKET_OPEN", "BRACKET_CLOSE", "STRING", - "error", "list_contents", "list", "map_contents", - "map", "value", "input", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "input ::= value", - /* 1 */ "list_contents ::= value", - /* 2 */ "list_contents ::= value COMMA list_contents", - /* 3 */ "list ::= CURLY_OPEN CURLY_CLOSE", - /* 4 */ "list ::= CURLY_OPEN list_contents CURLY_CLOSE", - /* 5 */ "map_contents ::= value COLON value", - /* 6 */ "map_contents ::= value COLON value COMMA map_contents", - /* 7 */ "map ::= BRACKET_OPEN BRACKET_CLOSE", - /* 8 */ "map ::= BRACKET_OPEN map_contents BRACKET_CLOSE", - /* 9 */ "value ::= STRING", - /* 10 */ "value ::= list", - /* 11 */ "value ::= map", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - /* TERMINAL Destructor */ - case 1: /* COMMA */ - case 2: /* CURLY_OPEN */ - case 3: /* CURLY_CLOSE */ - case 4: /* COLON */ - case 5: /* BRACKET_OPEN */ - case 6: /* BRACKET_CLOSE */ - case 7: /* STRING */ -{ -#line 37 "NCDValParser_parse.y" - free_token((yypminor->yy0)); -#line 377 "NCDValParser_parse.c" -} - break; - case 9: /* list_contents */ -{ -#line 47 "NCDValParser_parse.y" - (void)parser_out; -#line 384 "NCDValParser_parse.c" -} - break; - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && iyyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -#line 58 "NCDValParser_parse.y" - - if (yypMinor) { - free_token(yypMinor->yy0); - } -#line 562 "NCDValParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 14, 1 }, - { 9, 1 }, - { 9, 3 }, - { 10, 2 }, - { 10, 3 }, - { 11, 3 }, - { 11, 5 }, - { 12, 2 }, - { 12, 3 }, - { 13, 1 }, - { 13, 1 }, - { 13, 1 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ - case 0: /* input ::= value */ -#line 64 "NCDValParser_parse.y" -{ - if (!yymsp[0].minor.yy1.have) { - goto failZ0; - } - - if (!NCDVal_IsInvalid(parser_out->value)) { - // should never happen - parser_out->error_flags |= ERROR_FLAG_SYNTAX; - goto failZ0; - } - - if (!NCDValCons_Complete(&parser_out->cons, yymsp[0].minor.yy1.v, &parser_out->value, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failZ0; - } - -failZ0:; -} -#line 705 "NCDValParser_parse.c" - break; - case 1: /* list_contents ::= value */ -#line 83 "NCDValParser_parse.y" -{ - if (!yymsp[0].minor.yy1.have) { - goto failL0; - } - - NCDValCons_NewList(&parser_out->cons, &yygotominor.yy1.v); - - if (!NCDValCons_ListPrepend(&parser_out->cons, &yygotominor.yy1.v, yymsp[0].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failL0; - } - - yygotominor.yy1.have = 1; - goto doneL; - -failL0: - yygotominor.yy1.have = 0; -doneL:; -} -#line 728 "NCDValParser_parse.c" - break; - case 2: /* list_contents ::= value COMMA list_contents */ -#line 103 "NCDValParser_parse.y" -{ - if (!yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failM0; - } - - if (!NCDValCons_ListPrepend(&parser_out->cons, &yymsp[0].minor.yy1.v, yymsp[-2].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failM0; - } - - yygotominor.yy1.have = 1; - yygotominor.yy1.v = yymsp[0].minor.yy1.v; - goto doneM; - -failM0: - yygotominor.yy1.have = 0; -doneM:; - yy_destructor(yypParser,1,&yymsp[-1].minor); -} -#line 751 "NCDValParser_parse.c" - break; - case 3: /* list ::= CURLY_OPEN CURLY_CLOSE */ -#line 122 "NCDValParser_parse.y" -{ - NCDValCons_NewList(&parser_out->cons, &yygotominor.yy1.v); - yygotominor.yy1.have = 1; - yy_destructor(yypParser,2,&yymsp[-1].minor); - yy_destructor(yypParser,3,&yymsp[0].minor); -} -#line 761 "NCDValParser_parse.c" - break; - case 4: /* list ::= CURLY_OPEN list_contents CURLY_CLOSE */ -#line 127 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[-1].minor.yy1; - yy_destructor(yypParser,2,&yymsp[-2].minor); - yy_destructor(yypParser,3,&yymsp[0].minor); -} -#line 770 "NCDValParser_parse.c" - break; - case 5: /* map_contents ::= value COLON value */ -#line 131 "NCDValParser_parse.y" -{ - if (!yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failS0; - } - - NCDValCons_NewMap(&parser_out->cons, &yygotominor.yy1.v); - - if (!NCDValCons_MapInsert(&parser_out->cons, &yygotominor.yy1.v, yymsp[-2].minor.yy1.v, yymsp[0].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failS0; - } - - yygotominor.yy1.have = 1; - goto doneS; - -failS0: - yygotominor.yy1.have = 0; -doneS:; - yy_destructor(yypParser,4,&yymsp[-1].minor); -} -#line 794 "NCDValParser_parse.c" - break; - case 6: /* map_contents ::= value COLON value COMMA map_contents */ -#line 151 "NCDValParser_parse.y" -{ - if (!yymsp[-4].minor.yy1.have || !yymsp[-2].minor.yy1.have || !yymsp[0].minor.yy1.have) { - goto failT0; - } - - if (!NCDValCons_MapInsert(&parser_out->cons, &yymsp[0].minor.yy1.v, yymsp[-4].minor.yy1.v, yymsp[-2].minor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failT0; - } - - yygotominor.yy1.have = 1; - yygotominor.yy1.v = yymsp[0].minor.yy1.v; - goto doneT; - -failT0: - yygotominor.yy1.have = 0; -doneT:; - yy_destructor(yypParser,4,&yymsp[-3].minor); - yy_destructor(yypParser,1,&yymsp[-1].minor); -} -#line 818 "NCDValParser_parse.c" - break; - case 7: /* map ::= BRACKET_OPEN BRACKET_CLOSE */ -#line 170 "NCDValParser_parse.y" -{ - NCDValCons_NewMap(&parser_out->cons, &yygotominor.yy1.v); - yygotominor.yy1.have = 1; - yy_destructor(yypParser,5,&yymsp[-1].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 828 "NCDValParser_parse.c" - break; - case 8: /* map ::= BRACKET_OPEN map_contents BRACKET_CLOSE */ -#line 175 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[-1].minor.yy1; - yy_destructor(yypParser,5,&yymsp[-2].minor); - yy_destructor(yypParser,6,&yymsp[0].minor); -} -#line 837 "NCDValParser_parse.c" - break; - case 9: /* value ::= STRING */ -#line 179 "NCDValParser_parse.y" -{ - ASSERT(yymsp[0].minor.yy0.str) - - if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)yymsp[0].minor.yy0.str, yymsp[0].minor.yy0.len, &yygotominor.yy1.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failU0; - } - - yygotominor.yy1.have = 1; - goto doneU; - -failU0: - yygotominor.yy1.have = 0; -doneU:; - free_token(yymsp[0].minor.yy0); -} -#line 857 "NCDValParser_parse.c" - break; - case 10: /* value ::= list */ - case 11: /* value ::= map */ yytestcase(yyruleno==11); -#line 196 "NCDValParser_parse.y" -{ - yygotominor.yy1 = yymsp[0].minor.yy1; -} -#line 865 "NCDValParser_parse.c" - break; - default: - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 53 "NCDValParser_parse.y" - - parser_out->error_flags |= ERROR_FLAG_SYNTAX; -#line 930 "NCDValParser_parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyactyyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/v2rayng/badvpn/generated/NCDValParser_parse.h b/v2rayng/badvpn/generated/NCDValParser_parse.h deleted file mode 100644 index fd19b494ec..0000000000 --- a/v2rayng/badvpn/generated/NCDValParser_parse.h +++ /dev/null @@ -1,7 +0,0 @@ -#define COMMA 1 -#define CURLY_OPEN 2 -#define CURLY_CLOSE 3 -#define COLON 4 -#define BRACKET_OPEN 5 -#define BRACKET_CLOSE 6 -#define STRING 7 diff --git a/v2rayng/badvpn/generated/NCDValParser_parse.out b/v2rayng/badvpn/generated/NCDValParser_parse.out deleted file mode 100644 index 9f42273ffc..0000000000 --- a/v2rayng/badvpn/generated/NCDValParser_parse.out +++ /dev/null @@ -1,217 +0,0 @@ -State 0: - input ::= * value - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map shift 16 - value shift 6 - input accept - -State 1: - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= CURLY_OPEN * CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - list ::= CURLY_OPEN * list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - CURLY_CLOSE shift 19 - BRACKET_OPEN shift 2 - STRING shift 14 - list_contents shift 11 - list shift 15 - map shift 16 - value shift 7 - -State 2: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= BRACKET_OPEN * BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - map ::= BRACKET_OPEN * map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - BRACKET_CLOSE shift 17 - STRING shift 14 - list shift 15 - map_contents shift 10 - map shift 16 - value shift 8 - -State 3: - list_contents ::= * value - list_contents ::= * value COMMA list_contents - list_contents ::= value COMMA * list_contents - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list_contents shift 12 - list shift 15 - map shift 16 - value shift 7 - -State 4: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= * value COLON value - map_contents ::= * value COLON value COMMA map_contents - map_contents ::= value COLON value COMMA * map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map_contents shift 13 - map shift 16 - value shift 8 - -State 5: - list ::= * CURLY_OPEN CURLY_CLOSE - list ::= * CURLY_OPEN list_contents CURLY_CLOSE - map_contents ::= value COLON * value - map_contents ::= value COLON * value COMMA map_contents - map ::= * BRACKET_OPEN BRACKET_CLOSE - map ::= * BRACKET_OPEN map_contents BRACKET_CLOSE - value ::= * STRING - value ::= * list - value ::= * map - - CURLY_OPEN shift 1 - BRACKET_OPEN shift 2 - STRING shift 14 - list shift 15 - map shift 16 - value shift 9 - -State 6: - (0) input ::= value * - - $ reduce 0 - -State 7: - (1) list_contents ::= value * - list_contents ::= value * COMMA list_contents - - COMMA shift 3 - {default} reduce 1 - -State 8: - map_contents ::= value * COLON value - map_contents ::= value * COLON value COMMA map_contents - - COLON shift 5 - -State 9: - (5) map_contents ::= value COLON value * - map_contents ::= value COLON value * COMMA map_contents - - COMMA shift 4 - {default} reduce 5 - -State 10: - map ::= BRACKET_OPEN map_contents * BRACKET_CLOSE - - BRACKET_CLOSE shift 18 - -State 11: - list ::= CURLY_OPEN list_contents * CURLY_CLOSE - - CURLY_CLOSE shift 20 - -State 12: - (2) list_contents ::= value COMMA list_contents * - - {default} reduce 2 - -State 13: - (6) map_contents ::= value COLON value COMMA map_contents * - - {default} reduce 6 - -State 14: - (9) value ::= STRING * - - {default} reduce 9 - -State 15: - (10) value ::= list * - - {default} reduce 10 - -State 16: - (11) value ::= map * - - {default} reduce 11 - -State 17: - (7) map ::= BRACKET_OPEN BRACKET_CLOSE * - - {default} reduce 7 - -State 18: - (8) map ::= BRACKET_OPEN map_contents BRACKET_CLOSE * - - {default} reduce 8 - -State 19: - (3) list ::= CURLY_OPEN CURLY_CLOSE * - - {default} reduce 3 - -State 20: - (4) list ::= CURLY_OPEN list_contents CURLY_CLOSE * - - {default} reduce 4 - ----------------------------------------------------- -Symbols: - 0: $: - 1: COMMA - 2: CURLY_OPEN - 3: CURLY_CLOSE - 4: COLON - 5: BRACKET_OPEN - 6: BRACKET_CLOSE - 7: STRING - 8: error: - 9: list_contents: CURLY_OPEN BRACKET_OPEN STRING - 10: list: CURLY_OPEN - 11: map_contents: CURLY_OPEN BRACKET_OPEN STRING - 12: map: BRACKET_OPEN - 13: value: CURLY_OPEN BRACKET_OPEN STRING - 14: input: CURLY_OPEN BRACKET_OPEN STRING diff --git a/v2rayng/badvpn/generated/NCDValParser_parse.y b/v2rayng/badvpn/generated/NCDValParser_parse.y deleted file mode 100644 index ced123d302..0000000000 --- a/v2rayng/badvpn/generated/NCDValParser_parse.y +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file NCDConfigParser_parse.y - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// argument for passing state to parser hooks -%extra_argument { struct parser_state *parser_out } - -// type of structure representing tokens -%token_type { struct token } - -// token destructor frees extra memory allocated for tokens -%token_destructor { free_token($$); } - -// types of nonterminals -%type list_contents { struct value } -%type list { struct value } -%type map_contents { struct value } -%type map { struct value } -%type value { struct value } - -// mention parser_out in some destructor to and avoid unused variable warning -%destructor list_contents { (void)parser_out; } - -// try to dynamically grow the parse stack -%stack_size 0 - -// on syntax error, set the corresponding error flag -%syntax_error { - parser_out->error_flags |= ERROR_FLAG_SYNTAX; -} - -// workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked -%stack_overflow { - if (yypMinor) { - free_token(yypMinor->yy0); - } -} - -input ::= value(A). { - if (!A.have) { - goto failZ0; - } - - if (!NCDVal_IsInvalid(parser_out->value)) { - // should never happen - parser_out->error_flags |= ERROR_FLAG_SYNTAX; - goto failZ0; - } - - if (!NCDValCons_Complete(&parser_out->cons, A.v, &parser_out->value, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failZ0; - } - -failZ0:; -} - -list_contents(R) ::= value(A). { - if (!A.have) { - goto failL0; - } - - NCDValCons_NewList(&parser_out->cons, &R.v); - - if (!NCDValCons_ListPrepend(&parser_out->cons, &R.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failL0; - } - - R.have = 1; - goto doneL; - -failL0: - R.have = 0; -doneL:; -} - -list_contents(R) ::= value(A) COMMA list_contents(N). { - if (!A.have || !N.have) { - goto failM0; - } - - if (!NCDValCons_ListPrepend(&parser_out->cons, &N.v, A.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failM0; - } - - R.have = 1; - R.v = N.v; - goto doneM; - -failM0: - R.have = 0; -doneM:; -} - -list(R) ::= CURLY_OPEN CURLY_CLOSE. { - NCDValCons_NewList(&parser_out->cons, &R.v); - R.have = 1; -} - -list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. { - R = A; -} - -map_contents(R) ::= value(A) COLON value(B). { - if (!A.have || !B.have) { - goto failS0; - } - - NCDValCons_NewMap(&parser_out->cons, &R.v); - - if (!NCDValCons_MapInsert(&parser_out->cons, &R.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failS0; - } - - R.have = 1; - goto doneS; - -failS0: - R.have = 0; -doneS:; -} - -map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). { - if (!A.have || !B.have || !N.have) { - goto failT0; - } - - if (!NCDValCons_MapInsert(&parser_out->cons, &N.v, A.v, B.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failT0; - } - - R.have = 1; - R.v = N.v; - goto doneT; - -failT0: - R.have = 0; -doneT:; -} - -map(R) ::= BRACKET_OPEN BRACKET_CLOSE. { - NCDValCons_NewMap(&parser_out->cons, &R.v); - R.have = 1; -} - -map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. { - R = A; -} - -value(R) ::= STRING(A). { - ASSERT(A.str) - - if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)A.str, A.len, &R.v, &parser_out->cons_error)) { - handle_cons_error(parser_out); - goto failU0; - } - - R.have = 1; - goto doneU; - -failU0: - R.have = 0; -doneU:; - free_token(A); -} - -value(R) ::= list(A). { - R = A; -} - -value(R) ::= map(A). { - R = A; -} diff --git a/v2rayng/badvpn/generated/bison_BPredicate.c b/v2rayng/badvpn/generated/bison_BPredicate.c deleted file mode 100644 index 5a0a6056bc..0000000000 --- a/v2rayng/badvpn/generated/bison_BPredicate.c +++ /dev/null @@ -1,2168 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.7.12-4996" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* Copy the first part of user declarations. */ -/* Line 371 of yacc.c */ -#line 34 "predicate/BPredicate.y" - - -#include - -#include -#include - -#define YYLEX_PARAM scanner - -static struct predicate_node * make_constant (int val) -{ - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - return NULL; - } - - n->type = NODE_CONSTANT; - n->constant.val = val; - - return n; -} - -static struct predicate_node * make_negation (struct predicate_node *op) -{ - if (!op) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_NEG; - n->neg.op = op; - - return n; - -fail: - if (op) { - free_predicate_node(op); - } - return NULL; -} - -static struct predicate_node * make_conjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_CONJUNCT; - n->conjunct.op1 = op1; - n->conjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_disjunction (struct predicate_node *op1, struct predicate_node *op2) -{ - if (!op1 || !op2) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_DISJUNCT; - n->disjunct.op1 = op1; - n->disjunct.op2 = op2; - - return n; - -fail: - if (op1) { - free_predicate_node(op1); - } - if (op2) { - free_predicate_node(op2); - } - return NULL; -} - -static struct predicate_node * make_function (char *name, struct arguments_node *args, int need_args) -{ - if (!name || (!args && need_args)) { - goto fail; - } - - struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->type = NODE_FUNCTION; - n->function.name = name; - n->function.args = args; - - return n; - -fail: - if (name) { - free(name); - } - if (args) { - free_arguments_node(args); - } - return NULL; -} - -static struct arguments_node * make_arguments (struct arguments_arg arg, struct arguments_node *next, int need_next) -{ - if (arg.type == ARGUMENT_INVALID || (!next && need_next)) { - goto fail; - } - - struct arguments_node *n = (struct arguments_node *)malloc(sizeof(*n)); - if (!n) { - goto fail; - } - - n->arg = arg; - n->next = next; - - return n; - -fail: - free_argument(arg); - if (next) { - free_arguments_node(next); - } - return NULL; -} - -static struct arguments_arg make_argument_predicate (struct predicate_node *pr) -{ - struct arguments_arg ret; - - if (!pr) { - goto fail; - } - - ret.type = ARGUMENT_PREDICATE; - ret.predicate = pr; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - -static struct arguments_arg make_argument_string (char *string) -{ - struct arguments_arg ret; - - if (!string) { - goto fail; - } - - ret.type = ARGUMENT_STRING; - ret.string = string; - - return ret; - -fail: - ret.type = ARGUMENT_INVALID; - return ret; -} - - -/* Line 371 of yacc.c */ -#line 256 "generated//bison_BPredicate.c" - -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "bison_BPredicate.h". */ -#ifndef YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -# define YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - STRING = 258, - NAME = 259, - PEER1_NAME = 260, - PEER2_NAME = 261, - AND = 262, - OR = 263, - NOT = 264, - SPAR = 265, - EPAR = 266, - CONSTANT_TRUE = 267, - CONSTANT_FALSE = 268, - COMMA = 269 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 387 of yacc.c */ -#line 227 "predicate/BPredicate.y" - - char *text; - struct predicate_node *node; - struct arguments_node *arg_node; - struct predicate_node nfaw; - struct arguments_arg arg_arg; - - -/* Line 387 of yacc.c */ -#line 322 "generated//bison_BPredicate.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void *scanner, struct predicate_node **result); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -/* Line 390 of yacc.c */ -#line 362 "generated//bison_BPredicate.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 17 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 37 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 15 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 20 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 31 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 269 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 19, 21, 25, 28, 32, 36, 40, 45, 47, 51, - 53 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 16, 0, -1, 17, -1, 18, -1, 19, -1, 20, - -1, 21, -1, 22, -1, 23, -1, 12, -1, 13, - -1, 10, 17, 11, -1, 9, 17, -1, 17, 7, - 17, -1, 17, 8, 17, -1, 4, 10, 11, -1, - 4, 10, 24, 11, -1, 25, -1, 25, 14, 24, - -1, 17, -1, 3, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 276, 276, 281, 281, 281, 281, 281, 281, 284, - 288, 294, 300, 306, 312, 318, 322, 328, 332, 338, - 342 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "STRING", "NAME", "PEER1_NAME", - "PEER2_NAME", "AND", "OR", "NOT", "SPAR", "EPAR", "CONSTANT_TRUE", - "CONSTANT_FALSE", "COMMA", "$accept", "input", "predicate", "constant", - "parentheses", "neg", "conjunct", "disjunct", "function", "arguments", - "argument", YY_NULL -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 15, 16, 17, 17, 17, 17, 17, 17, 18, - 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, - 25 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 2, 3, 3, 3, 4, 1, 3, 1, - 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 0, 9, 10, 0, 2, 3, 4, - 5, 6, 7, 8, 0, 12, 0, 1, 0, 0, - 20, 15, 19, 0, 17, 11, 13, 14, 16, 0, - 18 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 6, 22, 8, 9, 10, 11, 12, 13, 23, - 24 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -10 -static const yytype_int8 yypact[] = -{ - 19, -9, 19, 19, -10, -10, 8, -1, -10, -10, - -10, -10, -10, -10, 1, -10, 26, -10, 19, 19, - -10, -10, -1, -2, 3, -10, -10, 13, -10, 12, - -10 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -10, -10, 0, -10, -10, -10, -10, -10, -10, -3, - -10 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 7, 14, 15, 16, 20, 1, 18, 19, 17, 28, - 2, 3, 21, 4, 5, 20, 1, 29, 26, 27, - 18, 2, 3, 1, 4, 5, 30, 0, 2, 3, - 0, 4, 5, 18, 19, 0, 0, 25 -}; - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-10))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int8 yycheck[] = -{ - 0, 10, 2, 3, 3, 4, 7, 8, 0, 11, - 9, 10, 11, 12, 13, 3, 4, 14, 18, 19, - 7, 9, 10, 4, 12, 13, 29, -1, 9, 10, - -1, 12, 13, 7, 8, -1, -1, 11 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 4, 9, 10, 12, 13, 16, 17, 18, 19, - 20, 21, 22, 23, 10, 17, 17, 0, 7, 8, - 3, 11, 17, 24, 25, 11, 17, 17, 11, 14, - 24 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, scanner, result, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -__attribute__((__unused__)) -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static unsigned -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -#else -static unsigned -yy_location_print_ (yyo, yylocp) - FILE *yyo; - YYLTYPE const * const yylocp; -#endif -{ - unsigned res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += fprintf (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += fprintf (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += fprintf (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += fprintf (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += fprintf (yyo, "-%d", end_col); - } - return res; - } - -# define YY_LOCATION_PRINT(File, Loc) \ - yy_location_print_ (File, &(Loc)) - -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, scanner, result); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (scanner); - YYUSE (result); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, result); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, void *scanner, struct predicate_node **result) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, scanner, result) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - void *scanner; - struct predicate_node **result; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , scanner, result); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, scanner, result); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, void *scanner, struct predicate_node **result) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, scanner, result) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - void *scanner; - struct predicate_node **result; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (scanner); - YYUSE (result); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 3: /* STRING */ -/* Line 1393 of yacc.c */ -#line 240 "predicate/BPredicate.y" - { - free(((*yyvaluep).text)); -}; -/* Line 1393 of yacc.c */ -#line 1391 "generated//bison_BPredicate.c" - break; - case 4: /* NAME */ -/* Line 1393 of yacc.c */ -#line 240 "predicate/BPredicate.y" - { - free(((*yyvaluep).text)); -}; -/* Line 1393 of yacc.c */ -#line 1400 "generated//bison_BPredicate.c" - break; - case 17: /* predicate */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1411 "generated//bison_BPredicate.c" - break; - case 18: /* constant */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1422 "generated//bison_BPredicate.c" - break; - case 19: /* parentheses */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1433 "generated//bison_BPredicate.c" - break; - case 20: /* neg */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1444 "generated//bison_BPredicate.c" - break; - case 21: /* conjunct */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1455 "generated//bison_BPredicate.c" - break; - case 22: /* disjunct */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1466 "generated//bison_BPredicate.c" - break; - case 23: /* function */ -/* Line 1393 of yacc.c */ -#line 250 "predicate/BPredicate.y" - { - if (((*yyvaluep).node)) { - free_predicate_node(((*yyvaluep).node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1477 "generated//bison_BPredicate.c" - break; - case 24: /* arguments */ -/* Line 1393 of yacc.c */ -#line 257 "predicate/BPredicate.y" - { - if (((*yyvaluep).arg_node)) { - free_arguments_node(((*yyvaluep).arg_node)); - } -}; -/* Line 1393 of yacc.c */ -#line 1488 "generated//bison_BPredicate.c" - break; - case 25: /* argument */ -/* Line 1393 of yacc.c */ -#line 264 "predicate/BPredicate.y" - { - free_argument(((*yyvaluep).arg_arg)); -}; -/* Line 1393 of yacc.c */ -#line 1497 "generated//bison_BPredicate.c" - break; - - default: - break; - } -} - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *scanner, struct predicate_node **result) -#else -int -yyparse (scanner, result) - void *scanner; - struct predicate_node **result; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -static YYSTYPE yyval_default; -# define YY_INITIAL_VALUE(Value) = Value -#endif -static YYLTYPE yyloc_default -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc = yyloc_default; - - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -/* Line 1787 of yacc.c */ -#line 276 "predicate/BPredicate.y" - { - *result = (yyvsp[(1) - (1)].node); - } - break; - - case 9: -/* Line 1787 of yacc.c */ -#line 284 "predicate/BPredicate.y" - { - (yyval.node) = make_constant(1); - } - break; - - case 10: -/* Line 1787 of yacc.c */ -#line 288 "predicate/BPredicate.y" - { - (yyval.node) = make_constant(0); - } - break; - - case 11: -/* Line 1787 of yacc.c */ -#line 294 "predicate/BPredicate.y" - { - (yyval.node) = (yyvsp[(2) - (3)].node); - } - break; - - case 12: -/* Line 1787 of yacc.c */ -#line 300 "predicate/BPredicate.y" - { - (yyval.node) = make_negation((yyvsp[(2) - (2)].node)); - } - break; - - case 13: -/* Line 1787 of yacc.c */ -#line 306 "predicate/BPredicate.y" - { - (yyval.node) = make_conjunction((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } - break; - - case 14: -/* Line 1787 of yacc.c */ -#line 312 "predicate/BPredicate.y" - { - (yyval.node) = make_disjunction((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } - break; - - case 15: -/* Line 1787 of yacc.c */ -#line 318 "predicate/BPredicate.y" - { - (yyval.node) = make_function((yyvsp[(1) - (3)].text), NULL, 0); - } - break; - - case 16: -/* Line 1787 of yacc.c */ -#line 322 "predicate/BPredicate.y" - { - (yyval.node) = make_function((yyvsp[(1) - (4)].text), (yyvsp[(3) - (4)].arg_node), 1); - } - break; - - case 17: -/* Line 1787 of yacc.c */ -#line 328 "predicate/BPredicate.y" - { - (yyval.arg_node) = make_arguments((yyvsp[(1) - (1)].arg_arg), NULL, 0); - } - break; - - case 18: -/* Line 1787 of yacc.c */ -#line 332 "predicate/BPredicate.y" - { - (yyval.arg_node) = make_arguments((yyvsp[(1) - (3)].arg_arg), (yyvsp[(3) - (3)].arg_node), 1); - } - break; - - case 19: -/* Line 1787 of yacc.c */ -#line 338 "predicate/BPredicate.y" - { - (yyval.arg_arg) = make_argument_predicate((yyvsp[(1) - (1)].node)); - } - break; - - case 20: -/* Line 1787 of yacc.c */ -#line 342 "predicate/BPredicate.y" - { - (yyval.arg_arg) = make_argument_string((yyvsp[(1) - (1)].text)); - } - break; - - -/* Line 1787 of yacc.c */ -#line 1932 "generated//bison_BPredicate.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, scanner, result, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (&yylloc, scanner, result, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, scanner, result); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, scanner, result); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, scanner, result, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, scanner, result); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, scanner, result); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - diff --git a/v2rayng/badvpn/generated/bison_BPredicate.h b/v2rayng/badvpn/generated/bison_BPredicate.h deleted file mode 100644 index 2bf36ceed0..0000000000 --- a/v2rayng/badvpn/generated/bison_BPredicate.h +++ /dev/null @@ -1,114 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -# define YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - STRING = 258, - NAME = 259, - PEER1_NAME = 260, - PEER2_NAME = 261, - AND = 262, - OR = 263, - NOT = 264, - SPAR = 265, - EPAR = 266, - CONSTANT_TRUE = 267, - CONSTANT_FALSE = 268, - COMMA = 269 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 2053 of yacc.c */ -#line 227 "predicate/BPredicate.y" - - char *text; - struct predicate_node *node; - struct arguments_node *arg_node; - struct predicate_node nfaw; - struct arguments_arg arg_arg; - - -/* Line 2053 of yacc.c */ -#line 80 "generated//bison_BPredicate.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void *scanner, struct predicate_node **result); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_GENERATED_BISON_BPREDICATE_H_INCLUDED */ diff --git a/v2rayng/badvpn/generated/blog_channel_BArpProbe.h b/v2rayng/badvpn/generated/blog_channel_BArpProbe.h deleted file mode 100644 index f168e63844..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BArpProbe.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BArpProbe diff --git a/v2rayng/badvpn/generated/blog_channel_BConnection.h b/v2rayng/badvpn/generated/blog_channel_BConnection.h deleted file mode 100644 index 8447db02c4..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BConnection diff --git a/v2rayng/badvpn/generated/blog_channel_BDHCPClient.h b/v2rayng/badvpn/generated/blog_channel_BDHCPClient.h deleted file mode 100644 index aacf34db8e..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BDHCPClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClient diff --git a/v2rayng/badvpn/generated/blog_channel_BDHCPClientCore.h b/v2rayng/badvpn/generated/blog_channel_BDHCPClientCore.h deleted file mode 100644 index 64fc74d363..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BDHCPClientCore.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDHCPClientCore diff --git a/v2rayng/badvpn/generated/blog_channel_BDatagram.h b/v2rayng/badvpn/generated/blog_channel_BDatagram.h deleted file mode 100644 index d95cf24579..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BDatagram.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BDatagram diff --git a/v2rayng/badvpn/generated/blog_channel_BEncryption.h b/v2rayng/badvpn/generated/blog_channel_BEncryption.h deleted file mode 100644 index 6991f3708d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BEncryption.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BEncryption diff --git a/v2rayng/badvpn/generated/blog_channel_BInputProcess.h b/v2rayng/badvpn/generated/blog_channel_BInputProcess.h deleted file mode 100644 index f65f715ac7..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BInputProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BInputProcess diff --git a/v2rayng/badvpn/generated/blog_channel_BLockReactor.h b/v2rayng/badvpn/generated/blog_channel_BLockReactor.h deleted file mode 100644 index 5aab6d4149..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BLockReactor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BLockReactor diff --git a/v2rayng/badvpn/generated/blog_channel_BNetwork.h b/v2rayng/badvpn/generated/blog_channel_BNetwork.h deleted file mode 100644 index c5e3bc1e4e..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BNetwork.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BNetwork diff --git a/v2rayng/badvpn/generated/blog_channel_BPredicate.h b/v2rayng/badvpn/generated/blog_channel_BPredicate.h deleted file mode 100644 index 1a683f1356..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BPredicate.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BPredicate diff --git a/v2rayng/badvpn/generated/blog_channel_BProcess.h b/v2rayng/badvpn/generated/blog_channel_BProcess.h deleted file mode 100644 index e11e5a627f..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BProcess diff --git a/v2rayng/badvpn/generated/blog_channel_BReactor.h b/v2rayng/badvpn/generated/blog_channel_BReactor.h deleted file mode 100644 index d111dc79d1..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BReactor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BReactor diff --git a/v2rayng/badvpn/generated/blog_channel_BSSLConnection.h b/v2rayng/badvpn/generated/blog_channel_BSSLConnection.h deleted file mode 100644 index bd55826ba8..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BSSLConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSSLConnection diff --git a/v2rayng/badvpn/generated/blog_channel_BSignal.h b/v2rayng/badvpn/generated/blog_channel_BSignal.h deleted file mode 100644 index 2820ebce16..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSignal diff --git a/v2rayng/badvpn/generated/blog_channel_BSocksClient.h b/v2rayng/badvpn/generated/blog_channel_BSocksClient.h deleted file mode 100644 index 72086fab58..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BSocksClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BSocksClient diff --git a/v2rayng/badvpn/generated/blog_channel_BTap.h b/v2rayng/badvpn/generated/blog_channel_BTap.h deleted file mode 100644 index ab3e951ed7..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BTap.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTap diff --git a/v2rayng/badvpn/generated/blog_channel_BThreadSignal.h b/v2rayng/badvpn/generated/blog_channel_BThreadSignal.h deleted file mode 100644 index f39fc368ed..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BThreadSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadSignal diff --git a/v2rayng/badvpn/generated/blog_channel_BThreadWork.h b/v2rayng/badvpn/generated/blog_channel_BThreadWork.h deleted file mode 100644 index f68383c24b..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BThreadWork.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BThreadWork diff --git a/v2rayng/badvpn/generated/blog_channel_BTime.h b/v2rayng/badvpn/generated/blog_channel_BTime.h deleted file mode 100644 index b323ee7671..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BTime.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BTime diff --git a/v2rayng/badvpn/generated/blog_channel_BUnixSignal.h b/v2rayng/badvpn/generated/blog_channel_BUnixSignal.h deleted file mode 100644 index 914b21b847..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_BUnixSignal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_BUnixSignal diff --git a/v2rayng/badvpn/generated/blog_channel_DPReceive.h b/v2rayng/badvpn/generated/blog_channel_DPReceive.h deleted file mode 100644 index 99889b5625..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_DPReceive.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPReceive diff --git a/v2rayng/badvpn/generated/blog_channel_DPRelay.h b/v2rayng/badvpn/generated/blog_channel_DPRelay.h deleted file mode 100644 index bc0153be0a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_DPRelay.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DPRelay diff --git a/v2rayng/badvpn/generated/blog_channel_DataProto.h b/v2rayng/badvpn/generated/blog_channel_DataProto.h deleted file mode 100644 index a6f900a39f..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_DataProto.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DataProto diff --git a/v2rayng/badvpn/generated/blog_channel_DatagramPeerIO.h b/v2rayng/badvpn/generated/blog_channel_DatagramPeerIO.h deleted file mode 100644 index 16e37b5b20..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_DatagramPeerIO.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_DatagramPeerIO diff --git a/v2rayng/badvpn/generated/blog_channel_FragmentProtoAssembler.h b/v2rayng/badvpn/generated/blog_channel_FragmentProtoAssembler.h deleted file mode 100644 index 25289efbfe..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_FragmentProtoAssembler.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FragmentProtoAssembler diff --git a/v2rayng/badvpn/generated/blog_channel_FrameDecider.h b/v2rayng/badvpn/generated/blog_channel_FrameDecider.h deleted file mode 100644 index 5dbf3c461c..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_FrameDecider.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_FrameDecider diff --git a/v2rayng/badvpn/generated/blog_channel_LineBuffer.h b/v2rayng/badvpn/generated/blog_channel_LineBuffer.h deleted file mode 100644 index 4286a742a2..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_LineBuffer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_LineBuffer diff --git a/v2rayng/badvpn/generated/blog_channel_Listener.h b/v2rayng/badvpn/generated/blog_channel_Listener.h deleted file mode 100644 index f61bfb3dbd..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_Listener.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_Listener diff --git a/v2rayng/badvpn/generated/blog_channel_NCDBuildProgram.h b/v2rayng/badvpn/generated/blog_channel_NCDBuildProgram.h deleted file mode 100644 index 1a6cdf910d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDBuildProgram.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDBuildProgram diff --git a/v2rayng/badvpn/generated/blog_channel_NCDConfigParser.h b/v2rayng/badvpn/generated/blog_channel_NCDConfigParser.h deleted file mode 100644 index 92d98d0678..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDConfigParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigParser diff --git a/v2rayng/badvpn/generated/blog_channel_NCDConfigTokenizer.h b/v2rayng/badvpn/generated/blog_channel_NCDConfigTokenizer.h deleted file mode 100644 index 0b3b689203..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDConfigTokenizer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDConfigTokenizer diff --git a/v2rayng/badvpn/generated/blog_channel_NCDIfConfig.h b/v2rayng/badvpn/generated/blog_channel_NCDIfConfig.h deleted file mode 100644 index 91bdbda513..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDIfConfig.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDIfConfig diff --git a/v2rayng/badvpn/generated/blog_channel_NCDInterfaceMonitor.h b/v2rayng/badvpn/generated/blog_channel_NCDInterfaceMonitor.h deleted file mode 100644 index 22c0f8d6aa..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDInterfaceMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDInterfaceMonitor diff --git a/v2rayng/badvpn/generated/blog_channel_NCDModuleIndex.h b/v2rayng/badvpn/generated/blog_channel_NCDModuleIndex.h deleted file mode 100644 index 34876642ea..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDModuleIndex.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDModuleIndex diff --git a/v2rayng/badvpn/generated/blog_channel_NCDModuleProcess.h b/v2rayng/badvpn/generated/blog_channel_NCDModuleProcess.h deleted file mode 100644 index db34dcc054..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDModuleProcess.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDModuleProcess diff --git a/v2rayng/badvpn/generated/blog_channel_NCDPlaceholderDb.h b/v2rayng/badvpn/generated/blog_channel_NCDPlaceholderDb.h deleted file mode 100644 index f1f1db2cb5..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDPlaceholderDb.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDPlaceholderDb diff --git a/v2rayng/badvpn/generated/blog_channel_NCDRequest.h b/v2rayng/badvpn/generated/blog_channel_NCDRequest.h deleted file mode 100644 index 5edc18a214..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDRequest.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRequest diff --git a/v2rayng/badvpn/generated/blog_channel_NCDRequestClient.h b/v2rayng/badvpn/generated/blog_channel_NCDRequestClient.h deleted file mode 100644 index 1e696d8ccc..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDRequestClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRequestClient diff --git a/v2rayng/badvpn/generated/blog_channel_NCDRfkillMonitor.h b/v2rayng/badvpn/generated/blog_channel_NCDRfkillMonitor.h deleted file mode 100644 index 56eba888f5..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDRfkillMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDRfkillMonitor diff --git a/v2rayng/badvpn/generated/blog_channel_NCDUdevCache.h b/v2rayng/badvpn/generated/blog_channel_NCDUdevCache.h deleted file mode 100644 index 088fc9b36d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDUdevCache.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevCache diff --git a/v2rayng/badvpn/generated/blog_channel_NCDUdevManager.h b/v2rayng/badvpn/generated/blog_channel_NCDUdevManager.h deleted file mode 100644 index e9d6375899..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDUdevManager.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevManager diff --git a/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitor.h b/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitor.h deleted file mode 100644 index bd93249aaf..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitor.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevMonitor diff --git a/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitorParser.h b/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitorParser.h deleted file mode 100644 index a7d560f4f3..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDUdevMonitorParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDUdevMonitorParser diff --git a/v2rayng/badvpn/generated/blog_channel_NCDVal.h b/v2rayng/badvpn/generated/blog_channel_NCDVal.h deleted file mode 100644 index f2b67c2826..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDVal.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDVal diff --git a/v2rayng/badvpn/generated/blog_channel_NCDValGenerator.h b/v2rayng/badvpn/generated/blog_channel_NCDValGenerator.h deleted file mode 100644 index 193826bbbb..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDValGenerator.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDValGenerator diff --git a/v2rayng/badvpn/generated/blog_channel_NCDValParser.h b/v2rayng/badvpn/generated/blog_channel_NCDValParser.h deleted file mode 100644 index 1d44acb76e..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_NCDValParser.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_NCDValParser diff --git a/v2rayng/badvpn/generated/blog_channel_PRStreamSink.h b/v2rayng/badvpn/generated/blog_channel_PRStreamSink.h deleted file mode 100644 index b70b61cd01..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_PRStreamSink.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PRStreamSink diff --git a/v2rayng/badvpn/generated/blog_channel_PRStreamSource.h b/v2rayng/badvpn/generated/blog_channel_PRStreamSource.h deleted file mode 100644 index e16d93db97..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_PRStreamSource.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PRStreamSource diff --git a/v2rayng/badvpn/generated/blog_channel_PacketProtoDecoder.h b/v2rayng/badvpn/generated/blog_channel_PacketProtoDecoder.h deleted file mode 100644 index fbfa5d81e4..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_PacketProtoDecoder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PacketProtoDecoder diff --git a/v2rayng/badvpn/generated/blog_channel_PasswordListener.h b/v2rayng/badvpn/generated/blog_channel_PasswordListener.h deleted file mode 100644 index 6ff0bb58bd..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_PasswordListener.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PasswordListener diff --git a/v2rayng/badvpn/generated/blog_channel_PeerChat.h b/v2rayng/badvpn/generated/blog_channel_PeerChat.h deleted file mode 100644 index cadf230859..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_PeerChat.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_PeerChat diff --git a/v2rayng/badvpn/generated/blog_channel_SPProtoDecoder.h b/v2rayng/badvpn/generated/blog_channel_SPProtoDecoder.h deleted file mode 100644 index 09bf2599b5..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_SPProtoDecoder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_SPProtoDecoder diff --git a/v2rayng/badvpn/generated/blog_channel_ServerConnection.h b/v2rayng/badvpn/generated/blog_channel_ServerConnection.h deleted file mode 100644 index faea1dddcc..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ServerConnection.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ServerConnection diff --git a/v2rayng/badvpn/generated/blog_channel_SocksUdpClient.h b/v2rayng/badvpn/generated/blog_channel_SocksUdpClient.h deleted file mode 100644 index 25779f48b9..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_SocksUdpClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_SocksUdpClient diff --git a/v2rayng/badvpn/generated/blog_channel_SocksUdpGwClient.h b/v2rayng/badvpn/generated/blog_channel_SocksUdpGwClient.h deleted file mode 100644 index 6ba39aedbc..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_SocksUdpGwClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_SocksUdpGwClient diff --git a/v2rayng/badvpn/generated/blog_channel_StreamPeerIO.h b/v2rayng/badvpn/generated/blog_channel_StreamPeerIO.h deleted file mode 100644 index 0359736e77..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_StreamPeerIO.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_StreamPeerIO diff --git a/v2rayng/badvpn/generated/blog_channel_UdpGwClient.h b/v2rayng/badvpn/generated/blog_channel_UdpGwClient.h deleted file mode 100644 index 85303768f2..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_UdpGwClient.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_UdpGwClient diff --git a/v2rayng/badvpn/generated/blog_channel_addr.h b/v2rayng/badvpn/generated/blog_channel_addr.h deleted file mode 100644 index 512db28659..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_addr diff --git a/v2rayng/badvpn/generated/blog_channel_client.h b/v2rayng/badvpn/generated/blog_channel_client.h deleted file mode 100644 index c851b77bd9..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_client.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_client diff --git a/v2rayng/badvpn/generated/blog_channel_dostest_attacker.h b/v2rayng/badvpn/generated/blog_channel_dostest_attacker.h deleted file mode 100644 index b267c8f409..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_dostest_attacker.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_dostest_attacker diff --git a/v2rayng/badvpn/generated/blog_channel_dostest_server.h b/v2rayng/badvpn/generated/blog_channel_dostest_server.h deleted file mode 100644 index 8d3988e0f3..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_dostest_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_dostest_server diff --git a/v2rayng/badvpn/generated/blog_channel_flooder.h b/v2rayng/badvpn/generated/blog_channel_flooder.h deleted file mode 100644 index 94f595eb2f..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_flooder.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_flooder diff --git a/v2rayng/badvpn/generated/blog_channel_lwip.h b/v2rayng/badvpn/generated/blog_channel_lwip.h deleted file mode 100644 index fb5687dfdc..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_lwip.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_lwip diff --git a/v2rayng/badvpn/generated/blog_channel_ncd.h b/v2rayng/badvpn/generated/blog_channel_ncd.h deleted file mode 100644 index 9bf2956744..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_alias.h b/v2rayng/badvpn/generated/blog_channel_ncd_alias.h deleted file mode 100644 index 5b52bf26b1..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_alias.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_alias diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_arithmetic.h b/v2rayng/badvpn/generated/blog_channel_ncd_arithmetic.h deleted file mode 100644 index 66c08a8e4e..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_arithmetic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_arithmetic diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_assert.h b/v2rayng/badvpn/generated/blog_channel_ncd_assert.h deleted file mode 100644 index 21e4d41905..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_assert.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_assert diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_backtrack.h b/v2rayng/badvpn/generated/blog_channel_ncd_backtrack.h deleted file mode 100644 index ea669f7910..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_backtrack.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_backtrack diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_basic_functions.h b/v2rayng/badvpn/generated/blog_channel_ncd_basic_functions.h deleted file mode 100644 index 9f0bfdd493..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_basic_functions.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_basic_functions diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_blocker.h b/v2rayng/badvpn/generated/blog_channel_ncd_blocker.h deleted file mode 100644 index a897b9f509..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_blocker.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_blocker diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_buffer.h b/v2rayng/badvpn/generated/blog_channel_ncd_buffer.h deleted file mode 100644 index 64e4433395..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_buffer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_buffer diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_call2.h b/v2rayng/badvpn/generated/blog_channel_ncd_call2.h deleted file mode 100644 index 4b64608d9d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_call2.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_call2 diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_choose.h b/v2rayng/badvpn/generated/blog_channel_ncd_choose.h deleted file mode 100644 index a915036fe1..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_choose.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_choose diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_concat.h b/v2rayng/badvpn/generated/blog_channel_ncd_concat.h deleted file mode 100644 index 8c54ccbba5..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_concat.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_concat diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_daemon.h b/v2rayng/badvpn/generated/blog_channel_ncd_daemon.h deleted file mode 100644 index 0a3ae3fa3e..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_daemon.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_daemon diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_depend.h b/v2rayng/badvpn/generated/blog_channel_ncd_depend.h deleted file mode 100644 index ae1ff8e93c..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_depend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_depend diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_depend_scope.h b/v2rayng/badvpn/generated/blog_channel_ncd_depend_scope.h deleted file mode 100644 index 1168714dca..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_depend_scope.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_depend_scope diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_dynamic_depend.h b/v2rayng/badvpn/generated/blog_channel_ncd_dynamic_depend.h deleted file mode 100644 index 7ff305ea98..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_dynamic_depend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_dynamic_depend diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_exit.h b/v2rayng/badvpn/generated/blog_channel_ncd_exit.h deleted file mode 100644 index 2d2e3af16a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_exit.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_exit diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_explode.h b/v2rayng/badvpn/generated/blog_channel_ncd_explode.h deleted file mode 100644 index b7dc820e69..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_explode.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_explode diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_file.h b/v2rayng/badvpn/generated/blog_channel_ncd_file.h deleted file mode 100644 index 6cfa5a5560..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_file.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_file diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_file_open.h b/v2rayng/badvpn/generated/blog_channel_ncd_file_open.h deleted file mode 100644 index dd4ecb5f9a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_file_open.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_file_open diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_foreach.h b/v2rayng/badvpn/generated/blog_channel_ncd_foreach.h deleted file mode 100644 index 430b229455..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_foreach.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_foreach diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_from_string.h b/v2rayng/badvpn/generated/blog_channel_ncd_from_string.h deleted file mode 100644 index e409fffa3b..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_from_string.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_from_string diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_getargs.h b/v2rayng/badvpn/generated/blog_channel_ncd_getargs.h deleted file mode 100644 index da7631d4fb..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_getargs.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_getargs diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_getenv.h b/v2rayng/badvpn/generated/blog_channel_ncd_getenv.h deleted file mode 100644 index 4f29021611..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_getenv.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_getenv diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_if.h b/v2rayng/badvpn/generated/blog_channel_ncd_if.h deleted file mode 100644 index 11a09a2ac1..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_if.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_if diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_imperative.h b/v2rayng/badvpn/generated/blog_channel_ncd_imperative.h deleted file mode 100644 index 362df87a04..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_imperative.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_imperative diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_implode.h b/v2rayng/badvpn/generated/blog_channel_ncd_implode.h deleted file mode 100644 index 5bb66d5b0b..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_implode.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_implode diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_index.h b/v2rayng/badvpn/generated/blog_channel_ncd_index.h deleted file mode 100644 index 666bbe9b96..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_index.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_index diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_list.h b/v2rayng/badvpn/generated/blog_channel_ncd_list.h deleted file mode 100644 index f153be789c..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_list.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_list diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_load_module.h b/v2rayng/badvpn/generated/blog_channel_ncd_load_module.h deleted file mode 100644 index c27dddb8e3..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_load_module.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_load_module diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_log.h b/v2rayng/badvpn/generated/blog_channel_ncd_log.h deleted file mode 100644 index 9ae2dc95b0..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_log.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_log diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_log_msg.h b/v2rayng/badvpn/generated/blog_channel_ncd_log_msg.h deleted file mode 100644 index 9e51b7ebfe..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_log_msg.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_log_msg diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_logical.h b/v2rayng/badvpn/generated/blog_channel_ncd_logical.h deleted file mode 100644 index 688453d871..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_logical.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_logical diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_multidepend.h b/v2rayng/badvpn/generated/blog_channel_ncd_multidepend.h deleted file mode 100644 index a82953df6d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_multidepend.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_multidepend diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_badvpn.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_badvpn.h deleted file mode 100644 index c9964c1615..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_badvpn.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_badvpn diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_rfkill.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_rfkill.h deleted file mode 100644 index e69896f922..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_rfkill.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_rfkill diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitdevice.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitdevice.h deleted file mode 100644 index 63c4f24204..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitdevice.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_waitdevice diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitlink.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitlink.h deleted file mode 100644 index 96244c0a00..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_waitlink.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_waitlink diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_wpa_supplicant.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_wpa_supplicant.h deleted file mode 100644 index 22572d36bd..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_backend_wpa_supplicant.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_backend_wpa_supplicant diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_dns.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_dns.h deleted file mode 100644 index 01c3744832..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_dns.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_dns diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_iptables.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_iptables.h deleted file mode 100644 index 42e2382764..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_iptables.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_iptables diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr.h deleted file mode 100644 index 75bcb24d2b..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_addr diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr_in_network.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr_in_network.h deleted file mode 100644 index 41f2df2e8a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_addr_in_network.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_addr_in_network diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_arp_probe.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_arp_probe.h deleted file mode 100644 index 18f7c783ec..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_arp_probe.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_arp_probe diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_dhcp.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_dhcp.h deleted file mode 100644 index 51fa61fb4a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_dhcp.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_dhcp diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_route.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_route.h deleted file mode 100644 index e181a90b29..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv4_route.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv4_route diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr.h deleted file mode 100644 index bd6bd10add..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_addr diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr_in_network.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr_in_network.h deleted file mode 100644 index ba33921ffc..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_addr_in_network.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_addr_in_network diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_route.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_route.h deleted file mode 100644 index b72e4d38ba..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_route.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_route diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h deleted file mode 100644 index ff7d6e1e33..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_ipv6_wait_dynamic_addr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_ipv6_wait_dynamic_addr diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_up.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_up.h deleted file mode 100644 index 7acdedef51..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_up.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_up diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_net_watch_interfaces.h b/v2rayng/badvpn/generated/blog_channel_ncd_net_watch_interfaces.h deleted file mode 100644 index 7fc078f797..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_net_watch_interfaces.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_net_watch_interfaces diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_netmask.h b/v2rayng/badvpn/generated/blog_channel_ncd_netmask.h deleted file mode 100644 index 10993f0090..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_netmask.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_netmask diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_objref.h b/v2rayng/badvpn/generated/blog_channel_ncd_objref.h deleted file mode 100644 index 783ee6e5f7..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_objref.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_objref diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_ondemand.h b/v2rayng/badvpn/generated/blog_channel_ncd_ondemand.h deleted file mode 100644 index c7a0578c37..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_ondemand.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_ondemand diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_parse.h b/v2rayng/badvpn/generated/blog_channel_ncd_parse.h deleted file mode 100644 index 672155bece..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_parse.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_parse diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_print.h b/v2rayng/badvpn/generated/blog_channel_ncd_print.h deleted file mode 100644 index 22638f3b67..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_print.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_print diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_process_manager.h b/v2rayng/badvpn/generated/blog_channel_ncd_process_manager.h deleted file mode 100644 index 627ba0e553..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_process_manager.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_process_manager diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_reboot.h b/v2rayng/badvpn/generated/blog_channel_ncd_reboot.h deleted file mode 100644 index 0e31d5551f..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_reboot.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_reboot diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_ref.h b/v2rayng/badvpn/generated/blog_channel_ncd_ref.h deleted file mode 100644 index 4f9f24aeb9..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_ref.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_ref diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_regex_match.h b/v2rayng/badvpn/generated/blog_channel_ncd_regex_match.h deleted file mode 100644 index 30813479f0..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_regex_match.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_regex_match diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_request.h b/v2rayng/badvpn/generated/blog_channel_ncd_request.h deleted file mode 100644 index 00103ea8a2..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_request.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_request diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_run.h b/v2rayng/badvpn/generated/blog_channel_ncd_run.h deleted file mode 100644 index 036a93e35c..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_run.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_run diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_runonce.h b/v2rayng/badvpn/generated/blog_channel_ncd_runonce.h deleted file mode 100644 index 2e5445204f..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_runonce.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_runonce diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sleep.h b/v2rayng/badvpn/generated/blog_channel_ncd_sleep.h deleted file mode 100644 index fb6c7fe3eb..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sleep.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sleep diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_socket.h b/v2rayng/badvpn/generated/blog_channel_ncd_socket.h deleted file mode 100644 index 3c1f0c42b0..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_socket.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_socket diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_spawn.h b/v2rayng/badvpn/generated/blog_channel_ncd_spawn.h deleted file mode 100644 index b9b3b24f69..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_spawn.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_spawn diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_strcmp.h b/v2rayng/badvpn/generated/blog_channel_ncd_strcmp.h deleted file mode 100644 index 6ef09adc68..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_strcmp.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_strcmp diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_substr.h b/v2rayng/badvpn/generated/blog_channel_ncd_substr.h deleted file mode 100644 index 691ad0e241..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_substr.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_substr diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_evdev.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_evdev.h deleted file mode 100644 index 4a7244e5a4..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_evdev.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_evdev diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_client.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_client.h deleted file mode 100644 index ce0f9e4c3d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_client.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_request_client diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_server.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_server.h deleted file mode 100644 index 1197958846..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_request_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_request_server diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_start_process.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_start_process.h deleted file mode 100644 index 45c2edc0d1..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_start_process.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_start_process diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_directory.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_directory.h deleted file mode 100644 index e190da5183..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_directory.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_directory diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_input.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_input.h deleted file mode 100644 index b89955566a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_input.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_input diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_usb.h b/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_usb.h deleted file mode 100644 index bc5102a0d2..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_sys_watch_usb.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_sys_watch_usb diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_timer.h b/v2rayng/badvpn/generated/blog_channel_ncd_timer.h deleted file mode 100644 index beaa73db4a..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_timer.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_timer diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_to_string.h b/v2rayng/badvpn/generated/blog_channel_ncd_to_string.h deleted file mode 100644 index 41cd8b98db..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_to_string.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_to_string diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_try.h b/v2rayng/badvpn/generated/blog_channel_ncd_try.h deleted file mode 100644 index bb76c6851d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_try.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_try diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_value.h b/v2rayng/badvpn/generated/blog_channel_ncd_value.h deleted file mode 100644 index fa624e8f5d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_value.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_value diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_valuemetic.h b/v2rayng/badvpn/generated/blog_channel_ncd_valuemetic.h deleted file mode 100644 index 385d2bb12d..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_valuemetic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_valuemetic diff --git a/v2rayng/badvpn/generated/blog_channel_ncd_var.h b/v2rayng/badvpn/generated/blog_channel_ncd_var.h deleted file mode 100644 index fa5c0c4372..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_ncd_var.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_var diff --git a/v2rayng/badvpn/generated/blog_channel_nsskey.h b/v2rayng/badvpn/generated/blog_channel_nsskey.h deleted file mode 100644 index 66e6a72d12..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_nsskey.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_nsskey diff --git a/v2rayng/badvpn/generated/blog_channel_server.h b/v2rayng/badvpn/generated/blog_channel_server.h deleted file mode 100644 index acb3ed0d1b..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_server.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_server diff --git a/v2rayng/badvpn/generated/blog_channel_tun2socks.h b/v2rayng/badvpn/generated/blog_channel_tun2socks.h deleted file mode 100644 index 21c1ce2d22..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_tun2socks.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_tun2socks diff --git a/v2rayng/badvpn/generated/blog_channel_udpgw.h b/v2rayng/badvpn/generated/blog_channel_udpgw.h deleted file mode 100644 index 504a352204..0000000000 --- a/v2rayng/badvpn/generated/blog_channel_udpgw.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef BLOG_CURRENT_CHANNEL -#undef BLOG_CURRENT_CHANNEL -#endif -#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_udpgw diff --git a/v2rayng/badvpn/generated/blog_channels_defines.h b/v2rayng/badvpn/generated/blog_channels_defines.h deleted file mode 100644 index 804c91487f..0000000000 --- a/v2rayng/badvpn/generated/blog_channels_defines.h +++ /dev/null @@ -1,149 +0,0 @@ -#define BLOG_CHANNEL_server 0 -#define BLOG_CHANNEL_client 1 -#define BLOG_CHANNEL_flooder 2 -#define BLOG_CHANNEL_tun2socks 3 -#define BLOG_CHANNEL_ncd 4 -#define BLOG_CHANNEL_ncd_var 5 -#define BLOG_CHANNEL_ncd_list 6 -#define BLOG_CHANNEL_ncd_depend 7 -#define BLOG_CHANNEL_ncd_multidepend 8 -#define BLOG_CHANNEL_ncd_dynamic_depend 9 -#define BLOG_CHANNEL_ncd_concat 10 -#define BLOG_CHANNEL_ncd_if 11 -#define BLOG_CHANNEL_ncd_strcmp 12 -#define BLOG_CHANNEL_ncd_regex_match 13 -#define BLOG_CHANNEL_ncd_logical 14 -#define BLOG_CHANNEL_ncd_sleep 15 -#define BLOG_CHANNEL_ncd_print 16 -#define BLOG_CHANNEL_ncd_blocker 17 -#define BLOG_CHANNEL_ncd_run 18 -#define BLOG_CHANNEL_ncd_runonce 19 -#define BLOG_CHANNEL_ncd_daemon 20 -#define BLOG_CHANNEL_ncd_spawn 21 -#define BLOG_CHANNEL_ncd_imperative 22 -#define BLOG_CHANNEL_ncd_ref 23 -#define BLOG_CHANNEL_ncd_index 24 -#define BLOG_CHANNEL_ncd_alias 25 -#define BLOG_CHANNEL_ncd_process_manager 26 -#define BLOG_CHANNEL_ncd_ondemand 27 -#define BLOG_CHANNEL_ncd_foreach 28 -#define BLOG_CHANNEL_ncd_choose 29 -#define BLOG_CHANNEL_ncd_net_backend_waitdevice 30 -#define BLOG_CHANNEL_ncd_net_backend_waitlink 31 -#define BLOG_CHANNEL_ncd_net_backend_badvpn 32 -#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 33 -#define BLOG_CHANNEL_ncd_net_backend_rfkill 34 -#define BLOG_CHANNEL_ncd_net_up 35 -#define BLOG_CHANNEL_ncd_net_dns 36 -#define BLOG_CHANNEL_ncd_net_iptables 37 -#define BLOG_CHANNEL_ncd_net_ipv4_addr 38 -#define BLOG_CHANNEL_ncd_net_ipv4_route 39 -#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 40 -#define BLOG_CHANNEL_ncd_net_ipv4_arp_probe 41 -#define BLOG_CHANNEL_ncd_net_watch_interfaces 42 -#define BLOG_CHANNEL_ncd_sys_watch_input 43 -#define BLOG_CHANNEL_ncd_sys_watch_usb 44 -#define BLOG_CHANNEL_ncd_sys_evdev 45 -#define BLOG_CHANNEL_ncd_sys_watch_directory 46 -#define BLOG_CHANNEL_StreamPeerIO 47 -#define BLOG_CHANNEL_DatagramPeerIO 48 -#define BLOG_CHANNEL_BReactor 49 -#define BLOG_CHANNEL_BSignal 50 -#define BLOG_CHANNEL_FragmentProtoAssembler 51 -#define BLOG_CHANNEL_BPredicate 52 -#define BLOG_CHANNEL_ServerConnection 53 -#define BLOG_CHANNEL_Listener 54 -#define BLOG_CHANNEL_DataProto 55 -#define BLOG_CHANNEL_FrameDecider 56 -#define BLOG_CHANNEL_BSocksClient 57 -#define BLOG_CHANNEL_BDHCPClientCore 58 -#define BLOG_CHANNEL_BDHCPClient 59 -#define BLOG_CHANNEL_NCDIfConfig 60 -#define BLOG_CHANNEL_BUnixSignal 61 -#define BLOG_CHANNEL_BProcess 62 -#define BLOG_CHANNEL_PRStreamSink 63 -#define BLOG_CHANNEL_PRStreamSource 64 -#define BLOG_CHANNEL_PacketProtoDecoder 65 -#define BLOG_CHANNEL_DPRelay 66 -#define BLOG_CHANNEL_BThreadWork 67 -#define BLOG_CHANNEL_DPReceive 68 -#define BLOG_CHANNEL_BInputProcess 69 -#define BLOG_CHANNEL_NCDUdevMonitorParser 70 -#define BLOG_CHANNEL_NCDUdevMonitor 71 -#define BLOG_CHANNEL_NCDUdevCache 72 -#define BLOG_CHANNEL_NCDUdevManager 73 -#define BLOG_CHANNEL_BTime 74 -#define BLOG_CHANNEL_BEncryption 75 -#define BLOG_CHANNEL_SPProtoDecoder 76 -#define BLOG_CHANNEL_LineBuffer 77 -#define BLOG_CHANNEL_BTap 78 -#define BLOG_CHANNEL_lwip 79 -#define BLOG_CHANNEL_NCDConfigTokenizer 80 -#define BLOG_CHANNEL_NCDConfigParser 81 -#define BLOG_CHANNEL_NCDValParser 82 -#define BLOG_CHANNEL_nsskey 83 -#define BLOG_CHANNEL_addr 84 -#define BLOG_CHANNEL_PasswordListener 85 -#define BLOG_CHANNEL_NCDInterfaceMonitor 86 -#define BLOG_CHANNEL_NCDRfkillMonitor 87 -#define BLOG_CHANNEL_udpgw 88 -#define BLOG_CHANNEL_UdpGwClient 89 -#define BLOG_CHANNEL_SocksUdpGwClient 90 -#define BLOG_CHANNEL_SocksUdpClient 91 -#define BLOG_CHANNEL_BNetwork 92 -#define BLOG_CHANNEL_BConnection 93 -#define BLOG_CHANNEL_BSSLConnection 94 -#define BLOG_CHANNEL_BDatagram 95 -#define BLOG_CHANNEL_PeerChat 96 -#define BLOG_CHANNEL_BArpProbe 97 -#define BLOG_CHANNEL_NCDModuleIndex 98 -#define BLOG_CHANNEL_NCDModuleProcess 99 -#define BLOG_CHANNEL_NCDValGenerator 100 -#define BLOG_CHANNEL_ncd_from_string 101 -#define BLOG_CHANNEL_ncd_to_string 102 -#define BLOG_CHANNEL_ncd_value 103 -#define BLOG_CHANNEL_ncd_try 104 -#define BLOG_CHANNEL_ncd_sys_request_server 105 -#define BLOG_CHANNEL_NCDRequest 106 -#define BLOG_CHANNEL_ncd_net_ipv6_wait_dynamic_addr 107 -#define BLOG_CHANNEL_NCDRequestClient 108 -#define BLOG_CHANNEL_ncd_request 109 -#define BLOG_CHANNEL_ncd_sys_request_client 110 -#define BLOG_CHANNEL_ncd_exit 111 -#define BLOG_CHANNEL_ncd_getargs 112 -#define BLOG_CHANNEL_ncd_arithmetic 113 -#define BLOG_CHANNEL_ncd_parse 114 -#define BLOG_CHANNEL_ncd_valuemetic 115 -#define BLOG_CHANNEL_ncd_file 116 -#define BLOG_CHANNEL_ncd_netmask 117 -#define BLOG_CHANNEL_ncd_implode 118 -#define BLOG_CHANNEL_ncd_call2 119 -#define BLOG_CHANNEL_ncd_assert 120 -#define BLOG_CHANNEL_ncd_reboot 121 -#define BLOG_CHANNEL_ncd_explode 122 -#define BLOG_CHANNEL_NCDPlaceholderDb 123 -#define BLOG_CHANNEL_NCDVal 124 -#define BLOG_CHANNEL_ncd_net_ipv6_addr 125 -#define BLOG_CHANNEL_ncd_net_ipv6_route 126 -#define BLOG_CHANNEL_ncd_net_ipv4_addr_in_network 127 -#define BLOG_CHANNEL_ncd_net_ipv6_addr_in_network 128 -#define BLOG_CHANNEL_dostest_server 129 -#define BLOG_CHANNEL_dostest_attacker 130 -#define BLOG_CHANNEL_ncd_timer 131 -#define BLOG_CHANNEL_ncd_file_open 132 -#define BLOG_CHANNEL_ncd_backtrack 133 -#define BLOG_CHANNEL_ncd_socket 134 -#define BLOG_CHANNEL_ncd_depend_scope 135 -#define BLOG_CHANNEL_ncd_substr 136 -#define BLOG_CHANNEL_ncd_sys_start_process 137 -#define BLOG_CHANNEL_NCDBuildProgram 138 -#define BLOG_CHANNEL_ncd_log 139 -#define BLOG_CHANNEL_ncd_log_msg 140 -#define BLOG_CHANNEL_ncd_buffer 141 -#define BLOG_CHANNEL_ncd_getenv 142 -#define BLOG_CHANNEL_BThreadSignal 143 -#define BLOG_CHANNEL_BLockReactor 144 -#define BLOG_CHANNEL_ncd_load_module 145 -#define BLOG_CHANNEL_ncd_basic_functions 146 -#define BLOG_CHANNEL_ncd_objref 147 -#define BLOG_NUM_CHANNELS 148 diff --git a/v2rayng/badvpn/generated/blog_channels_list.h b/v2rayng/badvpn/generated/blog_channels_list.h deleted file mode 100644 index 930bd8b288..0000000000 --- a/v2rayng/badvpn/generated/blog_channels_list.h +++ /dev/null @@ -1,148 +0,0 @@ -{"server", 4}, -{"client", 4}, -{"flooder", 4}, -{"tun2socks", 4}, -{"ncd", 4}, -{"ncd_var", 4}, -{"ncd_list", 4}, -{"ncd_depend", 4}, -{"ncd_multidepend", 4}, -{"ncd_dynamic_depend", 4}, -{"ncd_concat", 4}, -{"ncd_if", 4}, -{"ncd_strcmp", 4}, -{"ncd_regex_match", 4}, -{"ncd_logical", 4}, -{"ncd_sleep", 4}, -{"ncd_print", 4}, -{"ncd_blocker", 4}, -{"ncd_run", 4}, -{"ncd_runonce", 4}, -{"ncd_daemon", 4}, -{"ncd_spawn", 4}, -{"ncd_imperative", 4}, -{"ncd_ref", 4}, -{"ncd_index", 4}, -{"ncd_alias", 4}, -{"ncd_process_manager", 4}, -{"ncd_ondemand", 4}, -{"ncd_foreach", 4}, -{"ncd_choose", 4}, -{"ncd_net_backend_waitdevice", 4}, -{"ncd_net_backend_waitlink", 4}, -{"ncd_net_backend_badvpn", 4}, -{"ncd_net_backend_wpa_supplicant", 4}, -{"ncd_net_backend_rfkill", 4}, -{"ncd_net_up", 4}, -{"ncd_net_dns", 4}, -{"ncd_net_iptables", 4}, -{"ncd_net_ipv4_addr", 4}, -{"ncd_net_ipv4_route", 4}, -{"ncd_net_ipv4_dhcp", 4}, -{"ncd_net_ipv4_arp_probe", 4}, -{"ncd_net_watch_interfaces", 4}, -{"ncd_sys_watch_input", 4}, -{"ncd_sys_watch_usb", 4}, -{"ncd_sys_evdev", 4}, -{"ncd_sys_watch_directory", 4}, -{"StreamPeerIO", 4}, -{"DatagramPeerIO", 4}, -{"BReactor", 3}, -{"BSignal", 3}, -{"FragmentProtoAssembler", 4}, -{"BPredicate", 3}, -{"ServerConnection", 4}, -{"Listener", 4}, -{"DataProto", 4}, -{"FrameDecider", 4}, -{"BSocksClient", 4}, -{"BDHCPClientCore", 4}, -{"BDHCPClient", 4}, -{"NCDIfConfig", 4}, -{"BUnixSignal", 4}, -{"BProcess", 4}, -{"PRStreamSink", 4}, -{"PRStreamSource", 4}, -{"PacketProtoDecoder", 4}, -{"DPRelay", 4}, -{"BThreadWork", 4}, -{"DPReceive", 4}, -{"BInputProcess", 4}, -{"NCDUdevMonitorParser", 4}, -{"NCDUdevMonitor", 4}, -{"NCDUdevCache", 4}, -{"NCDUdevManager", 4}, -{"BTime", 4}, -{"BEncryption", 4}, -{"SPProtoDecoder", 4}, -{"LineBuffer", 4}, -{"BTap", 4}, -{"lwip", 4}, -{"NCDConfigTokenizer", 4}, -{"NCDConfigParser", 4}, -{"NCDValParser", 4}, -{"nsskey", 4}, -{"addr", 4}, -{"PasswordListener", 4}, -{"NCDInterfaceMonitor", 4}, -{"NCDRfkillMonitor", 4}, -{"udpgw", 4}, -{"UdpGwClient", 4}, -{"SocksUdpGwClient", 4}, -{"SocksUdpClient", 4}, -{"BNetwork", 4}, -{"BConnection", 4}, -{"BSSLConnection", 4}, -{"BDatagram", 4}, -{"PeerChat", 4}, -{"BArpProbe", 4}, -{"NCDModuleIndex", 4}, -{"NCDModuleProcess", 4}, -{"NCDValGenerator", 4}, -{"ncd_from_string", 4}, -{"ncd_to_string", 4}, -{"ncd_value", 4}, -{"ncd_try", 4}, -{"ncd_sys_request_server", 4}, -{"NCDRequest", 4}, -{"ncd_net_ipv6_wait_dynamic_addr", 4}, -{"NCDRequestClient", 4}, -{"ncd_request", 4}, -{"ncd_sys_request_client", 4}, -{"ncd_exit", 4}, -{"ncd_getargs", 4}, -{"ncd_arithmetic", 4}, -{"ncd_parse", 4}, -{"ncd_valuemetic", 4}, -{"ncd_file", 4}, -{"ncd_netmask", 4}, -{"ncd_implode", 4}, -{"ncd_call2", 4}, -{"ncd_assert", 4}, -{"ncd_reboot", 4}, -{"ncd_explode", 4}, -{"NCDPlaceholderDb", 4}, -{"NCDVal", 4}, -{"ncd_net_ipv6_addr", 4}, -{"ncd_net_ipv6_route", 4}, -{"ncd_net_ipv4_addr_in_network", 4}, -{"ncd_net_ipv6_addr_in_network", 4}, -{"dostest_server", 4}, -{"dostest_attacker", 4}, -{"ncd_timer", 4}, -{"ncd_file_open", 4}, -{"ncd_backtrack", 4}, -{"ncd_socket", 4}, -{"ncd_depend_scope", 4}, -{"ncd_substr", 4}, -{"ncd_sys_start_process", 4}, -{"NCDBuildProgram", 4}, -{"ncd_log", 4}, -{"ncd_log_msg", 4}, -{"ncd_buffer", 4}, -{"ncd_getenv", 4}, -{"BThreadSignal", 4}, -{"BLockReactor", 4}, -{"ncd_load_module", 4}, -{"ncd_basic_functions", 4}, -{"ncd_objref", 4}, diff --git a/v2rayng/badvpn/generated/bproto_addr.h b/v2rayng/badvpn/generated/bproto_addr.h deleted file mode 100644 index fbd96a807d..0000000000 --- a/v2rayng/badvpn/generated/bproto_addr.h +++ /dev/null @@ -1,675 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include -#include - -#include -#include -#include - - -#define addr_SIZEtype (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint8_s)) -#define addr_SIZEip_port (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (2)) -#define addr_SIZEipv4_addr (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (4)) -#define addr_SIZEipv6_addr (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (16)) - -typedef struct { - uint8_t *out; - int used; - int type_count; - int ip_port_count; - int ipv4_addr_count; - int ipv6_addr_count; -} addrWriter; - -static void addrWriter_Init (addrWriter *o, uint8_t *out); -static int addrWriter_Finish (addrWriter *o); -static void addrWriter_Addtype (addrWriter *o, uint8_t v); -static uint8_t * addrWriter_Addip_port (addrWriter *o); -static uint8_t * addrWriter_Addipv4_addr (addrWriter *o); -static uint8_t * addrWriter_Addipv6_addr (addrWriter *o); - -typedef struct { - uint8_t *buf; - int buf_len; - int type_start; - int type_span; - int type_pos; - int ip_port_start; - int ip_port_span; - int ip_port_pos; - int ipv4_addr_start; - int ipv4_addr_span; - int ipv4_addr_pos; - int ipv6_addr_start; - int ipv6_addr_span; - int ipv6_addr_pos; -} addrParser; - -static int addrParser_Init (addrParser *o, uint8_t *buf, int buf_len); -static int addrParser_GotEverything (addrParser *o); -static int addrParser_Gettype (addrParser *o, uint8_t *v); -static void addrParser_Resettype (addrParser *o); -static void addrParser_Forwardtype (addrParser *o); -static int addrParser_Getip_port (addrParser *o, uint8_t **data); -static void addrParser_Resetip_port (addrParser *o); -static void addrParser_Forwardip_port (addrParser *o); -static int addrParser_Getipv4_addr (addrParser *o, uint8_t **data); -static void addrParser_Resetipv4_addr (addrParser *o); -static void addrParser_Forwardipv4_addr (addrParser *o); -static int addrParser_Getipv6_addr (addrParser *o, uint8_t **data); -static void addrParser_Resetipv6_addr (addrParser *o); -static void addrParser_Forwardipv6_addr (addrParser *o); - -void addrWriter_Init (addrWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->type_count = 0; - o->ip_port_count = 0; - o->ipv4_addr_count = 0; - o->ipv6_addr_count = 0; -} - -int addrWriter_Finish (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 1) - ASSERT(o->ip_port_count >= 0 && o->ip_port_count <= 1) - ASSERT(o->ipv4_addr_count >= 0 && o->ipv4_addr_count <= 1) - ASSERT(o->ipv6_addr_count >= 0 && o->ipv6_addr_count <= 1) - - return o->used; -} - -void addrWriter_Addtype (addrWriter *o, uint8_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT8); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint8_s data; - data.v = htol8(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint8_s); - - o->type_count++; -} - -uint8_t * addrWriter_Addip_port (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ip_port_count == 0) - - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(2); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (2); - - o->ip_port_count++; - - return dest; -} - -uint8_t * addrWriter_Addipv4_addr (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ipv4_addr_count == 0) - - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(4); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (4); - - o->ipv4_addr_count++; - - return dest; -} - -uint8_t * addrWriter_Addipv6_addr (addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->ipv6_addr_count == 0) - - - struct BProto_header_s header; - header.id = htol16(4); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(16); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (16); - - o->ipv6_addr_count++; - - return dest; -} - -int addrParser_Init (addrParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->type_start = o->buf_len; - o->type_span = 0; - o->type_pos = 0; - o->ip_port_start = o->buf_len; - o->ip_port_span = 0; - o->ip_port_pos = 0; - o->ipv4_addr_start = o->buf_len; - o->ipv4_addr_span = 0; - o->ipv4_addr_pos = 0; - o->ipv6_addr_start = o->buf_len; - o->ipv6_addr_span = 0; - o->ipv6_addr_pos = 0; - - int type_count = 0; - int ip_port_count = 0; - int ipv4_addr_count = 0; - int ipv6_addr_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - case 1: - if (o->type_start == o->buf_len) { - o->type_start = entry_pos; - } - o->type_span = pos - o->type_start; - type_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (2))) { - return 0; - } - if (o->ip_port_start == o->buf_len) { - o->ip_port_start = entry_pos; - } - o->ip_port_span = pos - o->ip_port_start; - ip_port_count++; - break; - case 3: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (4))) { - return 0; - } - if (o->ipv4_addr_start == o->buf_len) { - o->ipv4_addr_start = entry_pos; - } - o->ipv4_addr_span = pos - o->ipv4_addr_start; - ipv4_addr_count++; - break; - case 4: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (16))) { - return 0; - } - if (o->ipv6_addr_start == o->buf_len) { - o->ipv6_addr_start = entry_pos; - } - o->ipv6_addr_span = pos - o->ipv6_addr_start; - ipv6_addr_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(type_count == 1)) { - return 0; - } - if (!(ip_port_count <= 1)) { - return 0; - } - if (!(ipv4_addr_count <= 1)) { - return 0; - } - if (!(ipv6_addr_count <= 1)) { - return 0; - } - - return 1; -} - -int addrParser_GotEverything (addrParser *o) -{ - return ( - o->type_pos == o->type_span - && - o->ip_port_pos == o->ip_port_span - && - o->ipv4_addr_pos == o->ipv4_addr_span - && - o->ipv6_addr_pos == o->ipv6_addr_span - ); -} - -int addrParser_Gettype (addrParser *o, uint8_t *v) -{ - ASSERT(o->type_pos >= 0) - ASSERT(o->type_pos <= o->type_span) - - int left = o->type_span - o->type_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->type_start + o->type_pos, sizeof(header)); - o->type_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - struct BProto_uint8_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - if (id == 1) { - *v = ltoh8(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->type_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->type_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->type_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->type_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resettype (addrParser *o) -{ - o->type_pos = 0; -} - -void addrParser_Forwardtype (addrParser *o) -{ - o->type_pos = o->type_span; -} - -int addrParser_Getip_port (addrParser *o, uint8_t **data) -{ - ASSERT(o->ip_port_pos >= 0) - ASSERT(o->ip_port_pos <= o->ip_port_span) - - int left = o->ip_port_span - o->ip_port_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ip_port_start + o->ip_port_pos, sizeof(header)); - o->ip_port_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ip_port_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ip_port_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ip_port_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ip_port_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ip_port_start + o->ip_port_pos, sizeof(val)); - o->ip_port_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ip_port_start + o->ip_port_pos; - o->ip_port_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 2) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetip_port (addrParser *o) -{ - o->ip_port_pos = 0; -} - -void addrParser_Forwardip_port (addrParser *o) -{ - o->ip_port_pos = o->ip_port_span; -} - -int addrParser_Getipv4_addr (addrParser *o, uint8_t **data) -{ - ASSERT(o->ipv4_addr_pos >= 0) - ASSERT(o->ipv4_addr_pos <= o->ipv4_addr_span) - - int left = o->ipv4_addr_span - o->ipv4_addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ipv4_addr_start + o->ipv4_addr_pos, sizeof(header)); - o->ipv4_addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ipv4_addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ipv4_addr_start + o->ipv4_addr_pos, sizeof(val)); - o->ipv4_addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ipv4_addr_start + o->ipv4_addr_pos; - o->ipv4_addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 3) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetipv4_addr (addrParser *o) -{ - o->ipv4_addr_pos = 0; -} - -void addrParser_Forwardipv4_addr (addrParser *o) -{ - o->ipv4_addr_pos = o->ipv4_addr_span; -} - -int addrParser_Getipv6_addr (addrParser *o, uint8_t **data) -{ - ASSERT(o->ipv6_addr_pos >= 0) - ASSERT(o->ipv6_addr_pos <= o->ipv6_addr_span) - - int left = o->ipv6_addr_span - o->ipv6_addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->ipv6_addr_start + o->ipv6_addr_pos, sizeof(header)); - o->ipv6_addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->ipv6_addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->ipv6_addr_start + o->ipv6_addr_pos, sizeof(val)); - o->ipv6_addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->ipv6_addr_start + o->ipv6_addr_pos; - o->ipv6_addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 4) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void addrParser_Resetipv6_addr (addrParser *o) -{ - o->ipv6_addr_pos = 0; -} - -void addrParser_Forwardipv6_addr (addrParser *o) -{ - o->ipv6_addr_pos = o->ipv6_addr_span; -} - diff --git a/v2rayng/badvpn/generated/bproto_bproto_test.h b/v2rayng/badvpn/generated/bproto_bproto_test.h deleted file mode 100644 index dc4ad80431..0000000000 --- a/v2rayng/badvpn/generated/bproto_bproto_test.h +++ /dev/null @@ -1,1029 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include -#include - -#include -#include -#include - - -#define msg1_SIZEa (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg1_SIZEb (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint32_s)) -#define msg1_SIZEc (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint64_s)) -#define msg1_SIZEd (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg1_SIZEe (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint8_s)) -#define msg1_SIZEf(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg1_SIZEg (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (4)) - -typedef struct { - uint8_t *out; - int used; - int a_count; - int b_count; - int c_count; - int d_count; - int e_count; - int f_count; - int g_count; -} msg1Writer; - -static void msg1Writer_Init (msg1Writer *o, uint8_t *out); -static int msg1Writer_Finish (msg1Writer *o); -static void msg1Writer_Adda (msg1Writer *o, uint16_t v); -static void msg1Writer_Addb (msg1Writer *o, uint32_t v); -static void msg1Writer_Addc (msg1Writer *o, uint64_t v); -static void msg1Writer_Addd (msg1Writer *o, uint16_t v); -static void msg1Writer_Adde (msg1Writer *o, uint8_t v); -static uint8_t * msg1Writer_Addf (msg1Writer *o, int len); -static uint8_t * msg1Writer_Addg (msg1Writer *o); - -typedef struct { - uint8_t *buf; - int buf_len; - int a_start; - int a_span; - int a_pos; - int b_start; - int b_span; - int b_pos; - int c_start; - int c_span; - int c_pos; - int d_start; - int d_span; - int d_pos; - int e_start; - int e_span; - int e_pos; - int f_start; - int f_span; - int f_pos; - int g_start; - int g_span; - int g_pos; -} msg1Parser; - -static int msg1Parser_Init (msg1Parser *o, uint8_t *buf, int buf_len); -static int msg1Parser_GotEverything (msg1Parser *o); -static int msg1Parser_Geta (msg1Parser *o, uint16_t *v); -static void msg1Parser_Reseta (msg1Parser *o); -static void msg1Parser_Forwarda (msg1Parser *o); -static int msg1Parser_Getb (msg1Parser *o, uint32_t *v); -static void msg1Parser_Resetb (msg1Parser *o); -static void msg1Parser_Forwardb (msg1Parser *o); -static int msg1Parser_Getc (msg1Parser *o, uint64_t *v); -static void msg1Parser_Resetc (msg1Parser *o); -static void msg1Parser_Forwardc (msg1Parser *o); -static int msg1Parser_Getd (msg1Parser *o, uint16_t *v); -static void msg1Parser_Resetd (msg1Parser *o); -static void msg1Parser_Forwardd (msg1Parser *o); -static int msg1Parser_Gete (msg1Parser *o, uint8_t *v); -static void msg1Parser_Resete (msg1Parser *o); -static void msg1Parser_Forwarde (msg1Parser *o); -static int msg1Parser_Getf (msg1Parser *o, uint8_t **data, int *data_len); -static void msg1Parser_Resetf (msg1Parser *o); -static void msg1Parser_Forwardf (msg1Parser *o); -static int msg1Parser_Getg (msg1Parser *o, uint8_t **data); -static void msg1Parser_Resetg (msg1Parser *o); -static void msg1Parser_Forwardg (msg1Parser *o); - -void msg1Writer_Init (msg1Writer *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->a_count = 0; - o->b_count = 0; - o->c_count = 0; - o->d_count = 0; - o->e_count = 0; - o->f_count = 0; - o->g_count = 0; -} - -int msg1Writer_Finish (msg1Writer *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->a_count == 1) - ASSERT(o->b_count >= 0 && o->b_count <= 1) - ASSERT(o->c_count >= 1) - ASSERT(o->d_count >= 0) - ASSERT(o->e_count == 1) - ASSERT(o->f_count == 1) - ASSERT(o->g_count == 1) - - return o->used; -} - -void msg1Writer_Adda (msg1Writer *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->a_count == 0) - - - struct BProto_header_s header; - header.id = htol16(5); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->a_count++; -} - -void msg1Writer_Addb (msg1Writer *o, uint32_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->b_count == 0) - - - struct BProto_header_s header; - header.id = htol16(6); - header.type = htol16(BPROTO_TYPE_UINT32); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint32_s data; - data.v = htol32(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint32_s); - - o->b_count++; -} - -void msg1Writer_Addc (msg1Writer *o, uint64_t v) -{ - ASSERT(o->used >= 0) - - - - struct BProto_header_s header; - header.id = htol16(7); - header.type = htol16(BPROTO_TYPE_UINT64); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint64_s data; - data.v = htol64(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint64_s); - - o->c_count++; -} - -void msg1Writer_Addd (msg1Writer *o, uint16_t v) -{ - ASSERT(o->used >= 0) - - - - struct BProto_header_s header; - header.id = htol16(8); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->d_count++; -} - -void msg1Writer_Adde (msg1Writer *o, uint8_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->e_count == 0) - - - struct BProto_header_s header; - header.id = htol16(9); - header.type = htol16(BPROTO_TYPE_UINT8); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint8_s data; - data.v = htol8(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint8_s); - - o->e_count++; -} - -uint8_t * msg1Writer_Addf (msg1Writer *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->f_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(10); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->f_count++; - - return dest; -} - -uint8_t * msg1Writer_Addg (msg1Writer *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->g_count == 0) - - - struct BProto_header_s header; - header.id = htol16(11); - header.type = htol16(BPROTO_TYPE_CONSTDATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(4); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += (4); - - o->g_count++; - - return dest; -} - -int msg1Parser_Init (msg1Parser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->a_start = o->buf_len; - o->a_span = 0; - o->a_pos = 0; - o->b_start = o->buf_len; - o->b_span = 0; - o->b_pos = 0; - o->c_start = o->buf_len; - o->c_span = 0; - o->c_pos = 0; - o->d_start = o->buf_len; - o->d_span = 0; - o->d_pos = 0; - o->e_start = o->buf_len; - o->e_span = 0; - o->e_pos = 0; - o->f_start = o->buf_len; - o->f_span = 0; - o->f_pos = 0; - o->g_start = o->buf_len; - o->g_span = 0; - o->g_pos = 0; - - int a_count = 0; - int b_count = 0; - int c_count = 0; - int d_count = 0; - int e_count = 0; - int f_count = 0; - int g_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - case 9: - if (o->e_start == o->buf_len) { - o->e_start = entry_pos; - } - o->e_span = pos - o->e_start; - e_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 5: - if (o->a_start == o->buf_len) { - o->a_start = entry_pos; - } - o->a_span = pos - o->a_start; - a_count++; - break; - case 8: - if (o->d_start == o->buf_len) { - o->d_start = entry_pos; - } - o->d_span = pos - o->d_start; - d_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - case 6: - if (o->b_start == o->buf_len) { - o->b_start = entry_pos; - } - o->b_span = pos - o->b_start; - b_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - case 7: - if (o->c_start == o->buf_len) { - o->c_start = entry_pos; - } - o->c_span = pos - o->c_start; - c_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 10: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->f_start == o->buf_len) { - o->f_start = entry_pos; - } - o->f_span = pos - o->f_start; - f_count++; - break; - case 11: - if (!(type == BPROTO_TYPE_CONSTDATA)) { - return 0; - } - if (!(payload_len == (4))) { - return 0; - } - if (o->g_start == o->buf_len) { - o->g_start = entry_pos; - } - o->g_span = pos - o->g_start; - g_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(a_count == 1)) { - return 0; - } - if (!(b_count <= 1)) { - return 0; - } - if (!(c_count >= 1)) { - return 0; - } - if (!(e_count == 1)) { - return 0; - } - if (!(f_count == 1)) { - return 0; - } - if (!(g_count == 1)) { - return 0; - } - - return 1; -} - -int msg1Parser_GotEverything (msg1Parser *o) -{ - return ( - o->a_pos == o->a_span - && - o->b_pos == o->b_span - && - o->c_pos == o->c_span - && - o->d_pos == o->d_span - && - o->e_pos == o->e_span - && - o->f_pos == o->f_span - && - o->g_pos == o->g_span - ); -} - -int msg1Parser_Geta (msg1Parser *o, uint16_t *v) -{ - ASSERT(o->a_pos >= 0) - ASSERT(o->a_pos <= o->a_span) - - int left = o->a_span - o->a_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->a_start + o->a_pos, sizeof(header)); - o->a_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->a_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->a_start + o->a_pos, sizeof(val)); - o->a_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 5) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->a_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->a_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->a_start + o->a_pos, sizeof(val)); - o->a_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->a_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Reseta (msg1Parser *o) -{ - o->a_pos = 0; -} - -void msg1Parser_Forwarda (msg1Parser *o) -{ - o->a_pos = o->a_span; -} - -int msg1Parser_Getb (msg1Parser *o, uint32_t *v) -{ - ASSERT(o->b_pos >= 0) - ASSERT(o->b_pos <= o->b_span) - - int left = o->b_span - o->b_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->b_start + o->b_pos, sizeof(header)); - o->b_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->b_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->b_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - struct BProto_uint32_s val; - memcpy(&val, o->buf + o->b_start + o->b_pos, sizeof(val)); - o->b_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - if (id == 6) { - *v = ltoh32(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->b_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->b_start + o->b_pos, sizeof(val)); - o->b_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->b_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetb (msg1Parser *o) -{ - o->b_pos = 0; -} - -void msg1Parser_Forwardb (msg1Parser *o) -{ - o->b_pos = o->b_span; -} - -int msg1Parser_Getc (msg1Parser *o, uint64_t *v) -{ - ASSERT(o->c_pos >= 0) - ASSERT(o->c_pos <= o->c_span) - - int left = o->c_span - o->c_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->c_start + o->c_pos, sizeof(header)); - o->c_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->c_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->c_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->c_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - struct BProto_uint64_s val; - memcpy(&val, o->buf + o->c_start + o->c_pos, sizeof(val)); - o->c_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - if (id == 7) { - *v = ltoh64(val.v); - return 1; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->c_start + o->c_pos, sizeof(val)); - o->c_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->c_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetc (msg1Parser *o) -{ - o->c_pos = 0; -} - -void msg1Parser_Forwardc (msg1Parser *o) -{ - o->c_pos = o->c_span; -} - -int msg1Parser_Getd (msg1Parser *o, uint16_t *v) -{ - ASSERT(o->d_pos >= 0) - ASSERT(o->d_pos <= o->d_span) - - int left = o->d_span - o->d_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->d_start + o->d_pos, sizeof(header)); - o->d_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->d_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->d_start + o->d_pos, sizeof(val)); - o->d_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 8) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->d_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->d_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->d_start + o->d_pos, sizeof(val)); - o->d_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->d_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetd (msg1Parser *o) -{ - o->d_pos = 0; -} - -void msg1Parser_Forwardd (msg1Parser *o) -{ - o->d_pos = o->d_span; -} - -int msg1Parser_Gete (msg1Parser *o, uint8_t *v) -{ - ASSERT(o->e_pos >= 0) - ASSERT(o->e_pos <= o->e_span) - - int left = o->e_span - o->e_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->e_start + o->e_pos, sizeof(header)); - o->e_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - struct BProto_uint8_s val; - memcpy(&val, o->buf + o->e_start + o->e_pos, sizeof(val)); - o->e_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - if (id == 9) { - *v = ltoh8(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->e_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->e_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->e_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->e_start + o->e_pos, sizeof(val)); - o->e_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->e_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resete (msg1Parser *o) -{ - o->e_pos = 0; -} - -void msg1Parser_Forwarde (msg1Parser *o) -{ - o->e_pos = o->e_span; -} - -int msg1Parser_Getf (msg1Parser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->f_pos >= 0) - ASSERT(o->f_pos <= o->f_span) - - int left = o->f_span - o->f_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->f_start + o->f_pos, sizeof(header)); - o->f_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->f_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->f_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->f_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->f_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->f_start + o->f_pos, sizeof(val)); - o->f_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->f_start + o->f_pos; - o->f_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 10) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetf (msg1Parser *o) -{ - o->f_pos = 0; -} - -void msg1Parser_Forwardf (msg1Parser *o) -{ - o->f_pos = o->f_span; -} - -int msg1Parser_Getg (msg1Parser *o, uint8_t **data) -{ - ASSERT(o->g_pos >= 0) - ASSERT(o->g_pos <= o->g_span) - - int left = o->g_span - o->g_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->g_start + o->g_pos, sizeof(header)); - o->g_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->g_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->g_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->g_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->g_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->g_start + o->g_pos, sizeof(val)); - o->g_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->g_start + o->g_pos; - o->g_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_CONSTDATA && id == 11) { - *data = payload; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg1Parser_Resetg (msg1Parser *o) -{ - o->g_pos = 0; -} - -void msg1Parser_Forwardg (msg1Parser *o) -{ - o->g_pos = o->g_span; -} - diff --git a/v2rayng/badvpn/generated/bproto_msgproto.h b/v2rayng/badvpn/generated/bproto_msgproto.h deleted file mode 100644 index e429223d69..0000000000 --- a/v2rayng/badvpn/generated/bproto_msgproto.h +++ /dev/null @@ -1,2122 +0,0 @@ -/* - DO NOT EDIT THIS FILE! - This file was automatically generated by the bproto generator. -*/ - -#include -#include - -#include -#include -#include - - -#define msg_SIZEtype (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg_SIZEpayload(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int type_count; - int payload_count; -} msgWriter; - -static void msgWriter_Init (msgWriter *o, uint8_t *out); -static int msgWriter_Finish (msgWriter *o); -static void msgWriter_Addtype (msgWriter *o, uint16_t v); -static uint8_t * msgWriter_Addpayload (msgWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int type_start; - int type_span; - int type_pos; - int payload_start; - int payload_span; - int payload_pos; -} msgParser; - -static int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len); -static int msgParser_GotEverything (msgParser *o); -static int msgParser_Gettype (msgParser *o, uint16_t *v); -static void msgParser_Resettype (msgParser *o); -static void msgParser_Forwardtype (msgParser *o); -static int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len); -static void msgParser_Resetpayload (msgParser *o); -static void msgParser_Forwardpayload (msgParser *o); - -void msgWriter_Init (msgWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->type_count = 0; - o->payload_count = 0; -} - -int msgWriter_Finish (msgWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 1) - ASSERT(o->payload_count == 1) - - return o->used; -} - -void msgWriter_Addtype (msgWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->type_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->type_count++; -} - -uint8_t * msgWriter_Addpayload (msgWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->payload_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->payload_count++; - - return dest; -} - -int msgParser_Init (msgParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->type_start = o->buf_len; - o->type_span = 0; - o->type_pos = 0; - o->payload_start = o->buf_len; - o->payload_span = 0; - o->payload_pos = 0; - - int type_count = 0; - int payload_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->type_start == o->buf_len) { - o->type_start = entry_pos; - } - o->type_span = pos - o->type_start; - type_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->payload_start == o->buf_len) { - o->payload_start = entry_pos; - } - o->payload_span = pos - o->payload_start; - payload_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(type_count == 1)) { - return 0; - } - if (!(payload_count == 1)) { - return 0; - } - - return 1; -} - -int msgParser_GotEverything (msgParser *o) -{ - return ( - o->type_pos == o->type_span - && - o->payload_pos == o->payload_span - ); -} - -int msgParser_Gettype (msgParser *o, uint16_t *v) -{ - ASSERT(o->type_pos >= 0) - ASSERT(o->type_pos <= o->type_span) - - int left = o->type_span - o->type_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->type_start + o->type_pos, sizeof(header)); - o->type_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->type_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->type_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->type_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->type_start + o->type_pos, sizeof(val)); - o->type_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->type_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msgParser_Resettype (msgParser *o) -{ - o->type_pos = 0; -} - -void msgParser_Forwardtype (msgParser *o) -{ - o->type_pos = o->type_span; -} - -int msgParser_Getpayload (msgParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->payload_pos >= 0) - ASSERT(o->payload_pos <= o->payload_span) - - int left = o->payload_span - o->payload_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->payload_start + o->payload_pos, sizeof(header)); - o->payload_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->payload_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->payload_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->payload_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->payload_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->payload_start + o->payload_pos, sizeof(val)); - o->payload_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->payload_start + o->payload_pos; - o->payload_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msgParser_Resetpayload (msgParser *o) -{ - o->payload_pos = 0; -} - -void msgParser_Forwardpayload (msgParser *o) -{ - o->payload_pos = o->payload_span; -} - -#define msg_youconnect_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_SIZEpassword (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint64_s)) - -typedef struct { - uint8_t *out; - int used; - int addr_count; - int key_count; - int password_count; -} msg_youconnectWriter; - -static void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out); -static int msg_youconnectWriter_Finish (msg_youconnectWriter *o); -static uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len); -static uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len); -static void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v); - -typedef struct { - uint8_t *buf; - int buf_len; - int addr_start; - int addr_span; - int addr_pos; - int key_start; - int key_span; - int key_pos; - int password_start; - int password_span; - int password_pos; -} msg_youconnectParser; - -static int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len); -static int msg_youconnectParser_GotEverything (msg_youconnectParser *o); -static int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len); -static void msg_youconnectParser_Resetaddr (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o); -static int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len); -static void msg_youconnectParser_Resetkey (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardkey (msg_youconnectParser *o); -static int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v); -static void msg_youconnectParser_Resetpassword (msg_youconnectParser *o); -static void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o); - -void msg_youconnectWriter_Init (msg_youconnectWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->addr_count = 0; - o->key_count = 0; - o->password_count = 0; -} - -int msg_youconnectWriter_Finish (msg_youconnectWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->addr_count >= 1) - ASSERT(o->key_count >= 0 && o->key_count <= 1) - ASSERT(o->password_count >= 0 && o->password_count <= 1) - - return o->used; -} - -uint8_t * msg_youconnectWriter_Addaddr (msg_youconnectWriter *o, int len) -{ - ASSERT(o->used >= 0) - - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->addr_count++; - - return dest; -} - -uint8_t * msg_youconnectWriter_Addkey (msg_youconnectWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->key_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->key_count++; - - return dest; -} - -void msg_youconnectWriter_Addpassword (msg_youconnectWriter *o, uint64_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->password_count == 0) - - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_UINT64); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint64_s data; - data.v = htol64(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint64_s); - - o->password_count++; -} - -int msg_youconnectParser_Init (msg_youconnectParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->addr_start = o->buf_len; - o->addr_span = 0; - o->addr_pos = 0; - o->key_start = o->buf_len; - o->key_span = 0; - o->key_pos = 0; - o->password_start = o->buf_len; - o->password_span = 0; - o->password_pos = 0; - - int addr_count = 0; - int key_count = 0; - int password_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - case 3: - if (o->password_start == o->buf_len) { - o->password_start = entry_pos; - } - o->password_span = pos - o->password_start; - password_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 1: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->addr_start == o->buf_len) { - o->addr_start = entry_pos; - } - o->addr_span = pos - o->addr_start; - addr_count++; - break; - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->key_start == o->buf_len) { - o->key_start = entry_pos; - } - o->key_span = pos - o->key_start; - key_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(addr_count >= 1)) { - return 0; - } - if (!(key_count <= 1)) { - return 0; - } - if (!(password_count <= 1)) { - return 0; - } - - return 1; -} - -int msg_youconnectParser_GotEverything (msg_youconnectParser *o) -{ - return ( - o->addr_pos == o->addr_span - && - o->key_pos == o->key_span - && - o->password_pos == o->password_span - ); -} - -int msg_youconnectParser_Getaddr (msg_youconnectParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->addr_pos >= 0) - ASSERT(o->addr_pos <= o->addr_span) - - int left = o->addr_span - o->addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); - o->addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); - o->addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->addr_start + o->addr_pos; - o->addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 1) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetaddr (msg_youconnectParser *o) -{ - o->addr_pos = 0; -} - -void msg_youconnectParser_Forwardaddr (msg_youconnectParser *o) -{ - o->addr_pos = o->addr_span; -} - -int msg_youconnectParser_Getkey (msg_youconnectParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->key_pos >= 0) - ASSERT(o->key_pos <= o->key_span) - - int left = o->key_span - o->key_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); - o->key_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->key_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->key_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->key_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->key_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); - o->key_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->key_start + o->key_pos; - o->key_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetkey (msg_youconnectParser *o) -{ - o->key_pos = 0; -} - -void msg_youconnectParser_Forwardkey (msg_youconnectParser *o) -{ - o->key_pos = o->key_span; -} - -int msg_youconnectParser_Getpassword (msg_youconnectParser *o, uint64_t *v) -{ - ASSERT(o->password_pos >= 0) - ASSERT(o->password_pos <= o->password_span) - - int left = o->password_span - o->password_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->password_start + o->password_pos, sizeof(header)); - o->password_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->password_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->password_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->password_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - struct BProto_uint64_s val; - memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); - o->password_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - if (id == 3) { - *v = ltoh64(val.v); - return 1; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->password_start + o->password_pos, sizeof(val)); - o->password_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->password_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnectParser_Resetpassword (msg_youconnectParser *o) -{ - o->password_pos = 0; -} - -void msg_youconnectParser_Forwardpassword (msg_youconnectParser *o) -{ - o->password_pos = o->password_span; -} - -#define msg_youconnect_addr_SIZEname(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_youconnect_addr_SIZEaddr(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int name_count; - int addr_count; -} msg_youconnect_addrWriter; - -static void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out); -static int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o); -static uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len); -static uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int name_start; - int name_span; - int name_pos; - int addr_start; - int addr_span; - int addr_pos; -} msg_youconnect_addrParser; - -static int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len); -static int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o); -static int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); -static void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o); -static void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o); -static int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len); -static void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o); -static void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o); - -void msg_youconnect_addrWriter_Init (msg_youconnect_addrWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->name_count = 0; - o->addr_count = 0; -} - -int msg_youconnect_addrWriter_Finish (msg_youconnect_addrWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->name_count == 1) - ASSERT(o->addr_count == 1) - - return o->used; -} - -uint8_t * msg_youconnect_addrWriter_Addname (msg_youconnect_addrWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->name_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->name_count++; - - return dest; -} - -uint8_t * msg_youconnect_addrWriter_Addaddr (msg_youconnect_addrWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->addr_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->addr_count++; - - return dest; -} - -int msg_youconnect_addrParser_Init (msg_youconnect_addrParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->name_start = o->buf_len; - o->name_span = 0; - o->name_pos = 0; - o->addr_start = o->buf_len; - o->addr_span = 0; - o->addr_pos = 0; - - int name_count = 0; - int addr_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 1: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->name_start == o->buf_len) { - o->name_start = entry_pos; - } - o->name_span = pos - o->name_start; - name_count++; - break; - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->addr_start == o->buf_len) { - o->addr_start = entry_pos; - } - o->addr_span = pos - o->addr_start; - addr_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(name_count == 1)) { - return 0; - } - if (!(addr_count == 1)) { - return 0; - } - - return 1; -} - -int msg_youconnect_addrParser_GotEverything (msg_youconnect_addrParser *o) -{ - return ( - o->name_pos == o->name_span - && - o->addr_pos == o->addr_span - ); -} - -int msg_youconnect_addrParser_Getname (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->name_pos >= 0) - ASSERT(o->name_pos <= o->name_span) - - int left = o->name_span - o->name_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->name_start + o->name_pos, sizeof(header)); - o->name_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->name_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->name_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->name_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->name_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->name_start + o->name_pos, sizeof(val)); - o->name_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->name_start + o->name_pos; - o->name_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 1) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnect_addrParser_Resetname (msg_youconnect_addrParser *o) -{ - o->name_pos = 0; -} - -void msg_youconnect_addrParser_Forwardname (msg_youconnect_addrParser *o) -{ - o->name_pos = o->name_span; -} - -int msg_youconnect_addrParser_Getaddr (msg_youconnect_addrParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->addr_pos >= 0) - ASSERT(o->addr_pos <= o->addr_span) - - int left = o->addr_span - o->addr_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->addr_start + o->addr_pos, sizeof(header)); - o->addr_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->addr_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->addr_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->addr_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->addr_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->addr_start + o->addr_pos, sizeof(val)); - o->addr_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->addr_start + o->addr_pos; - o->addr_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_youconnect_addrParser_Resetaddr (msg_youconnect_addrParser *o) -{ - o->addr_pos = 0; -} - -void msg_youconnect_addrParser_Forwardaddr (msg_youconnect_addrParser *o) -{ - o->addr_pos = o->addr_span; -} - -#define msg_seed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) -#define msg_seed_SIZEkey(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) -#define msg_seed_SIZEiv(_len) (sizeof(struct BProto_header_s) + sizeof(struct BProto_data_header_s) + (_len)) - -typedef struct { - uint8_t *out; - int used; - int seed_id_count; - int key_count; - int iv_count; -} msg_seedWriter; - -static void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out); -static int msg_seedWriter_Finish (msg_seedWriter *o); -static void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v); -static uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len); -static uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len); - -typedef struct { - uint8_t *buf; - int buf_len; - int seed_id_start; - int seed_id_span; - int seed_id_pos; - int key_start; - int key_span; - int key_pos; - int iv_start; - int iv_span; - int iv_pos; -} msg_seedParser; - -static int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len); -static int msg_seedParser_GotEverything (msg_seedParser *o); -static int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v); -static void msg_seedParser_Resetseed_id (msg_seedParser *o); -static void msg_seedParser_Forwardseed_id (msg_seedParser *o); -static int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len); -static void msg_seedParser_Resetkey (msg_seedParser *o); -static void msg_seedParser_Forwardkey (msg_seedParser *o); -static int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len); -static void msg_seedParser_Resetiv (msg_seedParser *o); -static void msg_seedParser_Forwardiv (msg_seedParser *o); - -void msg_seedWriter_Init (msg_seedWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->seed_id_count = 0; - o->key_count = 0; - o->iv_count = 0; -} - -int msg_seedWriter_Finish (msg_seedWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 1) - ASSERT(o->key_count == 1) - ASSERT(o->iv_count == 1) - - return o->used; -} - -void msg_seedWriter_Addseed_id (msg_seedWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->seed_id_count++; -} - -uint8_t * msg_seedWriter_Addkey (msg_seedWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->key_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(2); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->key_count++; - - return dest; -} - -uint8_t * msg_seedWriter_Addiv (msg_seedWriter *o, int len) -{ - ASSERT(o->used >= 0) - ASSERT(o->iv_count == 0) - ASSERT(len >= 0 && len <= UINT32_MAX) - - struct BProto_header_s header; - header.id = htol16(3); - header.type = htol16(BPROTO_TYPE_DATA); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_data_header_s data; - data.len = htol32(len); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_data_header_s); - - uint8_t *dest = (o->out + o->used); - o->used += len; - - o->iv_count++; - - return dest; -} - -int msg_seedParser_Init (msg_seedParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->seed_id_start = o->buf_len; - o->seed_id_span = 0; - o->seed_id_pos = 0; - o->key_start = o->buf_len; - o->key_span = 0; - o->key_pos = 0; - o->iv_start = o->buf_len; - o->iv_span = 0; - o->iv_pos = 0; - - int seed_id_count = 0; - int key_count = 0; - int iv_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->seed_id_start == o->buf_len) { - o->seed_id_start = entry_pos; - } - o->seed_id_span = pos - o->seed_id_start; - seed_id_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - case 2: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->key_start == o->buf_len) { - o->key_start = entry_pos; - } - o->key_span = pos - o->key_start; - key_count++; - break; - case 3: - if (!(type == BPROTO_TYPE_DATA)) { - return 0; - } - if (o->iv_start == o->buf_len) { - o->iv_start = entry_pos; - } - o->iv_span = pos - o->iv_start; - iv_count++; - break; - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(seed_id_count == 1)) { - return 0; - } - if (!(key_count == 1)) { - return 0; - } - if (!(iv_count == 1)) { - return 0; - } - - return 1; -} - -int msg_seedParser_GotEverything (msg_seedParser *o) -{ - return ( - o->seed_id_pos == o->seed_id_span - && - o->key_pos == o->key_span - && - o->iv_pos == o->iv_span - ); -} - -int msg_seedParser_Getseed_id (msg_seedParser *o, uint16_t *v) -{ - ASSERT(o->seed_id_pos >= 0) - ASSERT(o->seed_id_pos <= o->seed_id_span) - - int left = o->seed_id_span - o->seed_id_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); - o->seed_id_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->seed_id_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->seed_id_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->seed_id_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->seed_id_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetseed_id (msg_seedParser *o) -{ - o->seed_id_pos = 0; -} - -void msg_seedParser_Forwardseed_id (msg_seedParser *o) -{ - o->seed_id_pos = o->seed_id_span; -} - -int msg_seedParser_Getkey (msg_seedParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->key_pos >= 0) - ASSERT(o->key_pos <= o->key_span) - - int left = o->key_span - o->key_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->key_start + o->key_pos, sizeof(header)); - o->key_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->key_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->key_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->key_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->key_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->key_start + o->key_pos, sizeof(val)); - o->key_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->key_start + o->key_pos; - o->key_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 2) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetkey (msg_seedParser *o) -{ - o->key_pos = 0; -} - -void msg_seedParser_Forwardkey (msg_seedParser *o) -{ - o->key_pos = o->key_span; -} - -int msg_seedParser_Getiv (msg_seedParser *o, uint8_t **data, int *data_len) -{ - ASSERT(o->iv_pos >= 0) - ASSERT(o->iv_pos <= o->iv_span) - - int left = o->iv_span - o->iv_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->iv_start + o->iv_pos, sizeof(header)); - o->iv_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->iv_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - o->iv_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->iv_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->iv_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->iv_start + o->iv_pos, sizeof(val)); - o->iv_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - uint8_t *payload = o->buf + o->iv_start + o->iv_pos; - o->iv_pos += payload_len; - left -= payload_len; - - if (type == BPROTO_TYPE_DATA && id == 3) { - *data = payload; - *data_len = payload_len; - return 1; - } - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_seedParser_Resetiv (msg_seedParser *o) -{ - o->iv_pos = 0; -} - -void msg_seedParser_Forwardiv (msg_seedParser *o) -{ - o->iv_pos = o->iv_span; -} - -#define msg_confirmseed_SIZEseed_id (sizeof(struct BProto_header_s) + sizeof(struct BProto_uint16_s)) - -typedef struct { - uint8_t *out; - int used; - int seed_id_count; -} msg_confirmseedWriter; - -static void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out); -static int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o); -static void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v); - -typedef struct { - uint8_t *buf; - int buf_len; - int seed_id_start; - int seed_id_span; - int seed_id_pos; -} msg_confirmseedParser; - -static int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len); -static int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o); -static int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v); -static void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o); -static void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o); - -void msg_confirmseedWriter_Init (msg_confirmseedWriter *o, uint8_t *out) -{ - o->out = out; - o->used = 0; - o->seed_id_count = 0; -} - -int msg_confirmseedWriter_Finish (msg_confirmseedWriter *o) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 1) - - return o->used; -} - -void msg_confirmseedWriter_Addseed_id (msg_confirmseedWriter *o, uint16_t v) -{ - ASSERT(o->used >= 0) - ASSERT(o->seed_id_count == 0) - - - struct BProto_header_s header; - header.id = htol16(1); - header.type = htol16(BPROTO_TYPE_UINT16); - memcpy(o->out + o->used, &header, sizeof(header)); - o->used += sizeof(struct BProto_header_s); - - struct BProto_uint16_s data; - data.v = htol16(v); - memcpy(o->out + o->used, &data, sizeof(data)); - o->used += sizeof(struct BProto_uint16_s); - - o->seed_id_count++; -} - -int msg_confirmseedParser_Init (msg_confirmseedParser *o, uint8_t *buf, int buf_len) -{ - ASSERT(buf_len >= 0) - - o->buf = buf; - o->buf_len = buf_len; - o->seed_id_start = o->buf_len; - o->seed_id_span = 0; - o->seed_id_pos = 0; - - int seed_id_count = 0; - - int pos = 0; - int left = o->buf_len; - - while (left > 0) { - int entry_pos = pos; - - if (!(left >= sizeof(struct BProto_header_s))) { - return 0; - } - struct BProto_header_s header; - memcpy(&header, o->buf + pos, sizeof(header)); - pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - if (!(left >= sizeof(struct BProto_uint8_s))) { - return 0; - } - pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT16: { - if (!(left >= sizeof(struct BProto_uint16_s))) { - return 0; - } - pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - switch (id) { - case 1: - if (o->seed_id_start == o->buf_len) { - o->seed_id_start = entry_pos; - } - o->seed_id_span = pos - o->seed_id_start; - seed_id_count++; - break; - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT32: { - if (!(left >= sizeof(struct BProto_uint32_s))) { - return 0; - } - pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_UINT64: { - if (!(left >= sizeof(struct BProto_uint64_s))) { - return 0; - } - pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - - switch (id) { - default: - return 0; - } - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - if (!(left >= sizeof(struct BProto_data_header_s))) { - return 0; - } - struct BProto_data_header_s val; - memcpy(&val, o->buf + pos, sizeof(val)); - pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - if (!(left >= payload_len)) { - return 0; - } - pos += payload_len; - left -= payload_len; - - switch (id) { - default: - return 0; - } - } break; - default: - return 0; - } - } - - if (!(seed_id_count == 1)) { - return 0; - } - - return 1; -} - -int msg_confirmseedParser_GotEverything (msg_confirmseedParser *o) -{ - return ( - o->seed_id_pos == o->seed_id_span - ); -} - -int msg_confirmseedParser_Getseed_id (msg_confirmseedParser *o, uint16_t *v) -{ - ASSERT(o->seed_id_pos >= 0) - ASSERT(o->seed_id_pos <= o->seed_id_span) - - int left = o->seed_id_span - o->seed_id_pos; - - while (left > 0) { - ASSERT(left >= sizeof(struct BProto_header_s)) - struct BProto_header_s header; - memcpy(&header, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(header)); - o->seed_id_pos += sizeof(struct BProto_header_s); - left -= sizeof(struct BProto_header_s); - uint16_t type = ltoh16(header.type); - uint16_t id = ltoh16(header.id); - - switch (type) { - case BPROTO_TYPE_UINT8: { - ASSERT(left >= sizeof(struct BProto_uint8_s)) - o->seed_id_pos += sizeof(struct BProto_uint8_s); - left -= sizeof(struct BProto_uint8_s); - } break; - case BPROTO_TYPE_UINT16: { - ASSERT(left >= sizeof(struct BProto_uint16_s)) - struct BProto_uint16_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_uint16_s); - left -= sizeof(struct BProto_uint16_s); - - if (id == 1) { - *v = ltoh16(val.v); - return 1; - } - } break; - case BPROTO_TYPE_UINT32: { - ASSERT(left >= sizeof(struct BProto_uint32_s)) - o->seed_id_pos += sizeof(struct BProto_uint32_s); - left -= sizeof(struct BProto_uint32_s); - } break; - case BPROTO_TYPE_UINT64: { - ASSERT(left >= sizeof(struct BProto_uint64_s)) - o->seed_id_pos += sizeof(struct BProto_uint64_s); - left -= sizeof(struct BProto_uint64_s); - } break; - case BPROTO_TYPE_DATA: - case BPROTO_TYPE_CONSTDATA: - { - ASSERT(left >= sizeof(struct BProto_data_header_s)) - struct BProto_data_header_s val; - memcpy(&val, o->buf + o->seed_id_start + o->seed_id_pos, sizeof(val)); - o->seed_id_pos += sizeof(struct BProto_data_header_s); - left -= sizeof(struct BProto_data_header_s); - - uint32_t payload_len = ltoh32(val.len); - ASSERT(left >= payload_len) - o->seed_id_pos += payload_len; - left -= payload_len; - } break; - default: - ASSERT(0); - } - } - - return 0; -} - -void msg_confirmseedParser_Resetseed_id (msg_confirmseedParser *o) -{ - o->seed_id_pos = 0; -} - -void msg_confirmseedParser_Forwardseed_id (msg_confirmseedParser *o) -{ - o->seed_id_pos = o->seed_id_span; -} - diff --git a/v2rayng/badvpn/generated/flex_BPredicate.c b/v2rayng/badvpn/generated/flex_BPredicate.c deleted file mode 100644 index 95f4ff6866..0000000000 --- a/v2rayng/badvpn/generated/flex_BPredicate.c +++ /dev/null @@ -1,2143 +0,0 @@ -#line 2 "generated//flex_BPredicate.c" - -#line 4 "generated//flex_BPredicate.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if 1 - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void yypop_buffer_state (yyscan_t yyscanner ); - -static void yyensure_buffer_stack (yyscan_t yyscanner ); -static void yy_load_buffer_state (yyscan_t yyscanner ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap(yyscanner) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 13 -#define YY_END_OF_BUFFER 14 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[34] = - { 0, - 0, 0, 14, 12, 11, 11, 12, 1, 2, 3, - 9, 9, 9, 9, 9, 9, 11, 0, 10, 9, - 9, 9, 5, 9, 9, 4, 6, 9, 9, 9, - 7, 8, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 4, 1, 1, 1, 1, 1, 5, - 6, 1, 1, 7, 1, 1, 1, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, - 1, 1, 1, 1, 9, 8, 8, 10, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 11, 12, 8, - 8, 13, 8, 14, 8, 8, 8, 8, 8, 8, - 1, 1, 1, 1, 8, 1, 15, 8, 8, 8, - - 16, 17, 8, 8, 8, 8, 8, 18, 8, 8, - 8, 8, 8, 19, 20, 21, 22, 8, 8, 8, - 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[23] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2 - } ; - -static yyconst flex_int16_t yy_base[36] = - { 0, - 0, 0, 46, 47, 21, 23, 41, 47, 47, 47, - 0, 33, 31, 29, 26, 21, 25, 35, 47, 0, - 28, 23, 0, 18, 13, 0, 0, 14, 17, 16, - 0, 0, 47, 28, 29 - } ; - -static yyconst flex_int16_t yy_def[36] = - { 0, - 33, 1, 33, 33, 33, 33, 34, 33, 33, 33, - 35, 35, 35, 35, 35, 35, 33, 34, 33, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 0, 33, 33 - } ; - -static yyconst flex_int16_t yy_nxt[70] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 11, - 13, 14, 11, 11, 11, 11, 15, 11, 11, 11, - 16, 11, 17, 17, 17, 17, 17, 17, 18, 18, - 20, 32, 31, 30, 29, 28, 27, 26, 19, 25, - 24, 23, 22, 21, 19, 33, 3, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33 - } ; - -static yyconst flex_int16_t yy_chk[70] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 5, 5, 6, 6, 17, 17, 34, 34, - 35, 30, 29, 28, 25, 24, 22, 21, 18, 16, - 15, 14, 13, 12, 7, 3, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "predicate/BPredicate.l" -/** - * @file BPredicate.l - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @section DESCRIPTION - * - * {@link BPredicate} lexer file. - */ -#line 35 "predicate/BPredicate.l" - -#include -#include - -#include -#include - -#include - -#define YY_INPUT(buffer, res, max_size) \ - int bytes_read = LexMemoryBufferInput_Read((LexMemoryBufferInput *)yyget_extra(yyscanner), buffer, max_size); \ - res = (bytes_read == 0 ? YY_NULL : bytes_read); - -#define YY_NO_UNISTD_H 1 -#line 503 "generated//flex_BPredicate.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - yy_size_t yy_n_chars; - yy_size_t yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (yyscan_t yyscanner ); - -int yyget_debug (yyscan_t yyscanner ); - -void yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *yyget_in (yyscan_t yyscanner ); - -void yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *yyget_out (yyscan_t yyscanner ); - -void yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t yyget_leng (yyscan_t yyscanner ); - -char *yyget_text (yyscan_t yyscanner ); - -int yyget_lineno (yyscan_t yyscanner ); - -void yyset_lineno (int line_number ,yyscan_t yyscanner ); - -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - -YYSTYPE * yyget_lval (yyscan_t yyscanner ); - -void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *yyget_lloc (yyscan_t yyscanner ); - - void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (yyscan_t yyscanner ); -#else -extern int yywrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - - static void yy_push_state (int new_state ,yyscan_t yyscanner); - - static void yy_pop_state (yyscan_t yyscanner ); - - static int yy_top_state (yyscan_t yyscanner ); - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 52 "predicate/BPredicate.l" - -#line 756 "generated//flex_BPredicate.c" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 33 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 53 "predicate/BPredicate.l" -return SPAR; - YY_BREAK -case 2: -YY_RULE_SETUP -#line 54 "predicate/BPredicate.l" -return EPAR; - YY_BREAK -case 3: -YY_RULE_SETUP -#line 55 "predicate/BPredicate.l" -return COMMA; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 56 "predicate/BPredicate.l" -return AND; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 57 "predicate/BPredicate.l" -return OR; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 58 "predicate/BPredicate.l" -return NOT; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 59 "predicate/BPredicate.l" -return CONSTANT_TRUE; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 60 "predicate/BPredicate.l" -return CONSTANT_FALSE; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 61 "predicate/BPredicate.l" -{ - int l = strlen(yytext); - char *p = (char *)malloc(l + 1); - if (p) { - memcpy(p, yytext, l); - p[l] = '\0'; - } - yylval->text = p; - return NAME; - } - YY_BREAK -case 10: -/* rule 10 can match eol */ -YY_RULE_SETUP -#line 71 "predicate/BPredicate.l" -{ - int l = strlen(yytext); - char *p = (char *)malloc(l - 1); - if (p) { - memcpy(p, yytext + 1, l - 2); - p[l - 2] = '\0'; - } - yylval->text = p; - return STRING; - } - YY_BREAK -case 11: -/* rule 11 can match eol */ -YY_RULE_SETUP -#line 81 "predicate/BPredicate.l" -; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 82 "predicate/BPredicate.l" -LexMemoryBufferInput_SetError((LexMemoryBufferInput *)yyget_extra(yyscanner)); return 0; // remember failure and report EOF - YY_BREAK -case 13: -YY_RULE_SETUP -#line 83 "predicate/BPredicate.l" -ECHO; - YY_BREAK -#line 924 "generated//flex_BPredicate.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( yywrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 34 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 33); - - (void)yyg; - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register yy_size_t number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - yy_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void yy_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * @param yyscanner The scanner object. - */ - void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ,yyscanner ); - - yyfree((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(yyscanner); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void yypop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (yyscan_t yyscanner) -{ - yy_size_t num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - - static void yy_push_state (int new_state , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) - { - yy_size_t new_size; - - yyg->yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yyg->yy_start_stack_depth * sizeof( int ); - - if ( ! yyg->yy_start_stack ) - yyg->yy_start_stack = (int *) yyalloc(new_size ,yyscanner ); - - else - yyg->yy_start_stack = (int *) yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); - - if ( ! yyg->yy_start_stack ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); -} - - static void yy_pop_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( --yyg->yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); -} - - static int yy_top_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int yyget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int yyget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -yy_size_t yyget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *yyget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_column called with no buffer" ); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void yyset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int yyget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void yyset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * yyget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *yyget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* yylex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int yylex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* yylex_init_extra has the same functionality as yylex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to yyalloc in - * the yyextra field. - */ - -int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - yyset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - yyset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - yyfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - yyfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - yyfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 83 "predicate/BPredicate.l" - - - diff --git a/v2rayng/badvpn/generated/flex_BPredicate.h b/v2rayng/badvpn/generated/flex_BPredicate.h deleted file mode 100644 index f3d2428573..0000000000 --- a/v2rayng/badvpn/generated/flex_BPredicate.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef yyHEADER_H -#define yyHEADER_H 1 -#define yyIN_HEADER 1 - -#line 6 "generated//flex_BPredicate.h" - -#line 8 "generated//flex_BPredicate.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if 1 - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void yypop_buffer_state (yyscan_t yyscanner ); - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); - -void *yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void yyfree (void * ,yyscan_t yyscanner ); - -/* Begin user sect3 */ - -#define yywrap(yyscanner) 1 -#define YY_SKIP_YYWRAP - -#define yytext_ptr yytext_r - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (yyscan_t yyscanner ); - -int yyget_debug (yyscan_t yyscanner ); - -void yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *yyget_in (yyscan_t yyscanner ); - -void yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *yyget_out (yyscan_t yyscanner ); - -void yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -yy_size_t yyget_leng (yyscan_t yyscanner ); - -char *yyget_text (yyscan_t yyscanner ); - -int yyget_lineno (yyscan_t yyscanner ); - -void yyset_lineno (int line_number ,yyscan_t yyscanner ); - -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - -YYSTYPE * yyget_lval (yyscan_t yyscanner ); - -void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *yyget_lloc (yyscan_t yyscanner ); - - void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (yyscan_t yyscanner ); -#else -extern int yywrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 83 "predicate/BPredicate.l" - - -#line 349 "generated//flex_BPredicate.h" -#undef yyIN_HEADER -#endif /* yyHEADER_H */ diff --git a/v2rayng/badvpn/lemon/lemon.c b/v2rayng/badvpn/lemon/lemon.c deleted file mode 100644 index 8336e9a1ba..0000000000 --- a/v2rayng/badvpn/lemon/lemon.c +++ /dev/null @@ -1,4889 +0,0 @@ -/* -** This file contains all sources (including headers) to the LEMON -** LALR(1) parser generator. The sources have been combined into a -** single file to make it easy to include LEMON in the source tree -** and Makefile of another program. -** -** The author of this program disclaims copyright. -*/ -#include -#include -#include -#include -#include -#include - -#ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) -# define __WIN32__ -# endif -#endif - -#ifdef __WIN32__ -extern int access(); -#else -#include -#endif - -/* #define PRIVATE static */ -#define PRIVATE - -#ifdef TEST -#define MAXRHS 5 /* Set low to exercise exception code */ -#else -#define MAXRHS 1000 -#endif - -static char *msort(char*,char**,int(*)(const char*,const char*)); - -/* -** Compilers are getting increasingly pedantic about type conversions -** as C evolves ever closer to Ada.... To work around the latest problems -** we have to define the following variant of strlen(). -*/ -#define lemonStrlen(X) ((int)strlen(X)) - -static struct action *Action_new(void); -static struct action *Action_sort(struct action *); - -/********** From the file "build.h" ************************************/ -void FindRulePrecedences(); -void FindFirstSets(); -void FindStates(); -void FindLinks(); -void FindFollowSets(); -void FindActions(); - -/********* From the file "configlist.h" *********************************/ -void Configlist_init(/* void */); -struct config *Configlist_add(/* struct rule *, int */); -struct config *Configlist_addbasis(/* struct rule *, int */); -void Configlist_closure(/* void */); -void Configlist_sort(/* void */); -void Configlist_sortbasis(/* void */); -struct config *Configlist_return(/* void */); -struct config *Configlist_basis(/* void */); -void Configlist_eat(/* struct config * */); -void Configlist_reset(/* void */); - -/********* From the file "error.h" ***************************************/ -void ErrorMsg(const char *, int,const char *, ...); - -/****** From the file "option.h" ******************************************/ -struct s_options { - enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type; - char *label; - char *arg; - char *message; -}; -int OptInit(/* char**,struct s_options*,FILE* */); -int OptNArgs(/* void */); -char *OptArg(/* int */); -void OptErr(/* int */); -void OptPrint(/* void */); - -/******** From the file "parse.h" *****************************************/ -void Parse(/* struct lemon *lemp */); - -/********* From the file "plink.h" ***************************************/ -struct plink *Plink_new(/* void */); -void Plink_add(/* struct plink **, struct config * */); -void Plink_copy(/* struct plink **, struct plink * */); -void Plink_delete(/* struct plink * */); - -/********** From the file "report.h" *************************************/ -void Reprint(/* struct lemon * */); -void ReportOutput(/* struct lemon * */); -void ReportTable(/* struct lemon * */); -void ReportHeader(/* struct lemon * */); -void CompressTables(/* struct lemon * */); -void ResortStates(/* struct lemon * */); - -/********** From the file "set.h" ****************************************/ -void SetSize(/* int N */); /* All sets will be of size N */ -char *SetNew(/* void */); /* A new set for element 0..N */ -void SetFree(/* char* */); /* Deallocate a set */ - -int SetAdd(/* char*,int */); /* Add element to a set */ -int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ - -#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ - -/********** From the file "struct.h" *************************************/ -/* -** Principal data structures for the LEMON parser generator. -*/ - -typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean; - -/* Symbols (terminals and nonterminals) of the grammar are stored -** in the following: */ -struct symbol { - char *name; /* Name of the symbol */ - int index; /* Index number for this symbol */ - enum { - TERMINAL, - NONTERMINAL, - MULTITERMINAL - } type; /* Symbols are all either TERMINALS or NTs */ - struct rule *rule; /* Linked list of rules of this (if an NT) */ - struct symbol *fallback; /* fallback token in case this token doesn't parse */ - int prec; /* Precedence if defined (-1 otherwise) */ - enum e_assoc { - LEFT, - RIGHT, - NONE, - UNK - } assoc; /* Associativity if precedence is defined */ - char *firstset; /* First-set for all rules of this symbol */ - Boolean lambda; /* True if NT and can generate an empty string */ - int useCnt; /* Number of times used */ - char *destructor; /* Code which executes whenever this symbol is - ** popped from the stack during error processing */ - int destLineno; /* Line number for start of destructor */ - char *datatype; /* The data type of information held by this - ** object. Only used if type==NONTERMINAL */ - int dtnum; /* The data type number. In the parser, the value - ** stack is a union. The .yy%d element of this - ** union is the correct data type for this object */ - /* The following fields are used by MULTITERMINALs only */ - int nsubsym; /* Number of constituent symbols in the MULTI */ - struct symbol **subsym; /* Array of constituent symbols */ -}; - -/* Each production rule in the grammar is stored in the following -** structure. */ -struct rule { - struct symbol *lhs; /* Left-hand side of the rule */ - char *lhsalias; /* Alias for the LHS (NULL if none) */ - int lhsStart; /* True if left-hand side is the start symbol */ - int ruleline; /* Line number for the rule */ - int nrhs; /* Number of RHS symbols */ - struct symbol **rhs; /* The RHS symbols */ - char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ - int line; /* Line number at which code begins */ - char *code; /* The code executed when this rule is reduced */ - struct symbol *precsym; /* Precedence symbol for this rule */ - int index; /* An index number for this rule */ - Boolean canReduce; /* True if this rule is ever reduced */ - struct rule *nextlhs; /* Next rule with the same LHS */ - struct rule *next; /* Next rule in the global list */ -}; - -/* A configuration is a production rule of the grammar together with -** a mark (dot) showing how much of that rule has been processed so far. -** Configurations also contain a follow-set which is a list of terminal -** symbols which are allowed to immediately follow the end of the rule. -** Every configuration is recorded as an instance of the following: */ -struct config { - struct rule *rp; /* The rule upon which the configuration is based */ - int dot; /* The parse point */ - char *fws; /* Follow-set for this configuration only */ - struct plink *fplp; /* Follow-set forward propagation links */ - struct plink *bplp; /* Follow-set backwards propagation links */ - struct state *stp; /* Pointer to state which contains this */ - enum { - COMPLETE, /* The status is used during followset and */ - INCOMPLETE /* shift computations */ - } status; - struct config *next; /* Next configuration in the state */ - struct config *bp; /* The next basis configuration */ -}; - -/* Every shift or reduce operation is stored as one of the following */ -struct action { - struct symbol *sp; /* The look-ahead symbol */ - enum e_action { - SHIFT, - ACCEPT, - REDUCE, - ERROR, - SSCONFLICT, /* A shift/shift conflict */ - SRCONFLICT, /* Was a reduce, but part of a conflict */ - RRCONFLICT, /* Was a reduce, but part of a conflict */ - SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ - RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ - NOT_USED /* Deleted by compression */ - } type; - union { - struct state *stp; /* The new state, if a shift */ - struct rule *rp; /* The rule, if a reduce */ - } x; - struct action *next; /* Next action for this state */ - struct action *collide; /* Next action with the same hash */ -}; - -/* Each state of the generated parser's finite state machine -** is encoded as an instance of the following structure. */ -struct state { - struct config *bp; /* The basis configurations for this state */ - struct config *cfp; /* All configurations in this set */ - int statenum; /* Sequential number for this state */ - struct action *ap; /* Array of actions for this state */ - int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ - int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ - int iDflt; /* Default action */ -}; -#define NO_OFFSET (-2147483647) - -/* A followset propagation link indicates that the contents of one -** configuration followset should be propagated to another whenever -** the first changes. */ -struct plink { - struct config *cfp; /* The configuration to which linked */ - struct plink *next; /* The next propagate link */ -}; - -/* The state vector for the entire parser generator is recorded as -** follows. (LEMON uses no global variables and makes little use of -** static variables. Fields in the following structure can be thought -** of as begin global variables in the program.) */ -struct lemon { - struct state **sorted; /* Table of states sorted by state number */ - struct rule *rule; /* List of all rules */ - int nstate; /* Number of states */ - int nrule; /* Number of rules */ - int nsymbol; /* Number of terminal and nonterminal symbols */ - int nterminal; /* Number of terminal symbols */ - struct symbol **symbols; /* Sorted array of pointers to symbols */ - int errorcnt; /* Number of errors */ - struct symbol *errsym; /* The error symbol */ - struct symbol *wildcard; /* Token that matches anything */ - char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ - char *tokentype; /* Type of terminal symbols in the parser stack */ - char *vartype; /* The default type of non-terminal symbols */ - char *start; /* Name of the start symbol for the grammar */ - char *stacksize; /* Size of the parser stack */ - char *include; /* Code to put at the start of the C file */ - char *error; /* Code to execute when an error is seen */ - char *overflow; /* Code to execute on a stack overflow */ - char *failure; /* Code to execute on parser failure */ - char *accept; /* Code to execute when the parser excepts */ - char *extracode; /* Code appended to the generated file */ - char *tokendest; /* Code to execute to destroy token data */ - char *vardest; /* Code for the default non-terminal destructor */ - char *filename; /* Name of the input file */ - char *outname; /* Name of the current output file */ - char *tokenprefix; /* A prefix added to token names in the .h file */ - int nconflict; /* Number of parsing conflicts */ - int tablesize; /* Size of the parse tables */ - int basisflag; /* Print only basis configurations */ - int has_fallback; /* True if any %fallback is seen in the grammar */ - int nolinenosflag; /* True if #line statements should not be printed */ - char *argv0; /* Name of the program */ -}; - -#define MemoryCheck(X) if((X)==0){ \ - extern void memory_error(); \ - memory_error(); \ -} - -/**************** From the file "table.h" *********************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -/* Routines for handling a strings */ - -char *Strsafe(); - -void Strsafe_init(/* void */); -int Strsafe_insert(/* char * */); -char *Strsafe_find(/* char * */); - -/* Routines for handling symbols of the grammar */ - -struct symbol *Symbol_new(); -int Symbolcmpp(/* struct symbol **, struct symbol ** */); -void Symbol_init(/* void */); -int Symbol_insert(/* struct symbol *, char * */); -struct symbol *Symbol_find(/* char * */); -struct symbol *Symbol_Nth(/* int */); -int Symbol_count(/* */); -struct symbol **Symbol_arrayof(/* */); - -/* Routines to manage the state table */ - -int Configcmp(/* struct config *, struct config * */); -struct state *State_new(); -void State_init(/* void */); -int State_insert(/* struct state *, struct config * */); -struct state *State_find(/* struct config * */); -struct state **State_arrayof(/* */); - -/* Routines used for efficiency in Configlist_add */ - -void Configtable_init(/* void */); -int Configtable_insert(/* struct config * */); -struct config *Configtable_find(/* struct config * */); -void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -static struct action *Action_new(void){ - static struct action *freelist = 0; - struct action *new; - - if( freelist==0 ){ - int i; - int amt = 100; - freelist = (struct action *)calloc(amt, sizeof(struct action)); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Compare two actions for sorting purposes. Return negative, zero, or -** positive if the first action is less than, equal to, or greater than -** the first -*/ -static int actioncmp( - struct action *ap1, - struct action *ap2 -){ - int rc; - rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ){ - rc = (int)ap1->type - (int)ap2->type; - } - if( rc==0 && ap1->type==REDUCE ){ - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -static struct action *Action_sort( - struct action *ap -){ - ap = (struct action *)msort((char *)ap,(char **)&ap->next, - (int(*)(const char*,const char*))actioncmp); - return ap; -} - -void Action_add(app,type,sp,arg) -struct action **app; -enum e_action type; -struct symbol *sp; -char *arg; -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if( type==SHIFT ){ - new->x.stp = (struct state *)arg; - }else{ - new->x.rp = (struct rule *)arg; - } -} -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ - acttab *p = calloc( 1, sizeof(*p) ); - if( p==0 ){ - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action){ - if( p->nLookahead>=p->nLookaheadAlloc ){ - p->nLookaheadAlloc += 25; - p->aLookahead = realloc( p->aLookahead, - sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if( p->aLookahead==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if( p->nLookahead==0 ){ - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - }else{ - if( p->mxLookaheadmxLookahead = lookahead; - if( p->mnLookahead>lookahead ){ - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p){ - int i, j, k, n; - assert( p->nLookahead>0 ); - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if( p->nAction + n >= p->nActionAlloc ){ - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc( p->aAction, - sizeof(p->aAction[0])*p->nActionAlloc); - if( p->aAction==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; inActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; inAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( jnLookahead ) continue; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ - if( p->aAction[i].action!=p->mnAction ) continue; - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 || k>=p->nAction ) break; - if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; - if( p->aLookahead[j].action!=p->aAction[k].action ) break; - } - if( jnLookahead ) continue; - n = 0; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead<0 ) continue; - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; - } - if( n==p->nLookahead ){ - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if( k>=p->nAction ) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - -/********************** From the file "build.c" *****************************/ -/* -** Routines to construction the finite state machine for the LEMON -** parser generator. -*/ - -/* Find a precedence symbol of every rule in the grammar. -** -** Those rules which have a precedence symbol coded in the input -** grammar using the "[symbol]" construct will already have the -** rp->precsym field filled. Other rules take as their precedence -** symbol the first RHS symbol with a defined precedence. If there -** are not RHS symbols with a defined precedence, the precedence -** symbol field is left blank. -*/ -void FindRulePrecedences(xp) -struct lemon *xp; -{ - struct rule *rp; - for(rp=xp->rule; rp; rp=rp->next){ - if( rp->precsym==0 ){ - int i, j; - for(i=0; inrhs && rp->precsym==0; i++){ - struct symbol *sp = rp->rhs[i]; - if( sp->type==MULTITERMINAL ){ - for(j=0; jnsubsym; j++){ - if( sp->subsym[j]->prec>=0 ){ - rp->precsym = sp->subsym[j]; - break; - } - } - }else if( sp->prec>=0 ){ - rp->precsym = rp->rhs[i]; - } - } - } - } - return; -} - -/* Find all nonterminals which will generate the empty string. -** Then go back and compute the first sets of every nonterminal. -** The first set is the set of all terminal symbols which can begin -** a string generated by that nonterminal. -*/ -void FindFirstSets(lemp) -struct lemon *lemp; -{ - int i, j; - struct rule *rp; - int progress; - - for(i=0; insymbol; i++){ - lemp->symbols[i]->lambda = LEMON_FALSE; - } - for(i=lemp->nterminal; insymbol; i++){ - lemp->symbols[i]->firstset = SetNew(); - } - - /* First compute all lambdas */ - do{ - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->lhs->lambda ) continue; - for(i=0; inrhs; i++){ - struct symbol *sp = rp->rhs[i]; - if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; - } - if( i==rp->nrhs ){ - rp->lhs->lambda = LEMON_TRUE; - progress = 1; - } - } - }while( progress ); - - /* Now compute all first sets */ - do{ - struct symbol *s1, *s2; - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - s1 = rp->lhs; - for(i=0; inrhs; i++){ - s2 = rp->rhs[i]; - if( s2->type==TERMINAL ){ - progress += SetAdd(s1->firstset,s2->index); - break; - }else if( s2->type==MULTITERMINAL ){ - for(j=0; jnsubsym; j++){ - progress += SetAdd(s1->firstset,s2->subsym[j]->index); - } - break; - }else if( s1==s2 ){ - if( s1->lambda==LEMON_FALSE ) break; - }else{ - progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==LEMON_FALSE ) break; - } - } - } - }while( progress ); - return; -} - -/* Compute all LR(0) states for the grammar. Links -** are added to between some states so that the LR(1) follow sets -** can be computed later. -*/ -PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */ -void FindStates(lemp) -struct lemon *lemp; -{ - struct symbol *sp; - struct rule *rp; - - Configlist_init(); - - /* Find the start symbol */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ){ - ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); - lemp->errorcnt++; - sp = lemp->rule->lhs; - } - }else{ - sp = lemp->rule->lhs; - } - - /* Make sure the start symbol doesn't occur on the right-hand side of - ** any rule. Report an error if it does. (YACC would generate a new - ** start symbol in this case.) */ - for(rp=lemp->rule; rp; rp=rp->next){ - int i; - for(i=0; inrhs; i++){ - if( rp->rhs[i]==sp ){ /* FIX ME: Deal with multiterminals */ - ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); - lemp->errorcnt++; - } - } - } - - /* The basis configuration set for the first state - ** is all rules which have the start symbol as their - ** left-hand side */ - for(rp=sp->rule; rp; rp=rp->nextlhs){ - struct config *newcfp; - rp->lhsStart = 1; - newcfp = Configlist_addbasis(rp,0); - SetAdd(newcfp->fws,0); - } - - /* Compute the first state. All other states will be - ** computed automatically during the computation of the first one. - ** The returned pointer to the first state is not used. */ - (void)getstate(lemp); - return; -} - -/* Return a pointer to a state which is described by the configuration -** list which has been built from calls to Configlist_add. -*/ -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */ -PRIVATE struct state *getstate(lemp) -struct lemon *lemp; -{ - struct config *cfp, *bp; - struct state *stp; - - /* Extract the sorted basis of the new state. The basis was constructed - ** by prior calls to "Configlist_addbasis()". */ - Configlist_sortbasis(); - bp = Configlist_basis(); - - /* Get a state with the same basis */ - stp = State_find(bp); - if( stp ){ - /* A state with the same basis already exists! Copy all the follow-set - ** propagation links from the state under construction into the - ** preexisting state, then return a pointer to the preexisting state */ - struct config *x, *y; - for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ - Plink_copy(&y->bplp,x->bplp); - Plink_delete(x->fplp); - x->fplp = x->bplp = 0; - } - cfp = Configlist_return(); - Configlist_eat(cfp); - }else{ - /* This really is a new state. Construct all the details */ - Configlist_closure(lemp); /* Compute the configuration closure */ - Configlist_sort(); /* Sort the configuration closure */ - cfp = Configlist_return(); /* Get a pointer to the config list */ - stp = State_new(); /* A new state structure */ - MemoryCheck(stp); - stp->bp = bp; /* Remember the configuration basis */ - stp->cfp = cfp; /* Remember the configuration closure */ - stp->statenum = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ - State_insert(stp,stp->bp); /* Add to the state table */ - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; -} - -/* -** Return true if two symbols are the same. -*/ -int same_symbol(a,b) -struct symbol *a; -struct symbol *b; -{ - int i; - if( a==b ) return 1; - if( a->type!=MULTITERMINAL ) return 0; - if( b->type!=MULTITERMINAL ) return 0; - if( a->nsubsym!=b->nsubsym ) return 0; - for(i=0; insubsym; i++){ - if( a->subsym[i]!=b->subsym[i] ) return 0; - } - return 1; -} - -/* Construct all successor states to the given state. A "successor" -** state is any state which can be reached by a shift action. -*/ -PRIVATE void buildshifts(lemp,stp) -struct lemon *lemp; -struct state *stp; /* The state from which successors are computed */ -{ - struct config *cfp; /* For looping thru the config closure of "stp" */ - struct config *bcfp; /* For the inner loop on config closure of "stp" */ - struct config *new; /* */ - struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ - struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ - struct state *newstp; /* A pointer to a successor state */ - - /* Each configuration becomes complete after it contibutes to a successor - ** state. Initially, all configurations are incomplete */ - for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; - - /* Loop through all configurations of the state "stp" */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ - if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ - Configlist_reset(); /* Reset the new config set */ - sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ - - /* For every configuration in the state "stp" which has the symbol "sp" - ** following its dot, add the same configuration to the basis set under - ** construction but with the dot shifted one symbol to the right. */ - for(bcfp=cfp; bcfp; bcfp=bcfp->next){ - if( bcfp->status==COMPLETE ) continue; /* Already used */ - if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ - bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( !same_symbol(bsp,sp) ) continue; /* Must be same as for "cfp" */ - bcfp->status = COMPLETE; /* Mark this config as used */ - new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); - Plink_add(&new->bplp,bcfp); - } - - /* Get a pointer to the state described by the basis configuration set - ** constructed in the preceding loop */ - newstp = getstate(lemp); - - /* The state "newstp" is reached from the state "stp" by a shift action - ** on the symbol "sp" */ - if( sp->type==MULTITERMINAL ){ - int i; - for(i=0; insubsym; i++){ - Action_add(&stp->ap,SHIFT,sp->subsym[i],(char*)newstp); - } - }else{ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); - } - } -} - -/* -** Construct the propagation links -*/ -void FindLinks(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp, *other; - struct state *stp; - struct plink *plp; - - /* Housekeeping detail: - ** Add to every propagate link a pointer back to the state to - ** which the link is attached. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } - } - - /* Convert all backlinks into forward links. Only the forward - ** links are used in the follow-set computation. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } - } - } -} - -/* Compute all followsets. -** -** A followset is the set of all symbols which can come immediately -** after a configuration. -*/ -void FindFollowSets(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp; - struct plink *plp; - int progress; - int change; - - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } - } - - do{ - progress = 0; - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } - } - cfp->status = COMPLETE; - } - } - }while( progress ); -} - -static int resolve_conflict(); - -/* Compute the reduce actions, and resolve conflicts. -*/ -void FindActions(lemp) -struct lemon *lemp; -{ - int i,j; - struct config *cfp; - struct state *stp; - struct symbol *sp; - struct rule *rp; - - /* Add all of the reduce actions - ** A reduce action is added for each element of the followset of - ** a configuration which has its dot at the extreme right. - */ - for(i=0; instate; i++){ /* Loop over all states */ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; jnterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } - } - } - } - } - - /* Add the accepting token */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; - }else{ - sp = lemp->rule->lhs; - } - /* Add to the first state (which is always the starting state of the - ** finite state machine) an action to ACCEPT if the lookahead is the - ** start nonterminal. */ - Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); - - /* Resolve conflicts */ - for(i=0; instate; i++){ - struct action *ap, *nap; - struct state *stp; - stp = lemp->sorted[i]; - /* assert( stp->ap ); */ - stp->ap = Action_sort(stp->ap); - for(ap=stp->ap; ap && ap->next; ap=ap->next){ - for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ - /* The two actions "ap" and "nap" have the same lookahead. - ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); - } - } - } - - /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE; - for(i=0; instate; i++){ - struct action *ap; - for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE; - } - } - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->canReduce ) continue; - ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); - lemp->errorcnt++; - } -} - -/* Resolve a conflict between the two given actions. If the -** conflict can't be resolved, return non-zero. -** -** NO LONGER TRUE: -** To resolve a conflict, first look to see if either action -** is on an error rule. In that case, take the action which -** is not associated with the error rule. If neither or both -** actions are associated with an error rule, then try to -** use precedence to resolve the conflict. -** -** If either action is a SHIFT, then it must be apx. This -** function won't work if apx->type==REDUCE and apy->type==SHIFT. -*/ -static int resolve_conflict(apx,apy,errsym) -struct action *apx; -struct action *apy; -struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ -{ - struct symbol *spx, *spy; - int errcnt = 0; - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==SHIFT ){ - apy->type = SSCONFLICT; - errcnt++; - } - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; - spy = apy->x.rp->precsym; - if( spy==0 || spx->prec<0 || spy->prec<0 ){ - /* Not enough precedence information. */ - apy->type = SRCONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = SH_RESOLVED; - }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ - apy->type = RD_RESOLVED; /* associativity */ - }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ - apx->type = SH_RESOLVED; - }else{ - assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = SRCONFLICT; - errcnt++; - } - }else if( apx->type==REDUCE && apy->type==REDUCE ){ - spx = apx->x.rp->precsym; - spy = apy->x.rp->precsym; - if( spx==0 || spy==0 || spx->prec<0 || - spy->prec<0 || spx->prec==spy->prec ){ - apy->type = RRCONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = RD_RESOLVED; - } - }else{ - assert( - apx->type==SH_RESOLVED || - apx->type==RD_RESOLVED || - apx->type==SSCONFLICT || - apx->type==SRCONFLICT || - apx->type==RRCONFLICT || - apy->type==SH_RESOLVED || - apy->type==RD_RESOLVED || - apy->type==SSCONFLICT || - apy->type==SRCONFLICT || - apy->type==RRCONFLICT - ); - /* The REDUCE/SHIFT case cannot happen because SHIFTs come before - ** REDUCEs on the list. If we reach this point it must be because - ** the parser conflict had already been resolved. */ - } - return errcnt; -} -/********************* From the file "configlist.c" *************************/ -/* -** Routines to processing a configuration list and building a state -** in the LEMON parser generator. -*/ - -static struct config *freelist = 0; /* List of free configurations */ -static struct config *current = 0; /* Top of list of configurations */ -static struct config **currentend = 0; /* Last on list of configs */ -static struct config *basis = 0; /* Top of list of basis configs */ -static struct config **basisend = 0; /* End of list of basis configs */ - -/* Return a pointer to a new configuration */ -PRIVATE struct config *newconfig(){ - struct config *new; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)calloc( amt, sizeof(struct config) ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* The configuration "old" is no longer used */ -PRIVATE void deleteconfig(old) -struct config *old; -{ - old->next = freelist; - freelist = old; -} - -/* Initialized the configuration list builder */ -void Configlist_init(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_init(); - return; -} - -/* Initialized the configuration list builder */ -void Configlist_reset(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_clear(0); - return; -} - -/* Add another configuration to the configuration list */ -struct config *Configlist_add(rp,dot) -struct rule *rp; /* The rule */ -int dot; /* Index into the RHS of the rule where the dot goes */ -{ - struct config *cfp, model; - - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - Configtable_insert(cfp); - } - return cfp; -} - -/* Add a basis configuration to the configuration list */ -struct config *Configlist_addbasis(rp,dot) -struct rule *rp; -int dot; -{ - struct config *cfp, model; - - assert( basisend!=0 ); - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - *basisend = cfp; - basisend = &cfp->bp; - Configtable_insert(cfp); - } - return cfp; -} - -/* Compute the closure of the configuration list */ -void Configlist_closure(lemp) -struct lemon *lemp; -{ - struct config *cfp, *newcfp; - struct rule *rp, *newrp; - struct symbol *sp, *xsp; - int i, dot; - - assert( currentend!=0 ); - for(cfp=current; cfp; cfp=cfp->next){ - rp = cfp->rp; - dot = cfp->dot; - if( dot>=rp->nrhs ) continue; - sp = rp->rhs[dot]; - if( sp->type==NONTERMINAL ){ - if( sp->rule==0 && sp!=lemp->errsym ){ - ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", - sp->name); - lemp->errorcnt++; - } - for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ - newcfp = Configlist_add(newrp,0); - for(i=dot+1; inrhs; i++){ - xsp = rp->rhs[i]; - if( xsp->type==TERMINAL ){ - SetAdd(newcfp->fws,xsp->index); - break; - }else if( xsp->type==MULTITERMINAL ){ - int k; - for(k=0; knsubsym; k++){ - SetAdd(newcfp->fws, xsp->subsym[k]->index); - } - break; - }else{ - SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==LEMON_FALSE ) break; - } - } - if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); - } - } - } - return; -} - -/* Sort the configuration list */ -void Configlist_sort(){ - current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); - currentend = 0; - return; -} - -/* Sort the basis configuration list */ -void Configlist_sortbasis(){ - basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); - basisend = 0; - return; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_return(){ - struct config *old; - old = current; - current = 0; - currentend = 0; - return old; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_basis(){ - struct config *old; - old = basis; - basis = 0; - basisend = 0; - return old; -} - -/* Free all elements of the given configuration list */ -void Configlist_eat(cfp) -struct config *cfp; -{ - struct config *nextcfp; - for(; cfp; cfp=nextcfp){ - nextcfp = cfp->next; - assert( cfp->fplp==0 ); - assert( cfp->bplp==0 ); - if( cfp->fws ) SetFree(cfp->fws); - deleteconfig(cfp); - } - return; -} -/***************** From the file "error.c" *********************************/ -/* -** Code for printing error message. -*/ - -/* Find a good place to break "msg" so that its length is at least "min" -** but no more than "max". Make the point as close to max as possible. -*/ -static int findbreak(msg,min,max) -char *msg; -int min; -int max; -{ - int i,spot; - char c; - for(i=spot=min; i<=max; i++){ - c = msg[i]; - if( c=='\t' ) msg[i] = ' '; - if( c=='\n' ){ msg[i] = ' '; spot = i; break; } - if( c==0 ){ spot = i; break; } - if( c=='-' && i0 ){ - sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno); - }else{ - sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename); - } - prefixsize = lemonStrlen(prefix); - availablewidth = LINEWIDTH - prefixsize; - - /* Generate the error message */ - vsprintf(errmsg,format,ap); - va_end(ap); - errmsgsize = lemonStrlen(errmsg); - /* Remove trailing '\n's from the error message. */ - while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){ - errmsg[--errmsgsize] = 0; - } - - /* Print the error message */ - base = 0; - while( errmsg[base]!=0 ){ - end = restart = findbreak(&errmsg[base],0,availablewidth); - restart += base; - while( errmsg[restart]==' ' ) restart++; - fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]); - base = restart; - } -} -/**************** From the file "main.c" ************************************/ -/* -** Main program file for the LEMON parser generator. -*/ - -/* Report an out-of-memory condition and abort. This function -** is used mostly by the "MemoryCheck" macro in struct.h -*/ -void memory_error(){ - fprintf(stderr,"Out of memory. Aborting...\n"); - exit(1); -} - -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ - -/* This routine is called with the argument to each -D command-line option. -** Add the macro defined to the azDefine array. -*/ -static void handle_D_option(char *z){ - char **paz; - nDefine++; - azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine); - if( azDefine==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - paz = &azDefine[nDefine-1]; - *paz = malloc( lemonStrlen(z)+1 ); - if( *paz==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - strcpy(*paz, z); - for(z=*paz; *z && *z!='='; z++){} - *z = 0; -} - - -/* The main program. Parse the command line and do it... */ -int main(argc,argv) -int argc; -char **argv; -{ - static int version = 0; - static int rpflag = 0; - static int basisflag = 0; - static int compress = 0; - static int quiet = 0; - static int statistics = 0; - static int mhflag = 0; - static int nolinenosflag = 0; - static struct s_options options[] = { - {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, - {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, - {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, - {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, - {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file."}, - {OPT_FLAG, "l", (char*)&nolinenosflag, "Do not print #line statements."}, - {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, - {OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output."}, - {OPT_FLAG, "x", (char*)&version, "Print the version number."}, - {OPT_FLAG,0,0,0} - }; - int i; - struct lemon lem; - - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); - exit(0); - } - if( OptNArgs()!=1 ){ - fprintf(stderr,"Exactly one filename argument is required.\n"); - exit(1); - } - memset(&lem, 0, sizeof(lem)); - lem.errorcnt = 0; - - /* Initialize the machine */ - Strsafe_init(); - Symbol_init(); - State_init(); - lem.argv0 = argv[0]; - lem.filename = OptArg(0); - lem.basisflag = basisflag; - lem.nolinenosflag = nolinenosflag; - Symbol_new("$"); - lem.errsym = Symbol_new("error"); - lem.errsym->useCnt = 0; - - /* Parse the input file */ - Parse(&lem); - if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.nrule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); - } - - /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); - Symbol_new("{default}"); - lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), - (int(*)())Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); - lem.nterminal = i; - - /* Generate a reprint of the grammar, if requested on the command line */ - if( rpflag ){ - Reprint(&lem); - }else{ - /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal+1); - - /* Find the precedence for every production rule (that has one) */ - FindRulePrecedences(&lem); - - /* Compute the lambda-nonterminals and the first-sets for every - ** nonterminal */ - FindFirstSets(&lem); - - /* Compute all LR(0) states. Also record follow-set propagation - ** links so that the follow-set can be computed later */ - lem.nstate = 0; - FindStates(&lem); - lem.sorted = State_arrayof(); - - /* Tie up loose ends on the propagation links */ - FindLinks(&lem); - - /* Compute the follow set of every reducible configuration */ - FindFollowSets(&lem); - - /* Compute the action tables */ - FindActions(&lem); - - /* Compress the action tables */ - if( compress==0 ) CompressTables(&lem); - - /* Reorder and renumber the states so that states with fewer choices - ** occur at the end. */ - ResortStates(&lem); - - /* Generate a report of the parser generated. (the "y.output" file) */ - if( !quiet ) ReportOutput(&lem); - - /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); - - /* Produce a header file for use by the scanner. (This step is - ** omitted if the "-m" option is used because makeheaders will - ** generate the file for us.) */ - if( !mhflag ) ReportHeader(&lem); - } - if( statistics ){ - printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", - lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); - printf(" %d states, %d parser table entries, %d conflicts\n", - lem.nstate, lem.tablesize, lem.nconflict); - } - if( lem.nconflict ){ - fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); - } - exit(lem.errorcnt + lem.nconflict); - return (lem.errorcnt + lem.nconflict); -} -/******************** From the file "msort.c" *******************************/ -/* -** A generic merge-sort program. -** -** USAGE: -** Let "ptr" be a pointer to some structure which is at the head of -** a null-terminated list. Then to sort the list call: -** -** ptr = msort(ptr,&(ptr->next),cmpfnc); -** -** In the above, "cmpfnc" is a pointer to a function which compares -** two instances of the structure and returns an integer, as in -** strcmp. The second argument is a pointer to the pointer to the -** second element of the linked list. This address is used to compute -** the offset to the "next" field within the structure. The offset to -** the "next" field must be constant for all structures in the list. -** -** The function returns a new pointer which is the head of the list -** after sorting. -** -** ALGORITHM: -** Merge-sort. -*/ - -/* -** Return a pointer to the next structure in the linked list. -*/ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) - -/* -** Inputs: -** a: A sorted, null-terminated linked list. (May be null). -** b: A sorted, null-terminated linked list. (May be null). -** cmp: A pointer to the comparison function. -** offset: Offset in the structure to the "next" field. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** of both a and b. -** -** Side effects: -** The "next" pointers for elements in the lists a and b are -** changed. -*/ -static char *merge( - char *a, - char *b, - int (*cmp)(const char*,const char*), - int offset -){ - char *ptr, *head; - - if( a==0 ){ - head = b; - }else if( b==0 ){ - head = a; - }else{ - if( (*cmp)(a,b)<0 ){ - ptr = a; - a = NEXT(a); - }else{ - ptr = b; - b = NEXT(b); - } - head = ptr; - while( a && b ){ - if( (*cmp)(a,b)<0 ){ - NEXT(ptr) = a; - ptr = a; - a = NEXT(a); - }else{ - NEXT(ptr) = b; - ptr = b; - b = NEXT(b); - } - } - if( a ) NEXT(ptr) = a; - else NEXT(ptr) = b; - } - return head; -} - -/* -** Inputs: -** list: Pointer to a singly-linked list of structures. -** next: Pointer to pointer to the second element of the list. -** cmp: A comparison function. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** orginally in list. -** -** Side effects: -** The "next" pointers for elements in list are changed. -*/ -#define LISTSIZE 30 -static char *msort( - char *list, - char **next, - int (*cmp)(const char*,const char*) -){ - unsigned long offset; - char *ep; - char *set[LISTSIZE]; - int i; - offset = (unsigned long)next - (unsigned long)list; - for(i=0; istate = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ - psp->lhs = Symbol_new(x); - psp->nrhs = 0; - psp->lhsalias = 0; - psp->state = WAITING_FOR_ARROW; - }else if( x[0]=='{' ){ - if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"There is no prior rule opon which to attach the code \ -fragment which begins on this line."); - psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->line = psp->tokenlineno; - psp->prevrule->code = &x[1]; - } - }else if( x[0]=='[' ){ - psp->state = PRECEDENCE_MARK_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Token \"%s\" should be either \"%%\" or a nonterminal name.", - x); - psp->errorcnt++; - } - break; - case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The precedence symbol must be a terminal."); - psp->errorcnt++; - }else if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "There is no prior rule to assign precedence \"[%s]\".",x); - psp->errorcnt++; - }else if( psp->prevrule->precsym!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->precsym = Symbol_new(x); - } - psp->state = PRECEDENCE_MARK_2; - break; - case PRECEDENCE_MARK_2: - if( x[0]!=']' ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"]\" on precedence mark."); - psp->errorcnt++; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - break; - case WAITING_FOR_ARROW: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else if( x[0]=='(' ){ - psp->state = LHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Expected to see a \":\" following the LHS symbol \"%s\".", - psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->lhsalias = x; - psp->state = LHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the LHS \"%s\"\n", - x,psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = LHS_ALIAS_3; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_3: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"->\" following: \"%s(%s)\".", - psp->lhs->name,psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case IN_RHS: - if( x[0]=='.' ){ - struct rule *rp; - rp = (struct rule *)calloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); - if( rp==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't allocate enough memory for this rule."); - psp->errorcnt++; - psp->prevrule = 0; - }else{ - int i; - rp->ruleline = psp->tokenlineno; - rp->rhs = (struct symbol**)&rp[1]; - rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]); - for(i=0; inrhs; i++){ - rp->rhs[i] = psp->rhs[i]; - rp->rhsalias[i] = psp->alias[i]; - } - rp->lhs = psp->lhs; - rp->lhsalias = psp->lhsalias; - rp->nrhs = psp->nrhs; - rp->code = 0; - rp->precsym = 0; - rp->index = psp->gp->nrule++; - rp->nextlhs = rp->lhs->rule; - rp->lhs->rule = rp; - rp->next = 0; - if( psp->firstrule==0 ){ - psp->firstrule = psp->lastrule = rp; - }else{ - psp->lastrule->next = rp; - psp->lastrule = rp; - } - psp->prevrule = rp; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ - if( psp->nrhs>=MAXRHS ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbols on RHS of rule beginning at \"%s\".", - x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - }else{ - psp->rhs[psp->nrhs] = Symbol_new(x); - psp->alias[psp->nrhs] = 0; - psp->nrhs++; - } - }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ - struct symbol *msp = psp->rhs[psp->nrhs-1]; - if( msp->type!=MULTITERMINAL ){ - struct symbol *origsp = msp; - msp = calloc(1,sizeof(*msp)); - memset(msp, 0, sizeof(*msp)); - msp->type = MULTITERMINAL; - msp->nsubsym = 1; - msp->subsym = calloc(1,sizeof(struct symbol*)); - msp->subsym[0] = origsp; - msp->name = origsp->name; - psp->rhs[psp->nrhs-1] = msp; - } - msp->nsubsym++; - msp->subsym = realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); - msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); - if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Cannot form a compound containing a non-terminal"); - psp->errorcnt++; - } - }else if( x[0]=='(' && psp->nrhs>0 ){ - psp->state = RHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal character on RHS of rule: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->alias[psp->nrhs-1] = x; - psp->state = RHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", - x,psp->rhs[psp->nrhs-1]->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ - psp->declkeyword = x; - psp->declargslot = 0; - psp->decllinenoslot = 0; - psp->insertLineMacro = 1; - psp->state = WAITING_FOR_DECL_ARG; - if( strcmp(x,"name")==0 ){ - psp->declargslot = &(psp->gp->name); - psp->insertLineMacro = 0; - }else if( strcmp(x,"include")==0 ){ - psp->declargslot = &(psp->gp->include); - }else if( strcmp(x,"code")==0 ){ - psp->declargslot = &(psp->gp->extracode); - }else if( strcmp(x,"token_destructor")==0 ){ - psp->declargslot = &psp->gp->tokendest; - }else if( strcmp(x,"default_destructor")==0 ){ - psp->declargslot = &psp->gp->vardest; - }else if( strcmp(x,"token_prefix")==0 ){ - psp->declargslot = &psp->gp->tokenprefix; - psp->insertLineMacro = 0; - }else if( strcmp(x,"syntax_error")==0 ){ - psp->declargslot = &(psp->gp->error); - }else if( strcmp(x,"parse_accept")==0 ){ - psp->declargslot = &(psp->gp->accept); - }else if( strcmp(x,"parse_failure")==0 ){ - psp->declargslot = &(psp->gp->failure); - }else if( strcmp(x,"stack_overflow")==0 ){ - psp->declargslot = &(psp->gp->overflow); - }else if( strcmp(x,"extra_argument")==0 ){ - psp->declargslot = &(psp->gp->arg); - psp->insertLineMacro = 0; - }else if( strcmp(x,"token_type")==0 ){ - psp->declargslot = &(psp->gp->tokentype); - psp->insertLineMacro = 0; - }else if( strcmp(x,"default_type")==0 ){ - psp->declargslot = &(psp->gp->vartype); - psp->insertLineMacro = 0; - }else if( strcmp(x,"stack_size")==0 ){ - psp->declargslot = &(psp->gp->stacksize); - psp->insertLineMacro = 0; - }else if( strcmp(x,"start_symbol")==0 ){ - psp->declargslot = &(psp->gp->start); - psp->insertLineMacro = 0; - }else if( strcmp(x,"left")==0 ){ - psp->preccounter++; - psp->declassoc = LEFT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"right")==0 ){ - psp->preccounter++; - psp->declassoc = RIGHT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"nonassoc")==0 ){ - psp->preccounter++; - psp->declassoc = NONE; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"destructor")==0 ){ - psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; - }else if( strcmp(x,"type")==0 ){ - psp->state = WAITING_FOR_DATATYPE_SYMBOL; - }else if( strcmp(x,"fallback")==0 ){ - psp->fallback = 0; - psp->state = WAITING_FOR_FALLBACK_ID; - }else if( strcmp(x,"wildcard")==0 ){ - psp->state = WAITING_FOR_WILDCARD_ID; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Unknown declaration keyword: \"%%%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal declaration keyword: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->destructor; - psp->decllinenoslot = &sp->destLineno; - psp->insertLineMacro = 1; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->datatype; - psp->insertLineMacro = 0; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_PRECEDENCE_SYMBOL: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ - struct symbol *sp; - sp = Symbol_new(x); - if( sp->prec>=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol \"%s\" has already be given a precedence.",x); - psp->errorcnt++; - }else{ - sp->prec = psp->preccounter; - sp->assoc = psp->declassoc; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't assign a precedence to \"%s\".",x); - psp->errorcnt++; - } - break; - case WAITING_FOR_DECL_ARG: - if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ - char *zOld, *zNew, *zBuf, *z; - int nOld, n, nLine, nNew, nBack; - int addLineMacro; - char zLine[50]; - zNew = x; - if( zNew[0]=='"' || zNew[0]=='{' ) zNew++; - nNew = lemonStrlen(zNew); - if( *psp->declargslot ){ - zOld = *psp->declargslot; - }else{ - zOld = ""; - } - nOld = lemonStrlen(zOld); - n = nOld + nNew + 20; - addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro && - (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0); - if( addLineMacro ){ - for(z=psp->filename, nBack=0; *z; z++){ - if( *z=='\\' ) nBack++; - } - sprintf(zLine, "#line %d ", psp->tokenlineno); - nLine = lemonStrlen(zLine); - n += nLine + lemonStrlen(psp->filename) + nBack; - } - *psp->declargslot = zBuf = realloc(*psp->declargslot, n); - zBuf += nOld; - if( addLineMacro ){ - if( nOld && zBuf[-1]!='\n' ){ - *(zBuf++) = '\n'; - } - memcpy(zBuf, zLine, nLine); - zBuf += nLine; - *(zBuf++) = '"'; - for(z=psp->filename; *z; z++){ - if( *z=='\\' ){ - *(zBuf++) = '\\'; - } - *(zBuf++) = *z; - } - *(zBuf++) = '"'; - *(zBuf++) = '\n'; - } - if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){ - psp->decllinenoslot[0] = psp->tokenlineno; - } - memcpy(zBuf, zNew, nNew); - zBuf += nNew; - *zBuf = 0; - psp->state = WAITING_FOR_DECL_OR_RULE; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal argument to %%%s: %s",psp->declkeyword,x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_FALLBACK_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%fallback argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->fallback==0 ){ - psp->fallback = sp; - }else if( sp->fallback ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "More than one fallback assigned to token %s", x); - psp->errorcnt++; - }else{ - sp->fallback = psp->fallback; - psp->gp->has_fallback = 1; - } - } - break; - case WAITING_FOR_WILDCARD_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%wildcard argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->gp->wildcard==0 ){ - psp->gp->wildcard = sp; - }else{ - ErrorMsg(psp->filename, psp->tokenlineno, - "Extra wildcard to token: %s", x); - psp->errorcnt++; - } - } - break; - case RESYNC_AFTER_RULE_ERROR: -/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; -** break; */ - case RESYNC_AFTER_DECL_ERROR: - if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; - if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; - break; - } -} - -/* Run the preprocessor over the input file text. The global variables -** azDefine[0] through azDefine[nDefine-1] contains the names of all defined -** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and -** comments them out. Text in between is also commented out as appropriate. -*/ -static void preprocess_input(char *z){ - int i, j, k, n; - int exclude = 0; - int start = 0; - int lineno = 1; - int start_lineno = 1; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) lineno++; - if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ - if( exclude ){ - exclude--; - if( exclude==0 ){ - for(j=start; jfilename; - ps.errorcnt = 0; - ps.state = INITIALIZE; - - /* Begin by reading the input file */ - fp = fopen(ps.filename,"rb"); - if( fp==0 ){ - ErrorMsg(ps.filename,0,"Can't open this file for reading."); - gp->errorcnt++; - return; - } - fseek(fp,0,2); - filesize = ftell(fp); - rewind(fp); - filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); - gp->errorcnt++; - return; - } - if( fread(filebuf,1,filesize,fp)!=filesize ){ - ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", - filesize); - free(filebuf); - gp->errorcnt++; - return; - } - fclose(fp); - filebuf[filesize] = 0; - - /* Make an initial pass through the file to handle %ifdef and %ifndef */ - preprocess_input(filebuf); - - /* Now scan the text of the input file */ - lineno = 1; - for(cp=filebuf; (c= *cp)!=0; ){ - if( c=='\n' ) lineno++; /* Keep track of the line number */ - if( isspace(c) ){ cp++; continue; } /* Skip all white space */ - if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ - cp+=2; - while( (c= *cp)!=0 && c!='\n' ) cp++; - continue; - } - if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ - cp+=2; - while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c ) cp++; - continue; - } - ps.tokenstart = cp; /* Mark the beginning of the token */ - ps.tokenlineno = lineno; /* Linenumber on which token begins */ - if( c=='\"' ){ /* String literals */ - cp++; - while( (c= *cp)!=0 && c!='\"' ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c==0 ){ - ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( c=='{' ){ /* A block of C code */ - int level; - cp++; - for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ - if( c=='\n' ) lineno++; - else if( c=='{' ) level++; - else if( c=='}' ) level--; - else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ - int prevc; - cp = &cp[2]; - prevc = 0; - while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ - if( c=='\n' ) lineno++; - prevc = c; - cp++; - } - }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ - cp = &cp[2]; - while( (c= *cp)!=0 && c!='\n' ) cp++; - if( c ) lineno++; - }else if( c=='\'' || c=='\"' ){ /* String a character literals */ - int startchar, prevc; - startchar = c; - prevc = 0; - for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ - if( c=='\n' ) lineno++; - if( prevc=='\\' ) prevc = 0; - else prevc = c; - } - } - } - if( c==0 ){ - ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( isalnum(c) ){ /* Identifiers */ - while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ - cp += 3; - nextcp = cp; - }else if( (c=='/' || c=='|') && isalpha(cp[1]) ){ - cp += 2; - while( (c = *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else{ /* All other (one character) operators */ - cp++; - nextcp = cp; - } - c = *cp; - *cp = 0; /* Null terminate the token */ - parseonetoken(&ps); /* Parse the token */ - *cp = c; /* Restore the buffer */ - cp = nextcp; - } - free(filebuf); /* Release the buffer after parsing */ - gp->rule = ps.firstrule; - gp->errorcnt = ps.errorcnt; -} -/*************************** From the file "plink.c" *********************/ -/* -** Routines processing configuration follow-set propagation links -** in the LEMON parser generator. -*/ -static struct plink *plink_freelist = 0; - -/* Allocate a new plink */ -struct plink *Plink_new(){ - struct plink *new; - - if( plink_freelist==0 ){ - int i; - int amt = 100; - plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); - if( plink_freelist==0 ){ - fprintf(stderr, - "Unable to allocate memory for a new follow-set propagation link.\n"); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Add a plink to a plink list */ -void Plink_add(plpp,cfp) -struct plink **plpp; -struct config *cfp; -{ - struct plink *new; - new = Plink_new(); - new->next = *plpp; - *plpp = new; - new->cfp = cfp; -} - -/* Transfer every plink on the list "from" to the list "to" */ -void Plink_copy(to,from) -struct plink **to; -struct plink *from; -{ - struct plink *nextpl; - while( from ){ - nextpl = from->next; - from->next = *to; - *to = from; - from = nextpl; - } -} - -/* Delete every plink on the list */ -void Plink_delete(plp) -struct plink *plp; -{ - struct plink *nextpl; - - while( plp ){ - nextpl = plp->next; - plp->next = plink_freelist; - plink_freelist = plp; - plp = nextpl; - } -} -/*********************** From the file "report.c" **************************/ -/* -** Procedures for generating reports and tables in the LEMON parser generator. -*/ - -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. -*/ -PRIVATE char *file_makename(lemp,suffix) -struct lemon *lemp; -char *suffix; -{ - char *name; - char *cp; - - name = malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); - if( name==0 ){ - fprintf(stderr,"Can't allocate space for a filename.\n"); - exit(1); - } - strcpy(name,lemp->filename); - cp = strrchr(name,'.'); - if( cp ) *cp = 0; - strcat(name,suffix); - return name; -} - -/* Open a file with a name based on the name of the input file, -** but with a different (specified) suffix, and return a pointer -** to the stream */ -PRIVATE FILE *file_open(lemp,suffix,mode) -struct lemon *lemp; -char *suffix; -char *mode; -{ - FILE *fp; - - if( lemp->outname ) free(lemp->outname); - lemp->outname = file_makename(lemp, suffix); - fp = fopen(lemp->outname,mode); - if( fp==0 && *mode=='w' ){ - fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); - lemp->errorcnt++; - return 0; - } - return fp; -} - -/* Duplicate the input file without comments and without actions -** on rules */ -void Reprint(lemp) -struct lemon *lemp; -{ - struct rule *rp; - struct symbol *sp; - int i, j, maxlen, len, ncolumns, skip; - printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); - maxlen = 10; - for(i=0; insymbol; i++){ - sp = lemp->symbols[i]; - len = lemonStrlen(sp->name); - if( len>maxlen ) maxlen = len; - } - ncolumns = 76/(maxlen+5); - if( ncolumns<1 ) ncolumns = 1; - skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; - for(i=0; insymbol; j+=skip){ - sp = lemp->symbols[j]; - assert( sp->index==j ); - printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); - } - printf("\n"); - } - for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); - /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; inrhs; i++){ - sp = rp->rhs[i]; - printf(" %s", sp->name); - if( sp->type==MULTITERMINAL ){ - for(j=1; jnsubsym; j++){ - printf("|%s", sp->subsym[j]->name); - } - } - /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } - printf("."); - if( rp->precsym ) printf(" [%s]",rp->precsym->name); - /* if( rp->code ) printf("\n %s",rp->code); */ - printf("\n"); - } -} - -void ConfigPrint(fp,cfp) -FILE *fp; -struct config *cfp; -{ - struct rule *rp; - struct symbol *sp; - int i, j; - rp = cfp->rp; - fprintf(fp,"%s ::=",rp->lhs->name); - for(i=0; i<=rp->nrhs; i++){ - if( i==cfp->dot ) fprintf(fp," *"); - if( i==rp->nrhs ) break; - sp = rp->rhs[i]; - fprintf(fp," %s", sp->name); - if( sp->type==MULTITERMINAL ){ - for(j=1; jnsubsym; j++){ - fprintf(fp,"|%s",sp->subsym[j]->name); - } - } - } -} - -/* #define TEST */ -#if 0 -/* Print a set */ -PRIVATE void SetPrint(out,set,lemp) -FILE *out; -char *set; -struct lemon *lemp; -{ - int i; - char *spacer; - spacer = ""; - fprintf(out,"%12s[",""); - for(i=0; interminal; i++){ - if( SetFind(set,i) ){ - fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); - spacer = " "; - } - } - fprintf(out,"]\n"); -} - -/* Print a plink chain */ -PRIVATE void PlinkPrint(out,plp,tag) -FILE *out; -struct plink *plp; -char *tag; -{ - while( plp ){ - fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->statenum); - ConfigPrint(out,plp->cfp); - fprintf(out,"\n"); - plp = plp->next; - } -} -#endif - -/* Print an action to the given file descriptor. Return FALSE if -** nothing was actually printed. -*/ -int PrintAction(struct action *ap, FILE *fp, int indent){ - int result = 1; - switch( ap->type ){ - case SHIFT: - fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->statenum); - break; - case REDUCE: - fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); - break; - case ACCEPT: - fprintf(fp,"%*s accept",indent,ap->sp->name); - break; - case ERROR: - fprintf(fp,"%*s error",indent,ap->sp->name); - break; - case SRCONFLICT: - case RRCONFLICT: - fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); - break; - case SSCONFLICT: - fprintf(fp,"%*s shift %d ** Parsing conflict **", - indent,ap->sp->name,ap->x.stp->statenum); - break; - case SH_RESOLVED: - case RD_RESOLVED: - case NOT_USED: - result = 0; - break; - } - return result; -} - -/* Generate the "y.output" log file */ -void ReportOutput(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct config *cfp; - struct action *ap; - FILE *fp; - - fp = file_open(lemp,".out","wb"); - if( fp==0 ) return; - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - fprintf(fp,"State %d:\n",stp->statenum); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#if 0 - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - } - fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } - fprintf(fp,"\n"); - } - fprintf(fp, "----------------------------------------------------\n"); - fprintf(fp, "Symbols:\n"); - for(i=0; insymbol; i++){ - int j; - struct symbol *sp; - - sp = lemp->symbols[i]; - fprintf(fp, " %3d: %s", i, sp->name); - if( sp->type==NONTERMINAL ){ - fprintf(fp, ":"); - if( sp->lambda ){ - fprintf(fp, " "); - } - for(j=0; jnterminal; j++){ - if( sp->firstset && SetFind(sp->firstset, j) ){ - fprintf(fp, " %s", lemp->symbols[j]->name); - } - } - } - fprintf(fp, "\n"); - } - fclose(fp); - return; -} - -/* Search for the file "name" which is in the same directory as -** the exacutable */ -PRIVATE char *pathsearch(argv0,name,modemask) -char *argv0; -char *name; -int modemask; -{ - char *pathlist; - char *path,*cp; - char c; - -#ifdef __WIN32__ - cp = strrchr(argv0,'\\'); -#else - cp = strrchr(argv0,'/'); -#endif - if( cp ){ - c = *cp; - *cp = 0; - path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); - *cp = c; - }else{ - extern char *getenv(); - pathlist = getenv("PATH"); - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); - if( path!=0 ){ - while( *pathlist ){ - cp = strchr(pathlist,':'); - if( cp==0 ) cp = &pathlist[lemonStrlen(pathlist)]; - c = *cp; - *cp = 0; - sprintf(path,"%s/%s",pathlist,name); - *cp = c; - if( c==0 ) pathlist = ""; - else pathlist = &cp[1]; - if( access(path,modemask)==0 ) break; - } - } - } - return path; -} - -/* Given an action, compute the integer value for that action -** which is to be put in the action table of the generated machine. -** Return negative if no action should be generated. -*/ -PRIVATE int compute_action(lemp,ap) -struct lemon *lemp; -struct action *ap; -{ - int act; - switch( ap->type ){ - case SHIFT: act = ap->x.stp->statenum; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate; break; - case ERROR: act = lemp->nstate + lemp->nrule; break; - case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; - default: act = -1; break; - } - return act; -} - -#define LINESIZE 1000 -/* The next cluster of routines are for reading the template file -** and writing the results to the generated parser */ -/* The first function transfers data from "in" to "out" until -** a line is seen which begins with "%%". The line number is -** tracked. -** -** if name!=0, then any word that begin with "Parse" is changed to -** begin with *name instead. -*/ -PRIVATE void tplt_xfer(name,in,out,lineno) -char *name; -FILE *in; -FILE *out; -int *lineno; -{ - int i, iStart; - char line[LINESIZE]; - while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ - (*lineno)++; - iStart = 0; - if( name ){ - for(i=0; line[i]; i++){ - if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 - && (i==0 || !isalpha(line[i-1])) - ){ - if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); - fprintf(out,"%s",name); - i += 4; - iStart = i+1; - } - } - } - fprintf(out,"%s",&line[iStart]); - } -} - -/* The next function finds the template file and opens it, returning -** a pointer to the opened file. */ -PRIVATE FILE *tplt_open(lemp) -struct lemon *lemp; -{ - static char templatename[] = "lempar.c"; - char buf[1000]; - FILE *in; - char *tpltname; - char *cp; - - cp = strrchr(lemp->filename,'.'); - if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); - }else{ - sprintf(buf,"%s.lt",lemp->filename); - } - if( access(buf,004)==0 ){ - tpltname = buf; - }else if( access(templatename,004)==0 ){ - tpltname = templatename; - }else{ - tpltname = pathsearch(lemp->argv0,templatename,0); - } - if( tpltname==0 ){ - fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", - templatename); - lemp->errorcnt++; - return 0; - } - in = fopen(tpltname,"rb"); - if( in==0 ){ - fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - lemp->errorcnt++; - return 0; - } - return in; -} - -/* Print a #line directive line to the output file. */ -PRIVATE void tplt_linedir(out,lineno,filename) -FILE *out; -int lineno; -char *filename; -{ - fprintf(out,"#line %d \"",lineno); - while( *filename ){ - if( *filename == '\\' ) putc('\\',out); - putc(*filename,out); - filename++; - } - fprintf(out,"\"\n"); -} - -/* Print a string to the file and keep the linenumber up to date */ -PRIVATE void tplt_print(out,lemp,str,lineno) -FILE *out; -struct lemon *lemp; -char *str; -int *lineno; -{ - if( str==0 ) return; - while( *str ){ - putc(*str,out); - if( *str=='\n' ) (*lineno)++; - str++; - } - if( str[-1]!='\n' ){ - putc('\n',out); - (*lineno)++; - } - if (!lemp->nolinenosflag) { - (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); - } - return; -} - -/* -** The following routine emits code for the destructor for the -** symbol sp -*/ -void emit_destructor_code(out,sp,lemp,lineno) -FILE *out; -struct symbol *sp; -struct lemon *lemp; -int *lineno; -{ - char *cp = 0; - - if( sp->type==TERMINAL ){ - cp = lemp->tokendest; - if( cp==0 ) return; - fprintf(out,"{\n"); (*lineno)++; - }else if( sp->destructor ){ - cp = sp->destructor; - fprintf(out,"{\n"); (*lineno)++; - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,sp->destLineno,lemp->filename); } - }else if( lemp->vardest ){ - cp = lemp->vardest; - if( cp==0 ) return; - fprintf(out,"{\n"); (*lineno)++; - }else{ - assert( 0 ); /* Cannot happen */ - } - for(; *cp; cp++){ - if( *cp=='$' && cp[1]=='$' ){ - fprintf(out,"(yypminor->yy%d)",sp->dtnum); - cp++; - continue; - } - if( *cp=='\n' ) (*lineno)++; - fputc(*cp,out); - } - fprintf(out,"\n"); (*lineno)++; - if (!lemp->nolinenosflag) { - (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); - } - fprintf(out,"}\n"); (*lineno)++; - return; -} - -/* -** Return TRUE (non-zero) if the given symbol has a destructor. -*/ -int has_destructor(sp, lemp) -struct symbol *sp; -struct lemon *lemp; -{ - int ret; - if( sp->type==TERMINAL ){ - ret = lemp->tokendest!=0; - }else{ - ret = lemp->vardest!=0 || sp->destructor!=0; - } - return ret; -} - -/* -** Append text to a dynamically allocated string. If zText is 0 then -** reset the string to be empty again. Always return the complete text -** of the string (which is overwritten with each call). -** -** n bytes of zText are stored. If n==0 then all of zText up to the first -** \000 terminator is stored. zText can contain up to two instances of -** %d. The values of p1 and p2 are written into the first and second -** %d. -** -** If n==-1, then the previous character is overwritten. -*/ -PRIVATE char *append_str(char *zText, int n, int p1, int p2){ - static char *z = 0; - static int alloced = 0; - static int used = 0; - int c; - char zInt[40]; - - if( zText==0 ){ - used = 0; - return z; - } - if( n<=0 ){ - if( n<0 ){ - used += n; - assert( used>=0 ); - } - n = lemonStrlen(zText); - } - if( n+sizeof(zInt)*2+used >= alloced ){ - alloced = n + sizeof(zInt)*2 + used + 200; - z = realloc(z, alloced); - } - if( z==0 ) return ""; - while( n-- > 0 ){ - c = *(zText++); - if( c=='%' && n>0 && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); - p1 = p2; - strcpy(&z[used], zInt); - used += lemonStrlen(&z[used]); - zText++; - n--; - }else{ - z[used++] = c; - } - } - z[used] = 0; - return z; -} - -/* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. -*/ -PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ - char *cp, *xp; - int i; - char lhsused = 0; /* True if the LHS element has been used */ - char used[MAXRHS]; /* True for each RHS element which is used */ - - for(i=0; inrhs; i++) used[i] = 0; - lhsused = 0; - - if( rp->code==0 ){ - rp->code = "\n"; - rp->line = rp->ruleline; - } - - append_str(0,0,0,0); - for(cp=rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ - char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); - saved = *xp; - *xp = 0; - if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ - append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); - cp = xp; - lhsused = 1; - }else{ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ - if( cp!=rp->code && cp[-1]=='@' ){ - /* If the argument is of the form @X then substituted - ** the token number of X, not the value of X */ - append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); - }else{ - struct symbol *sp = rp->rhs[i]; - int dtnum; - if( sp->type==MULTITERMINAL ){ - dtnum = sp->subsym[0]->dtnum; - }else{ - dtnum = sp->dtnum; - } - append_str("yymsp[%d].minor.yy%d",0,i-rp->nrhs+1, dtnum); - } - cp = xp; - used[i] = 1; - break; - } - } - } - *xp = saved; - } - append_str(cp, 1, 0, 0); - } /* End loop */ - - /* Check to make sure the LHS has been used */ - if( rp->lhsalias && !lhsused ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label \"%s\" for \"%s(%s)\" is never used.", - rp->lhsalias,rp->lhs->name,rp->lhsalias); - lemp->errorcnt++; - } - - /* Generate destructor code for RHS symbols which are not used in the - ** reduce code */ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && !used[i] ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label %s for \"%s(%s)\" is never used.", - rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); - lemp->errorcnt++; - }else if( rp->rhsalias[i]==0 ){ - if( has_destructor(rp->rhs[i],lemp) ){ - append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, - rp->rhs[i]->index,i-rp->nrhs+1); - }else{ - /* No destructor defined for this term */ - } - } - } - if( rp->code ){ - cp = append_str(0,0,0,0); - rp->code = Strsafe(cp?cp:""); - } -} - -/* -** Generate code which executes when the rule "rp" is reduced. Write -** the code to "out". Make sure lineno stays up-to-date. -*/ -PRIVATE void emit_code(out,rp,lemp,lineno) -FILE *out; -struct rule *rp; -struct lemon *lemp; -int *lineno; -{ - char *cp; - - /* Generate code to do the reduce action */ - if( rp->code ){ - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,rp->line,lemp->filename); } - fprintf(out,"{%s",rp->code); - for(cp=rp->code; *cp; cp++){ - if( *cp=='\n' ) (*lineno)++; - } /* End loop */ - fprintf(out,"}\n"); (*lineno)++; - if (!lemp->nolinenosflag) { (*lineno)++; tplt_linedir(out,*lineno,lemp->outname); } - } /* End if( rp->code ) */ - - return; -} - -/* -** Print the definition of the union used for the parser's data stack. -** This union contains fields for every possible data type for tokens -** and nonterminals. In the process of computing and printing this -** union, also set the ".dtnum" field of every terminal and nonterminal -** symbol. -*/ -void print_stack_union(out,lemp,plineno,mhflag) -FILE *out; /* The output stream */ -struct lemon *lemp; /* The main info structure for this parser */ -int *plineno; /* Pointer to the line number */ -int mhflag; /* True if generating makeheaders output */ -{ - int lineno = *plineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ - char *stddt; /* Standardized name for a datatype */ - int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ - char *name; /* Name of the parser */ - - /* Allocate and initialize types[] and allocate stddt[] */ - arraysize = lemp->nsymbol * 2; - types = (char**)calloc( arraysize, sizeof(char*) ); - for(i=0; ivartype ){ - maxdtlength = lemonStrlen(lemp->vartype); - } - for(i=0; insymbol; i++){ - int len; - struct symbol *sp = lemp->symbols[i]; - if( sp->datatype==0 ) continue; - len = lemonStrlen(sp->datatype); - if( len>maxdtlength ) maxdtlength = len; - } - stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - - /* Build a hash table of datatypes. The ".dtnum" field of each symbol - ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is - ** used for terminal symbols. If there is no %default_type defined then - ** 0 is also used as the .dtnum value for nonterminals which do not specify - ** a datatype using the %type directive. - */ - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - char *cp; - if( sp==lemp->errsym ){ - sp->dtnum = arraysize+1; - continue; - } - if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ - sp->dtnum = 0; - continue; - } - cp = sp->datatype; - if( cp==0 ) cp = lemp->vartype; - j = 0; - while( isspace(*cp) ) cp++; - while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; - stddt[j] = 0; - if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){ - sp->dtnum = 0; - continue; - } - hash = 0; - for(j=0; stddt[j]; j++){ - hash = hash*53 + stddt[j]; - } - hash = (hash & 0x7fffffff)%arraysize; - while( types[hash] ){ - if( strcmp(types[hash],stddt)==0 ){ - sp->dtnum = hash + 1; - break; - } - hash++; - if( hash>=arraysize ) hash = 0; - } - if( types[hash]==0 ){ - sp->dtnum = hash + 1; - types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); - if( types[hash]==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - strcpy(types[hash],stddt); - } - } - - /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ - name = lemp->name ? lemp->name : "Parse"; - lineno = *plineno; - if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } - fprintf(out,"#define %sTOKENTYPE %s\n",name, - lemp->tokentype?lemp->tokentype:"void*"); lineno++; - if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - fprintf(out,"typedef union {\n"); lineno++; - fprintf(out," int yyinit;\n"); lineno++; - fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; - for(i=0; ierrsym->useCnt ){ - fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; - } - free(stddt); - free(types); - fprintf(out,"} YYMINORTYPE;\n"); lineno++; - *plineno = lineno; -} - -/* -** Return the name of a C datatype able to represent values between -** lwr and upr, inclusive. -*/ -static const char *minimum_size_type(int lwr, int upr){ - if( lwr>=0 ){ - if( upr<=255 ){ - return "unsigned char"; - }else if( upr<65535 ){ - return "unsigned short int"; - }else{ - return "unsigned int"; - } - }else if( lwr>=-127 && upr<=127 ){ - return "signed char"; - }else if( lwr>=-32767 && upr<32767 ){ - return "short"; - }else{ - return "int"; - } -} - -/* -** Each state contains a set of token transaction and a set of -** nonterminal transactions. Each of these sets makes an instance -** of the following structure. An array of these structures is used -** to order the creation of entries in the yy_action[] table. -*/ -struct axset { - struct state *stp; /* A pointer to a state */ - int isTkn; /* True to use tokens. False for non-terminals */ - int nAction; /* Number of actions */ -}; - -/* -** Compare to axset structures for sorting purposes -*/ -static int axset_compare(const void *a, const void *b){ - struct axset *p1 = (struct axset*)a; - struct axset *p2 = (struct axset*)b; - return p2->nAction - p1->nAction; -} - -/* -** Write text on "out" that describes the rule "rp". -*/ -static void writeRuleText(FILE *out, struct rule *rp){ - int j; - fprintf(out,"%s ::=", rp->lhs->name); - for(j=0; jnrhs; j++){ - struct symbol *sp = rp->rhs[j]; - fprintf(out," %s", sp->name); - if( sp->type==MULTITERMINAL ){ - int k; - for(k=1; knsubsym; k++){ - fprintf(out,"|%s",sp->subsym[k]->name); - } - } - } -} - - -/* Generate C source code for the parser */ -void ReportTable(lemp, mhflag) -struct lemon *lemp; -int mhflag; /* Output in makeheaders format if true */ -{ - FILE *out, *in; - char line[LINESIZE]; - int lineno; - struct state *stp; - struct action *ap; - struct rule *rp; - struct acttab *pActtab; - int i, j, n; - char *name; - int mnTknOfst, mxTknOfst; - int mnNtOfst, mxNtOfst; - struct axset *ax; - - in = tplt_open(lemp); - if( in==0 ) return; - out = file_open(lemp,".c","wb"); - if( out==0 ){ - fclose(in); - return; - } - lineno = 1; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,&lineno); - if( mhflag ){ - char *name = file_makename(lemp, ".h"); - fprintf(out,"#include \"%s\"\n", name); lineno++; - free(name); - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate #defines for all tokens */ - if( mhflag ){ - char *prefix; - fprintf(out,"#if INTERFACE\n"); lineno++; - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - lineno++; - } - fprintf(out,"#endif\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the defines */ - fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+1)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; - fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; - if( lemp->wildcard ){ - fprintf(out,"#define YYWILDCARD %d\n", - lemp->wildcard->index); lineno++; - } - print_stack_union(out,lemp,&lineno,mhflag); - fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++; - if( lemp->stacksize ){ - fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; - }else{ - fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; - } - fprintf(out, "#endif\n"); lineno++; - if( mhflag ){ - fprintf(out,"#if INTERFACE\n"); lineno++; - } - name = lemp->name ? lemp->name : "Parse"; - if( lemp->arg && lemp->arg[0] ){ - int i; - i = lemonStrlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; - fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", - name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", - name,&lemp->arg[i],&lemp->arg[i]); lineno++; - }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; - fprintf(out,"#define %sARG_FETCH\n",name); lineno++; - fprintf(out,"#define %sARG_STORE\n",name); lineno++; - } - if( mhflag ){ - fprintf(out,"#endif\n"); lineno++; - } - fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; - fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - if( lemp->errsym->useCnt ){ - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; - } - if( lemp->has_fallback ){ - fprintf(out,"#define YYFALLBACK 1\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the action table and its associates: - ** - ** yy_action[] A single table containing all actions. - ** yy_lookahead[] A table containing the lookahead for each entry in - ** yy_action. Used to detect hash collisions. - ** yy_shift_ofst[] For each state, the offset into yy_action for - ** shifting terminals. - ** yy_reduce_ofst[] For each state, the offset into yy_action for - ** shifting non-terminals after a reduce. - ** yy_default[] Default action for each state. - */ - - /* Compute the actions on all states and count them up */ - ax = calloc(lemp->nstate*2, sizeof(ax[0])); - if( ax==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - ax[i*2].stp = stp; - ax[i*2].isTkn = 1; - ax[i*2].nAction = stp->nTknAct; - ax[i*2+1].stp = stp; - ax[i*2+1].isTkn = 0; - ax[i*2+1].nAction = stp->nNtAct; - } - mxTknOfst = mnTknOfst = 0; - mxNtOfst = mnNtOfst = 0; - - /* Compute the action table. In order to try to keep the size of the - ** action table to a minimum, the heuristic of placing the largest action - ** sets first is used. - */ - qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); - for(i=0; instate*2 && ax[i].nAction>0; i++){ - stp = ax[i].stp; - if( ax[i].isTkn ){ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index>=lemp->nterminal ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iTknOfst = acttab_insert(pActtab); - if( stp->iTknOfstiTknOfst; - if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; - }else{ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->indexnterminal ) continue; - if( ap->sp->index==lemp->nsymbol ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iNtOfst = acttab_insert(pActtab); - if( stp->iNtOfstiNtOfst; - if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; - } - } - free(ax); - - /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - n = acttab_size(pActtab); - for(i=j=0; instate + lemp->nrule + 2; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", action); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_lookahead table */ - fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; - for(i=j=0; insymbol; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; - n = lemp->nstate; - while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++; - fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; - for(i=j=0; isorted[i]; - ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; - n = lemp->nstate; - while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++; - fprintf(out, "static const %s yy_reduce_ofst[] = {\n", - minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; - for(i=j=0; isorted[i]; - ofst = stp->iNtOfst; - if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the default action table */ - fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDflt); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of fallback tokens. - */ - if( lemp->has_fallback ){ - int mx = lemp->nterminal - 1; - while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } - for(i=0; i<=mx; i++){ - struct symbol *p = lemp->symbols[i]; - if( p->fallback==0 ){ - fprintf(out, " 0, /* %10s => nothing */\n", p->name); - }else{ - fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, - p->name, p->fallback->name); - } - lineno++; - } - } - tplt_xfer(lemp->name, in, out, &lineno); - - /* Generate a table containing the symbolic name of every symbol - */ - for(i=0; insymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } - } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate a table containing a text string that describes every - ** rule in the rule set of the grammar. This information is used - ** when tracing REDUCE actions. - */ - for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); - fprintf(out," /* %3d */ \"", i); - writeRuleText(out, rp); - fprintf(out,"\",\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes every time a symbol is popped from - ** the stack while processing errors or while destroying the parser. - ** (In other words, generate the %destructor actions) - */ - if( lemp->tokendest ){ - int once = 1; - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type!=TERMINAL ) continue; - if( once ){ - fprintf(out, " /* TERMINAL Destructor */\n"); lineno++; - once = 0; - } - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - } - for(i=0; insymbol && lemp->symbols[i]->type!=TERMINAL; i++); - if( insymbol ){ - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - int once = 1; - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - if( once ){ - fprintf(out, " /* Default NON-TERMINAL Destructor */\n"); lineno++; - once = 0; - } - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - } - fprintf(out," break;\n"); lineno++; - } - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; - - /* Combine duplicate destructors into a single case */ - for(j=i+1; jnsymbol; j++){ - struct symbol *sp2 = lemp->symbols[j]; - if( sp2 && sp2->type!=TERMINAL && sp2->destructor - && sp2->dtnum==sp->dtnum - && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d: /* %s */\n", - sp2->index, sp2->name); lineno++; - sp2->destructor = 0; - } - } - - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes whenever the parser stack overflows */ - tplt_print(out,lemp,lemp->overflow,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of rule information - ** - ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. - */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which execution during each REDUCE action */ - for(rp=lemp->rule; rp; rp=rp->next){ - translate_code(lemp, rp); - } - /* First output rules other than the default: rule */ - for(rp=lemp->rule; rp; rp=rp->next){ - struct rule *rp2; /* Other rules with the same action */ - if( rp->code==0 ) continue; - if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ - fprintf(out," case %d: /* ", rp->index); - writeRuleText(out, rp); - fprintf(out, " */\n"); lineno++; - for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ - fprintf(out," case %d: /* ", rp2->index); - writeRuleText(out, rp2); - fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++; - rp2->code = 0; - } - } - emit_code(out,rp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - rp->code = 0; - } - /* Finally, output the default: rule. We choose as the default: all - ** empty actions. */ - fprintf(out," default:\n"); lineno++; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code==0 ) continue; - assert( rp->code[0]=='\n' && rp->code[1]==0 ); - fprintf(out," /* (%d) ", rp->index); - writeRuleText(out, rp); - fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++; - } - fprintf(out," break;\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes if a parse fails */ - tplt_print(out,lemp,lemp->failure,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when a syntax error occurs */ - tplt_print(out,lemp,lemp->error,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when the parser accepts its input */ - tplt_print(out,lemp,lemp->accept,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Append any addition code the user desires */ - tplt_print(out,lemp,lemp->extracode,&lineno); - - fclose(in); - fclose(out); - return; -} - -/* Generate a header file for the parser */ -void ReportHeader(lemp) -struct lemon *lemp; -{ - FILE *out, *in; - char *prefix; - char line[LINESIZE]; - char pattern[LINESIZE]; - int i; - - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - in = file_open(lemp,".h","rb"); - if( in ){ - for(i=1; interminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - if( strcmp(line,pattern) ) break; - } - fclose(in); - if( i==lemp->nterminal ){ - /* No change in the file. Don't rewrite it. */ - return; - } - } - out = file_open(lemp,".h","wb"); - if( out ){ - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - } - fclose(out); - } - return; -} - -/* Reduce the size of the action tables, if possible, by making use -** of defaults. -** -** In this version, we take the most frequent REDUCE action and make -** it the default. Except, there is no default if the wildcard token -** is a possible look-ahead. -*/ -void CompressTables(lemp) -struct lemon *lemp; -{ - struct state *stp; - struct action *ap, *ap2; - struct rule *rp, *rp2, *rbest; - int nbest, n; - int i; - int usesWildcard; - - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - nbest = 0; - rbest = 0; - usesWildcard = 0; - - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==SHIFT && ap->sp==lemp->wildcard ){ - usesWildcard = 1; - } - if( ap->type!=REDUCE ) continue; - rp = ap->x.rp; - if( rp->lhsStart ) continue; - if( rp==rbest ) continue; - n = 1; - for(ap2=ap->next; ap2; ap2=ap2->next){ - if( ap2->type!=REDUCE ) continue; - rp2 = ap2->x.rp; - if( rp2==rbest ) continue; - if( rp2==rp ) n++; - } - if( n>nbest ){ - nbest = n; - rbest = rp; - } - } - - /* Do not make a default if the number of rules to default - ** is not at least 1 or if the wildcard token is a possible - ** lookahead. - */ - if( nbest<1 || usesWildcard ) continue; - - - /* Combine matching REDUCE actions into a single default */ - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) break; - } - assert( ap ); - ap->sp = Symbol_new("{default}"); - for(ap=ap->next; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; - } - stp->ap = Action_sort(stp->ap); - } -} - - -/* -** Compare two states for sorting purposes. The smaller state is the -** one with the most non-terminal actions. If they have the same number -** of non-terminal actions, then the smaller is the one with the most -** token actions. -*/ -static int stateResortCompare(const void *a, const void *b){ - const struct state *pA = *(const struct state**)a; - const struct state *pB = *(const struct state**)b; - int n; - - n = pB->nNtAct - pA->nNtAct; - if( n==0 ){ - n = pB->nTknAct - pA->nTknAct; - } - return n; -} - - -/* -** Renumber and resort states so that states with fewer choices -** occur at the end. Except, keep state 0 as the first state. -*/ -void ResortStates(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct action *ap; - - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - stp->nTknAct = stp->nNtAct = 0; - stp->iDflt = lemp->nstate + lemp->nrule; - stp->iTknOfst = NO_OFFSET; - stp->iNtOfst = NO_OFFSET; - for(ap=stp->ap; ap; ap=ap->next){ - if( compute_action(lemp,ap)>=0 ){ - if( ap->sp->indexnterminal ){ - stp->nTknAct++; - }else if( ap->sp->indexnsymbol ){ - stp->nNtAct++; - }else{ - stp->iDflt = compute_action(lemp, ap); - } - } - } - } - qsort(&lemp->sorted[1], lemp->nstate-1, sizeof(lemp->sorted[0]), - stateResortCompare); - for(i=0; instate; i++){ - lemp->sorted[i]->statenum = i; - } -} - - -/***************** From the file "set.c" ************************************/ -/* -** Set manipulation routines for the LEMON parser generator. -*/ - -static int size = 0; - -/* Set the set size */ -void SetSize(n) -int n; -{ - size = n+1; -} - -/* Allocate a new set */ -char *SetNew(){ - char *s; - s = (char*)calloc( size, 1); - if( s==0 ){ - extern void memory_error(); - memory_error(); - } - return s; -} - -/* Deallocate a set */ -void SetFree(s) -char *s; -{ - free(s); -} - -/* Add a new element to the set. Return TRUE if the element was added -** and FALSE if it was already there. */ -int SetAdd(s,e) -char *s; -int e; -{ - int rv; - assert( e>=0 && esize = 1024; - x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); - if( x1a->tbl==0 ){ - free(x1a); - x1a = 0; - }else{ - int i; - x1a->ht = (x1node**)&(x1a->tbl[1024]); - for(i=0; i<1024; i++) x1a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Strsafe_insert(data) -char *data; -{ - x1node *np; - int h; - int ph; - - if( x1a==0 ) return 0; - ph = strhash(data); - h = ph & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x1a->count>=x1a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x1 array; - array.size = size = x1a->size*2; - array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x1node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x1node *oldnp, *newnp; - oldnp = &(x1a->tbl[i]); - h = strhash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x1a->tbl); - *x1a = array; - } - /* Insert the new data */ - h = ph & (x1a->size-1); - np = &(x1a->tbl[x1a->count++]); - np->data = data; - if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); - np->next = x1a->ht[h]; - x1a->ht[h] = np; - np->from = &(x1a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -char *Strsafe_find(key) -char *key; -{ - int h; - x1node *np; - - if( x1a==0 ) return 0; - h = strhash(key) & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return a pointer to the (terminal or nonterminal) symbol "x". -** Create a new symbol if this is the first time "x" has been seen. -*/ -struct symbol *Symbol_new(x) -char *x; -{ - struct symbol *sp; - - sp = Symbol_find(x); - if( sp==0 ){ - sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); - MemoryCheck(sp); - sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; - sp->prec = -1; - sp->assoc = UNK; - sp->firstset = 0; - sp->lambda = LEMON_FALSE; - sp->destructor = 0; - sp->destLineno = 0; - sp->datatype = 0; - sp->useCnt = 0; - Symbol_insert(sp,sp->name); - } - sp->useCnt++; - return sp; -} - -/* Compare two symbols for working purposes -** -** Symbols that begin with upper case letters (terminals or tokens) -** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. -** -** We find experimentally that leaving the symbols in their original -** order (the order they appeared in the grammar file) gives the -** smallest parser tables in SQLite. -*/ -int Symbolcmpp(struct symbol **a, struct symbol **b){ - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - return i1-i2; -} - -/* There is one instance of the following structure for each -** associative array of type "x2". -*/ -struct s_x2 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x2node *tbl; /* The data stored here */ - struct s_x2node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x2". -*/ -typedef struct s_x2node { - struct symbol *data; /* The data */ - char *key; /* The key */ - struct s_x2node *next; /* Next entry with the same hash */ - struct s_x2node **from; /* Previous link */ -} x2node; - -/* There is only one instance of the array, which is the following */ -static struct s_x2 *x2a; - -/* Allocate a new associative array */ -void Symbol_init(){ - if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); - if( x2a ){ - x2a->size = 128; - x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); - if( x2a->tbl==0 ){ - free(x2a); - x2a = 0; - }else{ - int i; - x2a->ht = (x2node**)&(x2a->tbl[128]); - for(i=0; i<128; i++) x2a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Symbol_insert(data,key) -struct symbol *data; -char *key; -{ - x2node *np; - int h; - int ph; - - if( x2a==0 ) return 0; - ph = strhash(key); - h = ph & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x2a->count>=x2a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x2 array; - array.size = size = x2a->size*2; - array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x2node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x2node *oldnp, *newnp; - oldnp = &(x2a->tbl[i]); - h = strhash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x2a->tbl); - *x2a = array; - } - /* Insert the new data */ - h = ph & (x2a->size-1); - np = &(x2a->tbl[x2a->count++]); - np->key = key; - np->data = data; - if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); - np->next = x2a->ht[h]; - x2a->ht[h] = np; - np->from = &(x2a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct symbol *Symbol_find(key) -char *key; -{ - int h; - x2node *np; - - if( x2a==0 ) return 0; - h = strhash(key) & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return the n-th data. Return NULL if n is out of range. */ -struct symbol *Symbol_Nth(n) -int n; -{ - struct symbol *data; - if( x2a && n>0 && n<=x2a->count ){ - data = x2a->tbl[n-1].data; - }else{ - data = 0; - } - return data; -} - -/* Return the size of the array */ -int Symbol_count() -{ - return x2a ? x2a->count : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof() -{ - struct symbol **array; - int i,size; - if( x2a==0 ) return 0; - size = x2a->count; - array = (struct symbol **)calloc(size, sizeof(struct symbol *)); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Compare two configurations */ -int Configcmp(a,b) -struct config *a; -struct config *b; -{ - int x; - x = a->rp->index - b->rp->index; - if( x==0 ) x = a->dot - b->dot; - return x; -} - -/* Compare two states */ -PRIVATE int statecmp(a,b) -struct config *a; -struct config *b; -{ - int rc; - for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ - rc = a->rp->index - b->rp->index; - if( rc==0 ) rc = a->dot - b->dot; - } - if( rc==0 ){ - if( a ) rc = 1; - if( b ) rc = -1; - } - return rc; -} - -/* Hash a state */ -PRIVATE int statehash(a) -struct config *a; -{ - int h=0; - while( a ){ - h = h*571 + a->rp->index*37 + a->dot; - a = a->bp; - } - return h; -} - -/* Allocate a new state structure */ -struct state *State_new() -{ - struct state *new; - new = (struct state *)calloc(1, sizeof(struct state) ); - MemoryCheck(new); - return new; -} - -/* There is one instance of the following structure for each -** associative array of type "x3". -*/ -struct s_x3 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x3node *tbl; /* The data stored here */ - struct s_x3node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x3". -*/ -typedef struct s_x3node { - struct state *data; /* The data */ - struct config *key; /* The key */ - struct s_x3node *next; /* Next entry with the same hash */ - struct s_x3node **from; /* Previous link */ -} x3node; - -/* There is only one instance of the array, which is the following */ -static struct s_x3 *x3a; - -/* Allocate a new associative array */ -void State_init(){ - if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); - if( x3a ){ - x3a->size = 128; - x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); - if( x3a->tbl==0 ){ - free(x3a); - x3a = 0; - }else{ - int i; - x3a->ht = (x3node**)&(x3a->tbl[128]); - for(i=0; i<128; i++) x3a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int State_insert(data,key) -struct state *data; -struct config *key; -{ - x3node *np; - int h; - int ph; - - if( x3a==0 ) return 0; - ph = statehash(key); - h = ph & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x3a->count>=x3a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x3 array; - array.size = size = x3a->size*2; - array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x3node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x3node *oldnp, *newnp; - oldnp = &(x3a->tbl[i]); - h = statehash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x3a->tbl); - *x3a = array; - } - /* Insert the new data */ - h = ph & (x3a->size-1); - np = &(x3a->tbl[x3a->count++]); - np->key = key; - np->data = data; - if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); - np->next = x3a->ht[h]; - x3a->ht[h] = np; - np->from = &(x3a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct state *State_find(key) -struct config *key; -{ - int h; - x3node *np; - - if( x3a==0 ) return 0; - h = statehash(key) & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct state **State_arrayof() -{ - struct state **array; - int i,size; - if( x3a==0 ) return 0; - size = x3a->count; - array = (struct state **)malloc( sizeof(struct state *)*size ); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Hash a configuration */ -PRIVATE int confighash(a) -struct config *a; -{ - int h=0; - h = h*571 + a->rp->index*37 + a->dot; - return h; -} - -/* There is one instance of the following structure for each -** associative array of type "x4". -*/ -struct s_x4 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x4node *tbl; /* The data stored here */ - struct s_x4node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x4". -*/ -typedef struct s_x4node { - struct config *data; /* The data */ - struct s_x4node *next; /* Next entry with the same hash */ - struct s_x4node **from; /* Previous link */ -} x4node; - -/* There is only one instance of the array, which is the following */ -static struct s_x4 *x4a; - -/* Allocate a new associative array */ -void Configtable_init(){ - if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); - if( x4a ){ - x4a->size = 64; - x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); - if( x4a->tbl==0 ){ - free(x4a); - x4a = 0; - }else{ - int i; - x4a->ht = (x4node**)&(x4a->tbl[64]); - for(i=0; i<64; i++) x4a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Configtable_insert(data) -struct config *data; -{ - x4node *np; - int h; - int ph; - - if( x4a==0 ) return 0; - ph = confighash(data); - h = ph & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x4a->count>=x4a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x4 array; - array.size = size = x4a->size*2; - array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x4node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x4node *oldnp, *newnp; - oldnp = &(x4a->tbl[i]); - h = confighash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x4a->tbl); - *x4a = array; - } - /* Insert the new data */ - h = ph & (x4a->size-1); - np = &(x4a->tbl[x4a->count++]); - np->data = data; - if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); - np->next = x4a->ht[h]; - x4a->ht[h] = np; - np->from = &(x4a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct config *Configtable_find(key) -struct config *key; -{ - int h; - x4node *np; - - if( x4a==0 ) return 0; - h = confighash(key) & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Remove all data from the table. Pass each data to the function "f" -** as it is removed. ("f" may be null to avoid this step.) */ -void Configtable_clear(f) -int(*f)(/* struct config * */); -{ - int i; - if( x4a==0 || x4a->count==0 ) return; - if( f ) for(i=0; icount; i++) (*f)(x4a->tbl[i].data); - for(i=0; isize; i++) x4a->ht[i] = 0; - x4a->count = 0; - return; -} diff --git a/v2rayng/badvpn/lemon/lempar.c b/v2rayng/badvpn/lemon/lempar.c deleted file mode 100644 index 774b875e21..0000000000 --- a/v2rayng/badvpn/lemon/lempar.c +++ /dev/null @@ -1,842 +0,0 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included that follows the "include" declaration -** in the input grammar file. */ -#include -%% -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -%% -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -%% -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* The yyzerominor constant is used to initialize instances of -** YYMINORTYPE objects to zero. */ -static const YYMINORTYPE yyzerominor = { 0 }; - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -%% -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -%% -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ -#endif - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { -%% -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { -%% -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yystack = NULL; - pParser->yystksz = 0; - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - ParseARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ -%% - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor(pParser, yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -int ParseStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_MAX ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_MAX ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && iyyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { -%% -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - /*memset(&yygotominor, 0, sizeof(yygotominor));*/ - yygotominor = yyzerominor; - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ -%% - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ - yyminorunion = yyzerominor; - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyactyyerrcnt--; - yymajor = YYNOCODE; - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ - assert( yyact == YY_ERROR_ACTION ); -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor,yyminorunion); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} diff --git a/v2rayng/badvpn/lime/HOWTO b/v2rayng/badvpn/lime/HOWTO deleted file mode 100644 index f447c84fab..0000000000 --- a/v2rayng/badvpn/lime/HOWTO +++ /dev/null @@ -1,70 +0,0 @@ -Lime: An LALR(1) parser generator in and for PHP. - -Interpretter pattern got you down? Time to use a real parser? Welcome to Lime. - -If you're familiar with BISON or YACC, you may want to read the metagrammar. -It's written in the Lime input language, so you'll get a head-start on -understanding how to use Lime. - -0. If you're not running Linux on an IA32 box, then you will have to rebuild - lime_scan_tokens for your system. It should be enough to erase it, - and then type "CFLAGS=-O2 make lime_scan_tokens" at the bash prompt. - -1. Stare at the file lime/metagrammar to understand the syntax. You're seeing - slightly modified and tweaked Backus-Naur forms. The main differences - are that you get to name your components, instead of refering to them - by numbers the way that BISON demands. This idea was stolen from the - C-based "Lemon" parser from which Lime derives its name. Incidentally, - the author of Lemon disclaimed copyright, so you get a copy of the C - code that taught me LALR(1) parsing better than any book, despite the - obvious difficulties in understanding it. Oh, and one other thing: - symbols are terminal if the scanner feeds them to the parser. They - are non-terminal if they appear on the left side of a production rule. - Lime names semantic categories using strings instead of the numbers - that BISON-based parsers use, so you don't have to declare any list of - terminal symbols anywhere. - -2. Look at the file lime/lime.php to see what pragmas are defined. To be more - specific, you might look at the method lime::pragma(), which at the - time of this writing, supports "%left", "%right", "%nonassoc", - "%start", and "%class". The first three are for operator precedence. - The last two declare the start symbol and the name of a PHP class to - generate which will hold all the bottom-up parsing tables. - -3. Write a grammar file. - -4. php /path/to/lime/lime.php list-of-grammar-files > my_parser.php - -5. Read the function parse_lime_grammar() in lime.php to understand - how to integrate your parser into your program. - -6. Integrate your parser as follows: - ---------------- CUT --------------- - -include_once "lime/parse_engine.php"; -include_once "my_parser.php"; -# -# Later: -# -$parser = new parse_engine(new my_parser()); -# -# And still later: -# -try { - while (..something..) { - $parser->eat($type, $val); - # You figure out how to get the parameters. - } - # And after the last token has been eaten: - $parser->eat_eof(); -} catch (parse_error $e) { - die($e->getMessage()); -} -return $parser->semantic; - ---------------- CUT --------------- - -7. You now have the computed semantic value of whatever you parsed. Add salt - and pepper to taste, and serve. - diff --git a/v2rayng/badvpn/lime/flex_token_stream.php b/v2rayng/badvpn/lime/flex_token_stream.php deleted file mode 100644 index c21e411fbb..0000000000 --- a/v2rayng/badvpn/lime/flex_token_stream.php +++ /dev/null @@ -1,34 +0,0 @@ -executable(); - $tokens = explode("\0", `$scanner < "\$PHP_LIME_SCAN_STDIN"`); - array_pop($tokens); - $this->tokens = $tokens; - $this->lineno = 1; - } - function next() { - if (list($key, $token) = each($this->tokens)) { - list($this->lineno, $type, $text) = explode("\1", $token); - return array($type, $text); - } - } - function feed($parser) { - while (list($type, $text) = $this->next()) { - $parser->eat($type, $text); - } - return $parser->eat_eof(); - } -} diff --git a/v2rayng/badvpn/lime/lemon.c b/v2rayng/badvpn/lime/lemon.c deleted file mode 100644 index 708b3538d7..0000000000 --- a/v2rayng/badvpn/lime/lemon.c +++ /dev/null @@ -1,4588 +0,0 @@ -/* -** This file contains all sources (including headers) to the LEMON -** LALR(1) parser generator. The sources have been combined into a -** single file to make it easy to include LEMON in the source tree -** and Makefile of another program. -** -** The author of this program disclaims copyright. -*/ -#include -#include -#include -#include -#include - -#ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) -# define __WIN32__ -# endif -#endif - -/* #define PRIVATE static */ -#define PRIVATE - -#ifdef TEST -#define MAXRHS 5 /* Set low to exercise exception code */ -#else -#define MAXRHS 1000 -#endif - -char *msort(); -extern void *malloc(); - -/******** From the file "action.h" *************************************/ -struct action *Action_new(); -struct action *Action_sort(); - -/********* From the file "assert.h" ************************************/ -void myassert(); -#ifndef NDEBUG -# define assert(X) if(!(X))myassert(__FILE__,__LINE__) -#else -# define assert(X) -#endif - -/********** From the file "build.h" ************************************/ -void FindRulePrecedences(); -void FindFirstSets(); -void FindStates(); -void FindLinks(); -void FindFollowSets(); -void FindActions(); - -/********* From the file "configlist.h" *********************************/ -void Configlist_init(/* void */); -struct config *Configlist_add(/* struct rule *, int */); -struct config *Configlist_addbasis(/* struct rule *, int */); -void Configlist_closure(/* void */); -void Configlist_sort(/* void */); -void Configlist_sortbasis(/* void */); -struct config *Configlist_return(/* void */); -struct config *Configlist_basis(/* void */); -void Configlist_eat(/* struct config * */); -void Configlist_reset(/* void */); - -/********* From the file "error.h" ***************************************/ -void ErrorMsg(const char *, int,const char *, ...); - -/****** From the file "option.h" ******************************************/ -struct s_options { - enum { OPT_FLAG=1, OPT_INT, OPT_DBL, OPT_STR, - OPT_FFLAG, OPT_FINT, OPT_FDBL, OPT_FSTR} type; - char *label; - char *arg; - char *message; -}; -int OptInit(/* char**,struct s_options*,FILE* */); -int OptNArgs(/* void */); -char *OptArg(/* int */); -void OptErr(/* int */); -void OptPrint(/* void */); - -/******** From the file "parse.h" *****************************************/ -void Parse(/* struct lemon *lemp */); - -/********* From the file "plink.h" ***************************************/ -struct plink *Plink_new(/* void */); -void Plink_add(/* struct plink **, struct config * */); -void Plink_copy(/* struct plink **, struct plink * */); -void Plink_delete(/* struct plink * */); - -/********** From the file "report.h" *************************************/ -void Reprint(/* struct lemon * */); -void ReportOutput(/* struct lemon * */); -void ReportTable(/* struct lemon * */); -void ReportHeader(/* struct lemon * */); -void CompressTables(/* struct lemon * */); - -/********** From the file "set.h" ****************************************/ -void SetSize(/* int N */); /* All sets will be of size N */ -char *SetNew(/* void */); /* A new set for element 0..N */ -void SetFree(/* char* */); /* Deallocate a set */ - -int SetAdd(/* char*,int */); /* Add element to a set */ -int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ - -#define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ - -/********** From the file "struct.h" *************************************/ -/* -** Principal data structures for the LEMON parser generator. -*/ - -typedef enum {B_FALSE=0, B_TRUE} Boolean; - -/* Symbols (terminals and nonterminals) of the grammar are stored -** in the following: */ -struct symbol { - char *name; /* Name of the symbol */ - int index; /* Index number for this symbol */ - enum { - TERMINAL, - NONTERMINAL - } type; /* Symbols are all either TERMINALS or NTs */ - struct rule *rule; /* Linked list of rules of this (if an NT) */ - struct symbol *fallback; /* fallback token in case this token doesn't parse */ - int prec; /* Precedence if defined (-1 otherwise) */ - enum e_assoc { - LEFT, - RIGHT, - NONE, - UNK - } assoc; /* Associativity if predecence is defined */ - char *firstset; /* First-set for all rules of this symbol */ - Boolean lambda; /* True if NT and can generate an empty string */ - char *destructor; /* Code which executes whenever this symbol is - ** popped from the stack during error processing */ - int destructorln; /* Line number of destructor code */ - char *datatype; /* The data type of information held by this - ** object. Only used if type==NONTERMINAL */ - int dtnum; /* The data type number. In the parser, the value - ** stack is a union. The .yy%d element of this - ** union is the correct data type for this object */ -}; - -/* Each production rule in the grammar is stored in the following -** structure. */ -struct rule { - struct symbol *lhs; /* Left-hand side of the rule */ - char *lhsalias; /* Alias for the LHS (NULL if none) */ - int ruleline; /* Line number for the rule */ - int nrhs; /* Number of RHS symbols */ - struct symbol **rhs; /* The RHS symbols */ - char **rhsalias; /* An alias for each RHS symbol (NULL if none) */ - int line; /* Line number at which code begins */ - char *code; /* The code executed when this rule is reduced */ - struct symbol *precsym; /* Precedence symbol for this rule */ - int index; /* An index number for this rule */ - Boolean canReduce; /* True if this rule is ever reduced */ - struct rule *nextlhs; /* Next rule with the same LHS */ - struct rule *next; /* Next rule in the global list */ -}; - -/* A configuration is a production rule of the grammar together with -** a mark (dot) showing how much of that rule has been processed so far. -** Configurations also contain a follow-set which is a list of terminal -** symbols which are allowed to immediately follow the end of the rule. -** Every configuration is recorded as an instance of the following: */ -struct config { - struct rule *rp; /* The rule upon which the configuration is based */ - int dot; /* The parse point */ - char *fws; /* Follow-set for this configuration only */ - struct plink *fplp; /* Follow-set forward propagation links */ - struct plink *bplp; /* Follow-set backwards propagation links */ - struct state *stp; /* Pointer to state which contains this */ - enum { - COMPLETE, /* The status is used during followset and */ - INCOMPLETE /* shift computations */ - } status; - struct config *next; /* Next configuration in the state */ - struct config *bp; /* The next basis configuration */ -}; - -/* Every shift or reduce operation is stored as one of the following */ -struct action { - struct symbol *sp; /* The look-ahead symbol */ - enum e_action { - SHIFT, - ACCEPT, - REDUCE, - ERROR, - CONFLICT, /* Was a reduce, but part of a conflict */ - SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ - RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ - NOT_USED /* Deleted by compression */ - } type; - union { - struct state *stp; /* The new state, if a shift */ - struct rule *rp; /* The rule, if a reduce */ - } x; - struct action *next; /* Next action for this state */ - struct action *collide; /* Next action with the same hash */ -}; - -/* Each state of the generated parser's finite state machine -** is encoded as an instance of the following structure. */ -struct state { - struct config *bp; /* The basis configurations for this state */ - struct config *cfp; /* All configurations in this set */ - int index; /* Sequencial number for this state */ - struct action *ap; /* Array of actions for this state */ - int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ - int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ - int iDflt; /* Default action */ -}; -#define NO_OFFSET (-2147483647) - -/* A followset propagation link indicates that the contents of one -** configuration followset should be propagated to another whenever -** the first changes. */ -struct plink { - struct config *cfp; /* The configuration to which linked */ - struct plink *next; /* The next propagate link */ -}; - -/* The state vector for the entire parser generator is recorded as -** follows. (LEMON uses no global variables and makes little use of -** static variables. Fields in the following structure can be thought -** of as begin global variables in the program.) */ -struct lemon { - struct state **sorted; /* Table of states sorted by state number */ - struct rule *rule; /* List of all rules */ - int nstate; /* Number of states */ - int nrule; /* Number of rules */ - int nsymbol; /* Number of terminal and nonterminal symbols */ - int nterminal; /* Number of terminal symbols */ - struct symbol **symbols; /* Sorted array of pointers to symbols */ - int errorcnt; /* Number of errors */ - struct symbol *errsym; /* The error symbol */ - char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ - char *tokentype; /* Type of terminal symbols in the parser stack */ - char *vartype; /* The default type of non-terminal symbols */ - char *start; /* Name of the start symbol for the grammar */ - char *stacksize; /* Size of the parser stack */ - char *include; /* Code to put at the start of the C file */ - int includeln; /* Line number for start of include code */ - char *error; /* Code to execute when an error is seen */ - int errorln; /* Line number for start of error code */ - char *overflow; /* Code to execute on a stack overflow */ - int overflowln; /* Line number for start of overflow code */ - char *failure; /* Code to execute on parser failure */ - int failureln; /* Line number for start of failure code */ - char *accept; /* Code to execute when the parser excepts */ - int acceptln; /* Line number for the start of accept code */ - char *extracode; /* Code appended to the generated file */ - int extracodeln; /* Line number for the start of the extra code */ - char *tokendest; /* Code to execute to destroy token data */ - int tokendestln; /* Line number for token destroyer code */ - char *vardest; /* Code for the default non-terminal destructor */ - int vardestln; /* Line number for default non-term destructor code*/ - char *filename; /* Name of the input file */ - char *outname; /* Name of the current output file */ - char *tokenprefix; /* A prefix added to token names in the .h file */ - int nconflict; /* Number of parsing conflicts */ - int tablesize; /* Size of the parse tables */ - int basisflag; /* Print only basis configurations */ - int has_fallback; /* True if any %fallback is seen in the grammer */ - char *argv0; /* Name of the program */ -}; - -#define MemoryCheck(X) if((X)==0){ \ - extern void memory_error(); \ - memory_error(); \ -} - -/**************** From the file "table.h" *********************************/ -/* -** All code in this file has been automatically generated -** from a specification in the file -** "table.q" -** by the associative array code building program "aagen". -** Do not edit this file! Instead, edit the specification -** file, then rerun aagen. -*/ -/* -** Code for processing tables in the LEMON parser generator. -*/ - -/* Routines for handling a strings */ - -char *Strsafe(); - -void Strsafe_init(/* void */); -int Strsafe_insert(/* char * */); -char *Strsafe_find(/* char * */); - -/* Routines for handling symbols of the grammar */ - -struct symbol *Symbol_new(); -int Symbolcmpp(/* struct symbol **, struct symbol ** */); -void Symbol_init(/* void */); -int Symbol_insert(/* struct symbol *, char * */); -struct symbol *Symbol_find(/* char * */); -struct symbol *Symbol_Nth(/* int */); -int Symbol_count(/* */); -struct symbol **Symbol_arrayof(/* */); - -/* Routines to manage the state table */ - -int Configcmp(/* struct config *, struct config * */); -struct state *State_new(); -void State_init(/* void */); -int State_insert(/* struct state *, struct config * */); -struct state *State_find(/* struct config * */); -struct state **State_arrayof(/* */); - -/* Routines used for efficiency in Configlist_add */ - -void Configtable_init(/* void */); -int Configtable_insert(/* struct config * */); -struct config *Configtable_find(/* struct config * */); -void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -struct action *Action_new(){ - static struct action *freelist = 0; - struct action *new; - - if( freelist==0 ){ - int i; - int amt = 100; - freelist = (struct action *)malloc( sizeof(struct action)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Compare two actions */ -static int actioncmp(ap1,ap2) -struct action *ap1; -struct action *ap2; -{ - int rc; - rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ) rc = (int)ap1->type - (int)ap2->type; - if( rc==0 ){ - assert( ap1->type==REDUCE || ap1->type==RD_RESOLVED || ap1->type==CONFLICT); - assert( ap2->type==REDUCE || ap2->type==RD_RESOLVED || ap2->type==CONFLICT); - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -struct action *Action_sort(ap) -struct action *ap; -{ - ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp); - return ap; -} - -void Action_add(app,type,sp,arg) -struct action **app; -enum e_action type; -struct symbol *sp; -char *arg; -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if( type==SHIFT ){ - new->x.stp = (struct state *)arg; - }else{ - new->x.rp = (struct rule *)arg; - } -} -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ - free( p->aAction ); - free( p->aLookahead ); - free( p ); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void){ - acttab *p = malloc( sizeof(*p) ); - if( p==0 ){ - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action){ - if( p->nLookahead>=p->nLookaheadAlloc ){ - p->nLookaheadAlloc += 25; - p->aLookahead = realloc( p->aLookahead, - sizeof(p->aLookahead[0])*p->nLookaheadAlloc ); - if( p->aLookahead==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if( p->nLookahead==0 ){ - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - }else{ - if( p->mxLookaheadmxLookahead = lookahead; - if( p->mnLookahead>lookahead ){ - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p){ - int i, j, k, n; - assert( p->nLookahead>0 ); - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if( p->nAction + n >= p->nActionAlloc ){ - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc( p->aAction, - sizeof(p->aAction[0])*p->nActionAlloc); - if( p->aAction==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; inActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; inAction+p->mnLookahead; i++){ - if( p->aAction[i].lookahead<0 ){ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 ) break; - if( p->aAction[k].lookahead>=0 ) break; - } - if( jnLookahead ) continue; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break; - } - if( j==p->nAction ){ - break; /* Fits in empty slots */ - } - }else if( p->aAction[i].lookahead==p->mnLookahead ){ - if( p->aAction[i].action!=p->mnAction ) continue; - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if( k<0 || k>=p->nAction ) break; - if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break; - if( p->aLookahead[j].action!=p->aAction[k].action ) break; - } - if( jnLookahead ) continue; - n = 0; - for(j=0; jnAction; j++){ - if( p->aAction[j].lookahead<0 ) continue; - if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++; - } - if( n==p->nLookahead ){ - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if( k>=p->nAction ) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - -/********************** From the file "assert.c" ****************************/ -/* -** A more efficient way of handling assertions. -*/ -void myassert(file,line) -char *file; -int line; -{ - fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file); - exit(1); -} -/********************** From the file "build.c" *****************************/ -/* -** Routines to construction the finite state machine for the LEMON -** parser generator. -*/ - -/* Find a precedence symbol of every rule in the grammar. -** -** Those rules which have a precedence symbol coded in the input -** grammar using the "[symbol]" construct will already have the -** rp->precsym field filled. Other rules take as their precedence -** symbol the first RHS symbol with a defined precedence. If there -** are not RHS symbols with a defined precedence, the precedence -** symbol field is left blank. -*/ -void FindRulePrecedences(xp) -struct lemon *xp; -{ - struct rule *rp; - for(rp=xp->rule; rp; rp=rp->next){ - if( rp->precsym==0 ){ - int i; - for(i=0; inrhs; i++){ - if( rp->rhs[i]->prec>=0 ){ - rp->precsym = rp->rhs[i]; - break; - } - } - } - } - return; -} - -/* Find all nonterminals which will generate the empty string. -** Then go back and compute the first sets of every nonterminal. -** The first set is the set of all terminal symbols which can begin -** a string generated by that nonterminal. -*/ -void FindFirstSets(lemp) -struct lemon *lemp; -{ - int i; - struct rule *rp; - int progress; - - for(i=0; insymbol; i++){ - lemp->symbols[i]->lambda = B_FALSE; - } - for(i=lemp->nterminal; insymbol; i++){ - lemp->symbols[i]->firstset = SetNew(); - } - - /* First compute all lambdas */ - do{ - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->lhs->lambda ) continue; - for(i=0; inrhs; i++){ - if( rp->rhs[i]->lambda==B_FALSE ) break; - } - if( i==rp->nrhs ){ - rp->lhs->lambda = B_TRUE; - progress = 1; - } - } - }while( progress ); - - /* Now compute all first sets */ - do{ - struct symbol *s1, *s2; - progress = 0; - for(rp=lemp->rule; rp; rp=rp->next){ - s1 = rp->lhs; - for(i=0; inrhs; i++){ - s2 = rp->rhs[i]; - if( s2->type==TERMINAL ){ - progress += SetAdd(s1->firstset,s2->index); - break; - }else if( s1==s2 ){ - if( s1->lambda==B_FALSE ) break; - }else{ - progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==B_FALSE ) break; - } - } - } - }while( progress ); - return; -} - -/* Compute all LR(0) states for the grammar. Links -** are added to between some states so that the LR(1) follow sets -** can be computed later. -*/ -PRIVATE struct state *getstate(/* struct lemon * */); /* forward reference */ -void FindStates(lemp) -struct lemon *lemp; -{ - struct symbol *sp; - struct rule *rp; - - Configlist_init(); - - /* Find the start symbol */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ){ - ErrorMsg(lemp->filename,0, -"The specified start symbol \"%s\" is not \ -in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); - lemp->errorcnt++; - sp = lemp->rule->lhs; - } - }else{ - sp = lemp->rule->lhs; - } - - /* Make sure the start symbol doesn't occur on the right-hand side of - ** any rule. Report an error if it does. (YACC would generate a new - ** start symbol in this case.) */ - for(rp=lemp->rule; rp; rp=rp->next){ - int i; - for(i=0; inrhs; i++){ - if( rp->rhs[i]==sp ){ - ErrorMsg(lemp->filename,0, -"The start symbol \"%s\" occurs on the \ -right-hand side of a rule. This will result in a parser which \ -does not work properly.",sp->name); - lemp->errorcnt++; - } - } - } - - /* The basis configuration set for the first state - ** is all rules which have the start symbol as their - ** left-hand side */ - for(rp=sp->rule; rp; rp=rp->nextlhs){ - struct config *newcfp; - newcfp = Configlist_addbasis(rp,0); - SetAdd(newcfp->fws,0); - } - - /* Compute the first state. All other states will be - ** computed automatically during the computation of the first one. - ** The returned pointer to the first state is not used. */ - (void)getstate(lemp); - return; -} - -/* Return a pointer to a state which is described by the configuration -** list which has been built from calls to Configlist_add. -*/ -PRIVATE void buildshifts(/* struct lemon *, struct state * */); /* Forwd ref */ -PRIVATE struct state *getstate(lemp) -struct lemon *lemp; -{ - struct config *cfp, *bp; - struct state *stp; - - /* Extract the sorted basis of the new state. The basis was constructed - ** by prior calls to "Configlist_addbasis()". */ - Configlist_sortbasis(); - bp = Configlist_basis(); - - /* Get a state with the same basis */ - stp = State_find(bp); - if( stp ){ - /* A state with the same basis already exists! Copy all the follow-set - ** propagation links from the state under construction into the - ** preexisting state, then return a pointer to the preexisting state */ - struct config *x, *y; - for(x=bp, y=stp->bp; x && y; x=x->bp, y=y->bp){ - Plink_copy(&y->bplp,x->bplp); - Plink_delete(x->fplp); - x->fplp = x->bplp = 0; - } - cfp = Configlist_return(); - Configlist_eat(cfp); - }else{ - /* This really is a new state. Construct all the details */ - Configlist_closure(lemp); /* Compute the configuration closure */ - Configlist_sort(); /* Sort the configuration closure */ - cfp = Configlist_return(); /* Get a pointer to the config list */ - stp = State_new(); /* A new state structure */ - MemoryCheck(stp); - stp->bp = bp; /* Remember the configuration basis */ - stp->cfp = cfp; /* Remember the configuration closure */ - stp->index = lemp->nstate++; /* Every state gets a sequence number */ - stp->ap = 0; /* No actions, yet. */ - State_insert(stp,stp->bp); /* Add to the state table */ - buildshifts(lemp,stp); /* Recursively compute successor states */ - } - return stp; -} - -/* Construct all successor states to the given state. A "successor" -** state is any state which can be reached by a shift action. -*/ -PRIVATE void buildshifts(lemp,stp) -struct lemon *lemp; -struct state *stp; /* The state from which successors are computed */ -{ - struct config *cfp; /* For looping thru the config closure of "stp" */ - struct config *bcfp; /* For the inner loop on config closure of "stp" */ - struct config *new; /* */ - struct symbol *sp; /* Symbol following the dot in configuration "cfp" */ - struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ - struct state *newstp; /* A pointer to a successor state */ - - /* Each configuration becomes complete after it contibutes to a successor - ** state. Initially, all configurations are incomplete */ - for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; - - /* Loop through all configurations of the state "stp" */ - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; /* Already used by inner loop */ - if( cfp->dot>=cfp->rp->nrhs ) continue; /* Can't shift this config */ - Configlist_reset(); /* Reset the new config set */ - sp = cfp->rp->rhs[cfp->dot]; /* Symbol after the dot */ - - /* For every configuration in the state "stp" which has the symbol "sp" - ** following its dot, add the same configuration to the basis set under - ** construction but with the dot shifted one symbol to the right. */ - for(bcfp=cfp; bcfp; bcfp=bcfp->next){ - if( bcfp->status==COMPLETE ) continue; /* Already used */ - if( bcfp->dot>=bcfp->rp->nrhs ) continue; /* Can't shift this one */ - bsp = bcfp->rp->rhs[bcfp->dot]; /* Get symbol after dot */ - if( bsp!=sp ) continue; /* Must be same as for "cfp" */ - bcfp->status = COMPLETE; /* Mark this config as used */ - new = Configlist_addbasis(bcfp->rp,bcfp->dot+1); - Plink_add(&new->bplp,bcfp); - } - - /* Get a pointer to the state described by the basis configuration set - ** constructed in the preceding loop */ - newstp = getstate(lemp); - - /* The state "newstp" is reached from the state "stp" by a shift action - ** on the symbol "sp" */ - Action_add(&stp->ap,SHIFT,sp,(char *)newstp); - } -} - -/* -** Construct the propagation links -*/ -void FindLinks(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp, *other; - struct state *stp; - struct plink *plp; - - /* Housekeeping detail: - ** Add to every propagate link a pointer back to the state to - ** which the link is attached. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - cfp->stp = stp; - } - } - - /* Convert all backlinks into forward links. Only the forward - ** links are used in the follow-set computation. */ - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ - for(plp=cfp->bplp; plp; plp=plp->next){ - other = plp->cfp; - Plink_add(&other->fplp,cfp); - } - } - } -} - -/* Compute all followsets. -** -** A followset is the set of all symbols which can come immediately -** after a configuration. -*/ -void FindFollowSets(lemp) -struct lemon *lemp; -{ - int i; - struct config *cfp; - struct plink *plp; - int progress; - int change; - - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - cfp->status = INCOMPLETE; - } - } - - do{ - progress = 0; - for(i=0; instate; i++){ - for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ - if( cfp->status==COMPLETE ) continue; - for(plp=cfp->fplp; plp; plp=plp->next){ - change = SetUnion(plp->cfp->fws,cfp->fws); - if( change ){ - plp->cfp->status = INCOMPLETE; - progress = 1; - } - } - cfp->status = COMPLETE; - } - } - }while( progress ); -} - -static int resolve_conflict(); - -/* Compute the reduce actions, and resolve conflicts. -*/ -void FindActions(lemp) -struct lemon *lemp; -{ - int i,j; - struct config *cfp; - struct state *stp; - struct symbol *sp; - struct rule *rp; - - /* Add all of the reduce actions - ** A reduce action is added for each element of the followset of - ** a configuration which has its dot at the extreme right. - */ - for(i=0; instate; i++){ /* Loop over all states */ - stp = lemp->sorted[i]; - for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ - if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ - for(j=0; jnterminal; j++){ - if( SetFind(cfp->fws,j) ){ - /* Add a reduce action to the state "stp" which will reduce by the - ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ - Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); - } - } - } - } - } - - /* Add the accepting token */ - if( lemp->start ){ - sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; - }else{ - sp = lemp->rule->lhs; - } - /* Add to the first state (which is always the starting state of the - ** finite state machine) an action to ACCEPT if the lookahead is the - ** start nonterminal. */ - Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); - - /* Resolve conflicts */ - for(i=0; instate; i++){ - struct action *ap, *nap; - struct state *stp; - stp = lemp->sorted[i]; - assert( stp->ap ); - stp->ap = Action_sort(stp->ap); - for(ap=stp->ap; ap && ap->next; ap=ap->next){ - for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ - /* The two actions "ap" and "nap" have the same lookahead. - ** Figure out which one should be used */ - lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); - } - } - } - - /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE; - for(i=0; instate; i++){ - struct action *ap; - for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE; - } - } - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->canReduce ) continue; - ErrorMsg(lemp->filename,rp->ruleline,"This rule can not be reduced.\n"); - lemp->errorcnt++; - } -} - -/* Resolve a conflict between the two given actions. If the -** conflict can't be resolve, return non-zero. -** -** NO LONGER TRUE: -** To resolve a conflict, first look to see if either action -** is on an error rule. In that case, take the action which -** is not associated with the error rule. If neither or both -** actions are associated with an error rule, then try to -** use precedence to resolve the conflict. -** -** If either action is a SHIFT, then it must be apx. This -** function won't work if apx->type==REDUCE and apy->type==SHIFT. -*/ -static int resolve_conflict(apx,apy,errsym) -struct action *apx; -struct action *apy; -struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ -{ - struct symbol *spx, *spy; - int errcnt = 0; - assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ - if( apx->type==SHIFT && apy->type==REDUCE ){ - spx = apx->sp; - spy = apy->x.rp->precsym; - if( spy==0 || spx->prec<0 || spy->prec<0 ){ - /* Not enough precedence information. */ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = SH_RESOLVED; - }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ - apy->type = RD_RESOLVED; /* associativity */ - }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ - apx->type = SH_RESOLVED; - }else{ - assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = CONFLICT; - errcnt++; - } - }else if( apx->type==REDUCE && apy->type==REDUCE ){ - spx = apx->x.rp->precsym; - spy = apy->x.rp->precsym; - if( spx==0 || spy==0 || spx->prec<0 || - spy->prec<0 || spx->prec==spy->prec ){ - apy->type = CONFLICT; - errcnt++; - }else if( spx->prec>spy->prec ){ - apy->type = RD_RESOLVED; - }else if( spx->precprec ){ - apx->type = RD_RESOLVED; - } - }else{ - assert( - apx->type==SH_RESOLVED || - apx->type==RD_RESOLVED || - apx->type==CONFLICT || - apy->type==SH_RESOLVED || - apy->type==RD_RESOLVED || - apy->type==CONFLICT - ); - /* The REDUCE/SHIFT case cannot happen because SHIFTs come before - ** REDUCEs on the list. If we reach this point it must be because - ** the parser conflict had already been resolved. */ - } - return errcnt; -} -/********************* From the file "configlist.c" *************************/ -/* -** Routines to processing a configuration list and building a state -** in the LEMON parser generator. -*/ - -static struct config *freelist = 0; /* List of free configurations */ -static struct config *current = 0; /* Top of list of configurations */ -static struct config **currentend = 0; /* Last on list of configs */ -static struct config *basis = 0; /* Top of list of basis configs */ -static struct config **basisend = 0; /* End of list of basis configs */ - -/* Return a pointer to a new configuration */ -PRIVATE struct config *newconfig(){ - struct config *new; - if( freelist==0 ){ - int i; - int amt = 3; - freelist = (struct config *)malloc( sizeof(struct config)*amt ); - if( freelist==0 ){ - fprintf(stderr,"Unable to allocate memory for a new configuration."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* The configuration "old" is no longer used */ -PRIVATE void deleteconfig(old) -struct config *old; -{ - old->next = freelist; - freelist = old; -} - -/* Initialized the configuration list builder */ -void Configlist_init(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_init(); - return; -} - -/* Initialized the configuration list builder */ -void Configlist_reset(){ - current = 0; - currentend = ¤t; - basis = 0; - basisend = &basis; - Configtable_clear(0); - return; -} - -/* Add another configuration to the configuration list */ -struct config *Configlist_add(rp,dot) -struct rule *rp; /* The rule */ -int dot; /* Index into the RHS of the rule where the dot goes */ -{ - struct config *cfp, model; - - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - Configtable_insert(cfp); - } - return cfp; -} - -/* Add a basis configuration to the configuration list */ -struct config *Configlist_addbasis(rp,dot) -struct rule *rp; -int dot; -{ - struct config *cfp, model; - - assert( basisend!=0 ); - assert( currentend!=0 ); - model.rp = rp; - model.dot = dot; - cfp = Configtable_find(&model); - if( cfp==0 ){ - cfp = newconfig(); - cfp->rp = rp; - cfp->dot = dot; - cfp->fws = SetNew(); - cfp->stp = 0; - cfp->fplp = cfp->bplp = 0; - cfp->next = 0; - cfp->bp = 0; - *currentend = cfp; - currentend = &cfp->next; - *basisend = cfp; - basisend = &cfp->bp; - Configtable_insert(cfp); - } - return cfp; -} - -/* Compute the closure of the configuration list */ -void Configlist_closure(lemp) -struct lemon *lemp; -{ - struct config *cfp, *newcfp; - struct rule *rp, *newrp; - struct symbol *sp, *xsp; - int i, dot; - - assert( currentend!=0 ); - for(cfp=current; cfp; cfp=cfp->next){ - rp = cfp->rp; - dot = cfp->dot; - if( dot>=rp->nrhs ) continue; - sp = rp->rhs[dot]; - if( sp->type==NONTERMINAL ){ - if( sp->rule==0 && sp!=lemp->errsym ){ - ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.", - sp->name); - lemp->errorcnt++; - } - for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){ - newcfp = Configlist_add(newrp,0); - for(i=dot+1; inrhs; i++){ - xsp = rp->rhs[i]; - if( xsp->type==TERMINAL ){ - SetAdd(newcfp->fws,xsp->index); - break; - }else{ - SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==B_FALSE ) break; - } - } - if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); - } - } - } - return; -} - -/* Sort the configuration list */ -void Configlist_sort(){ - current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp); - currentend = 0; - return; -} - -/* Sort the basis configuration list */ -void Configlist_sortbasis(){ - basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp); - basisend = 0; - return; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_return(){ - struct config *old; - old = current; - current = 0; - currentend = 0; - return old; -} - -/* Return a pointer to the head of the configuration list and -** reset the list */ -struct config *Configlist_basis(){ - struct config *old; - old = basis; - basis = 0; - basisend = 0; - return old; -} - -/* Free all elements of the given configuration list */ -void Configlist_eat(cfp) -struct config *cfp; -{ - struct config *nextcfp; - for(; cfp; cfp=nextcfp){ - nextcfp = cfp->next; - assert( cfp->fplp==0 ); - assert( cfp->bplp==0 ); - if( cfp->fws ) SetFree(cfp->fws); - deleteconfig(cfp); - } - return; -} -/***************** From the file "error.c" *********************************/ -/* -** Code for printing error message. -*/ - -/* Find a good place to break "msg" so that its length is at least "min" -** but no more than "max". Make the point as close to max as possible. -*/ -static int findbreak(msg,min,max) -char *msg; -int min; -int max; -{ - int i,spot; - char c; - for(i=spot=min; i<=max; i++){ - c = msg[i]; - if( c=='\t' ) msg[i] = ' '; - if( c=='\n' ){ msg[i] = ' '; spot = i; break; } - if( c==0 ){ spot = i; break; } - if( c=='-' && i0 ){ - sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno); - }else{ - sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename); - } - prefixsize = strlen(prefix); - availablewidth = LINEWIDTH - prefixsize; - - /* Generate the error message */ - vsprintf(errmsg,format,ap); - va_end(ap); - errmsgsize = strlen(errmsg); - /* Remove trailing '\n's from the error message. */ - while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){ - errmsg[--errmsgsize] = 0; - } - - /* Print the error message */ - base = 0; - while( errmsg[base]!=0 ){ - end = restart = findbreak(&errmsg[base],0,availablewidth); - restart += base; - while( errmsg[restart]==' ' ) restart++; - fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]); - base = restart; - } -} -/**************** From the file "main.c" ************************************/ -/* -** Main program file for the LEMON parser generator. -*/ - -/* Report an out-of-memory condition and abort. This function -** is used mostly by the "MemoryCheck" macro in struct.h -*/ -void memory_error(){ - fprintf(stderr,"Out of memory. Aborting...\n"); - exit(1); -} - -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ - -/* This routine is called with the argument to each -D command-line option. -** Add the macro defined to the azDefine array. -*/ -static void handle_D_option(char *z){ - char **paz; - nDefine++; - azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine); - if( azDefine==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - paz = &azDefine[nDefine-1]; - *paz = malloc( strlen(z)+1 ); - if( *paz==0 ){ - fprintf(stderr,"out of memory\n"); - exit(1); - } - strcpy(*paz, z); - for(z=*paz; *z && *z!='='; z++){} - *z = 0; -} - - -/* The main program. Parse the command line and do it... */ -int main(argc,argv) -int argc; -char **argv; -{ - static int version = 0; - static int rpflag = 0; - static int basisflag = 0; - static int compress = 0; - static int quiet = 0; - static int statistics = 0; - static int mhflag = 0; - static struct s_options options[] = { - {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."}, - {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."}, - {OPT_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."}, - {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."}, - {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"}, - {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."}, - {OPT_FLAG, "s", (char*)&statistics, - "Print parser stats to standard output."}, - {OPT_FLAG, "x", (char*)&version, "Print the version number."}, - {OPT_FLAG,0,0,0} - }; - int i; - struct lemon lem; - - OptInit(argv,options,stderr); - if( version ){ - printf("Lemon version 1.0\n"); - exit(0); - } - if( OptNArgs()!=1 ){ - fprintf(stderr,"Exactly one filename argument is required.\n"); - exit(1); - } - lem.errorcnt = 0; - - /* Initialize the machine */ - Strsafe_init(); - Symbol_init(); - State_init(); - lem.argv0 = argv[0]; - lem.filename = OptArg(0); - lem.basisflag = basisflag; - lem.has_fallback = 0; - lem.nconflict = 0; - lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0; - lem.vartype = 0; - lem.stacksize = 0; - lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest = - lem.tokenprefix = lem.outname = lem.extracode = 0; - lem.vardest = 0; - lem.tablesize = 0; - Symbol_new("$"); - lem.errsym = Symbol_new("error"); - - /* Parse the input file */ - Parse(&lem); - if( lem.errorcnt ) exit(lem.errorcnt); - if( lem.rule==0 ){ - fprintf(stderr,"Empty grammar.\n"); - exit(1); - } - - /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); - Symbol_new("{default}"); - lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), - (int(*)())Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); - lem.nterminal = i; - - /* Generate a reprint of the grammar, if requested on the command line */ - if( rpflag ){ - Reprint(&lem); - }else{ - /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal); - - /* Find the precedence for every production rule (that has one) */ - FindRulePrecedences(&lem); - - /* Compute the lambda-nonterminals and the first-sets for every - ** nonterminal */ - FindFirstSets(&lem); - - /* Compute all LR(0) states. Also record follow-set propagation - ** links so that the follow-set can be computed later */ - lem.nstate = 0; - FindStates(&lem); - lem.sorted = State_arrayof(); - - /* Tie up loose ends on the propagation links */ - FindLinks(&lem); - - /* Compute the follow set of every reducible configuration */ - FindFollowSets(&lem); - - /* Compute the action tables */ - FindActions(&lem); - - /* Compress the action tables */ - if( compress==0 ) CompressTables(&lem); - - /* Generate a report of the parser generated. (the "y.output" file) */ - if( !quiet ) ReportOutput(&lem); - - /* Generate the source code for the parser */ - ReportTable(&lem, mhflag); - - /* Produce a header file for use by the scanner. (This step is - ** omitted if the "-m" option is used because makeheaders will - ** generate the file for us.) */ - if( !mhflag ) ReportHeader(&lem); - } - if( statistics ){ - printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", - lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); - printf(" %d states, %d parser table entries, %d conflicts\n", - lem.nstate, lem.tablesize, lem.nconflict); - } - if( lem.nconflict ){ - fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); - } - exit(lem.errorcnt + lem.nconflict); - return (lem.errorcnt + lem.nconflict); -} -/******************** From the file "msort.c" *******************************/ -/* -** A generic merge-sort program. -** -** USAGE: -** Let "ptr" be a pointer to some structure which is at the head of -** a null-terminated list. Then to sort the list call: -** -** ptr = msort(ptr,&(ptr->next),cmpfnc); -** -** In the above, "cmpfnc" is a pointer to a function which compares -** two instances of the structure and returns an integer, as in -** strcmp. The second argument is a pointer to the pointer to the -** second element of the linked list. This address is used to compute -** the offset to the "next" field within the structure. The offset to -** the "next" field must be constant for all structures in the list. -** -** The function returns a new pointer which is the head of the list -** after sorting. -** -** ALGORITHM: -** Merge-sort. -*/ - -/* -** Return a pointer to the next structure in the linked list. -*/ -#define NEXT(A) (*(char**)(((unsigned long)A)+offset)) - -/* -** Inputs: -** a: A sorted, null-terminated linked list. (May be null). -** b: A sorted, null-terminated linked list. (May be null). -** cmp: A pointer to the comparison function. -** offset: Offset in the structure to the "next" field. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** of both a and b. -** -** Side effects: -** The "next" pointers for elements in the lists a and b are -** changed. -*/ -static char *merge(a,b,cmp,offset) -char *a; -char *b; -int (*cmp)(); -int offset; -{ - char *ptr, *head; - - if( a==0 ){ - head = b; - }else if( b==0 ){ - head = a; - }else{ - if( (*cmp)(a,b)<0 ){ - ptr = a; - a = NEXT(a); - }else{ - ptr = b; - b = NEXT(b); - } - head = ptr; - while( a && b ){ - if( (*cmp)(a,b)<0 ){ - NEXT(ptr) = a; - ptr = a; - a = NEXT(a); - }else{ - NEXT(ptr) = b; - ptr = b; - b = NEXT(b); - } - } - if( a ) NEXT(ptr) = a; - else NEXT(ptr) = b; - } - return head; -} - -/* -** Inputs: -** list: Pointer to a singly-linked list of structures. -** next: Pointer to pointer to the second element of the list. -** cmp: A comparison function. -** -** Return Value: -** A pointer to the head of a sorted list containing the elements -** orginally in list. -** -** Side effects: -** The "next" pointers for elements in list are changed. -*/ -#define LISTSIZE 30 -char *msort(list,next,cmp) -char *list; -char **next; -int (*cmp)(); -{ - unsigned long offset; - char *ep; - char *set[LISTSIZE]; - int i; - offset = (unsigned long)next - (unsigned long)list; - for(i=0; istate = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ - psp->lhs = Symbol_new(x); - psp->nrhs = 0; - psp->lhsalias = 0; - psp->state = WAITING_FOR_ARROW; - }else if( x[0]=='{' ){ - if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"There is not prior rule opon which to attach the code \ -fragment which begins on this line."); - psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Code fragment beginning on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->line = psp->tokenlineno; - psp->prevrule->code = &x[1]; - } - }else if( x[0]=='[' ){ - psp->state = PRECEDENCE_MARK_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Token \"%s\" should be either \"%%\" or a nonterminal name.", - x); - psp->errorcnt++; - } - break; - case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The precedence symbol must be a terminal."); - psp->errorcnt++; - }else if( psp->prevrule==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "There is no prior rule to assign precedence \"[%s]\".",x); - psp->errorcnt++; - }else if( psp->prevrule->precsym!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, -"Precedence mark on this line is not the first \ -to follow the previous rule."); - psp->errorcnt++; - }else{ - psp->prevrule->precsym = Symbol_new(x); - } - psp->state = PRECEDENCE_MARK_2; - break; - case PRECEDENCE_MARK_2: - if( x[0]!=']' ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"]\" on precedence mark."); - psp->errorcnt++; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - break; - case WAITING_FOR_ARROW: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else if( x[0]=='(' ){ - psp->state = LHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Expected to see a \":\" following the LHS symbol \"%s\".", - psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->lhsalias = x; - psp->state = LHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the LHS \"%s\"\n", - x,psp->lhs->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = LHS_ALIAS_3; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case LHS_ALIAS_3: - if( x[0]==':' && x[1]==':' && x[2]=='=' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \"->\" following: \"%s(%s)\".", - psp->lhs->name,psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case IN_RHS: - if( x[0]=='.' ){ - struct rule *rp; - rp = (struct rule *)malloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); - if( rp==0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't allocate enough memory for this rule."); - psp->errorcnt++; - psp->prevrule = 0; - }else{ - int i; - rp->ruleline = psp->tokenlineno; - rp->rhs = (struct symbol**)&rp[1]; - rp->rhsalias = (char**)&(rp->rhs[psp->nrhs]); - for(i=0; inrhs; i++){ - rp->rhs[i] = psp->rhs[i]; - rp->rhsalias[i] = psp->alias[i]; - } - rp->lhs = psp->lhs; - rp->lhsalias = psp->lhsalias; - rp->nrhs = psp->nrhs; - rp->code = 0; - rp->precsym = 0; - rp->index = psp->gp->nrule++; - rp->nextlhs = rp->lhs->rule; - rp->lhs->rule = rp; - rp->next = 0; - if( psp->firstrule==0 ){ - psp->firstrule = psp->lastrule = rp; - }else{ - psp->lastrule->next = rp; - psp->lastrule = rp; - } - psp->prevrule = rp; - } - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ - if( psp->nrhs>=MAXRHS ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbol on RHS or rule beginning at \"%s\".", - x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - }else{ - psp->rhs[psp->nrhs] = Symbol_new(x); - psp->alias[psp->nrhs] = 0; - psp->nrhs++; - } - }else if( x[0]=='(' && psp->nrhs>0 ){ - psp->state = RHS_ALIAS_1; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal character on RHS of rule: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_1: - if( isalpha(x[0]) ){ - psp->alias[psp->nrhs-1] = x; - psp->state = RHS_ALIAS_2; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "\"%s\" is not a valid alias for the RHS symbol \"%s\"\n", - x,psp->rhs[psp->nrhs-1]->name); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case RHS_ALIAS_2: - if( x[0]==')' ){ - psp->state = IN_RHS; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Missing \")\" following LHS alias name \"%s\".",psp->lhsalias); - psp->errorcnt++; - psp->state = RESYNC_AFTER_RULE_ERROR; - } - break; - case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ - psp->declkeyword = x; - psp->declargslot = 0; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - if( strcmp(x,"name")==0 ){ - psp->declargslot = &(psp->gp->name); - }else if( strcmp(x,"include")==0 ){ - psp->declargslot = &(psp->gp->include); - psp->decllnslot = &psp->gp->includeln; - }else if( strcmp(x,"code")==0 ){ - psp->declargslot = &(psp->gp->extracode); - psp->decllnslot = &psp->gp->extracodeln; - }else if( strcmp(x,"token_destructor")==0 ){ - psp->declargslot = &psp->gp->tokendest; - psp->decllnslot = &psp->gp->tokendestln; - }else if( strcmp(x,"default_destructor")==0 ){ - psp->declargslot = &psp->gp->vardest; - psp->decllnslot = &psp->gp->vardestln; - }else if( strcmp(x,"token_prefix")==0 ){ - psp->declargslot = &psp->gp->tokenprefix; - }else if( strcmp(x,"syntax_error")==0 ){ - psp->declargslot = &(psp->gp->error); - psp->decllnslot = &psp->gp->errorln; - }else if( strcmp(x,"parse_accept")==0 ){ - psp->declargslot = &(psp->gp->accept); - psp->decllnslot = &psp->gp->acceptln; - }else if( strcmp(x,"parse_failure")==0 ){ - psp->declargslot = &(psp->gp->failure); - psp->decllnslot = &psp->gp->failureln; - }else if( strcmp(x,"stack_overflow")==0 ){ - psp->declargslot = &(psp->gp->overflow); - psp->decllnslot = &psp->gp->overflowln; - }else if( strcmp(x,"extra_argument")==0 ){ - psp->declargslot = &(psp->gp->arg); - }else if( strcmp(x,"token_type")==0 ){ - psp->declargslot = &(psp->gp->tokentype); - }else if( strcmp(x,"default_type")==0 ){ - psp->declargslot = &(psp->gp->vartype); - }else if( strcmp(x,"stack_size")==0 ){ - psp->declargslot = &(psp->gp->stacksize); - }else if( strcmp(x,"start_symbol")==0 ){ - psp->declargslot = &(psp->gp->start); - }else if( strcmp(x,"left")==0 ){ - psp->preccounter++; - psp->declassoc = LEFT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"right")==0 ){ - psp->preccounter++; - psp->declassoc = RIGHT; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"nonassoc")==0 ){ - psp->preccounter++; - psp->declassoc = NONE; - psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; - }else if( strcmp(x,"destructor")==0 ){ - psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; - }else if( strcmp(x,"type")==0 ){ - psp->state = WAITING_FOR_DATATYPE_SYMBOL; - }else if( strcmp(x,"fallback")==0 ){ - psp->fallback = 0; - psp->state = WAITING_FOR_FALLBACK_ID; - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Unknown declaration keyword: \"%%%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal declaration keyword: \"%s\".",x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->destructor; - psp->decllnslot = &sp->destructorln; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol name missing after %destructor keyword"); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - struct symbol *sp = Symbol_new(x); - psp->declargslot = &sp->datatype; - psp->decllnslot = 0; - psp->state = WAITING_FOR_DECL_ARG; - } - break; - case WAITING_FOR_PRECEDENCE_SYMBOL: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ - struct symbol *sp; - sp = Symbol_new(x); - if( sp->prec>=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "Symbol \"%s\" has already be given a precedence.",x); - psp->errorcnt++; - }else{ - sp->prec = psp->preccounter; - sp->assoc = psp->declassoc; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Can't assign a precedence to \"%s\".",x); - psp->errorcnt++; - } - break; - case WAITING_FOR_DECL_ARG: - if( (x[0]=='{' || x[0]=='\"' || isalnum(x[0])) ){ - if( *(psp->declargslot)!=0 ){ - ErrorMsg(psp->filename,psp->tokenlineno, - "The argument \"%s\" to declaration \"%%%s\" is not the first.", - x[0]=='\"' ? &x[1] : x,psp->declkeyword); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - }else{ - *(psp->declargslot) = (x[0]=='\"' || x[0]=='{') ? &x[1] : x; - if( psp->decllnslot ) *psp->decllnslot = psp->tokenlineno; - psp->state = WAITING_FOR_DECL_OR_RULE; - } - }else{ - ErrorMsg(psp->filename,psp->tokenlineno, - "Illegal argument to %%%s: %s",psp->declkeyword,x); - psp->errorcnt++; - psp->state = RESYNC_AFTER_DECL_ERROR; - } - break; - case WAITING_FOR_FALLBACK_ID: - if( x[0]=='.' ){ - psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "%%fallback argument \"%s\" should be a token", x); - psp->errorcnt++; - }else{ - struct symbol *sp = Symbol_new(x); - if( psp->fallback==0 ){ - psp->fallback = sp; - }else if( sp->fallback ){ - ErrorMsg(psp->filename, psp->tokenlineno, - "More than one fallback assigned to token %s", x); - psp->errorcnt++; - }else{ - sp->fallback = psp->fallback; - psp->gp->has_fallback = 1; - } - } - break; - case RESYNC_AFTER_RULE_ERROR: -/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; -** break; */ - case RESYNC_AFTER_DECL_ERROR: - if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; - if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; - break; - } -} - -/* Run the proprocessor over the input file text. The global variables -** azDefine[0] through azDefine[nDefine-1] contains the names of all defined -** macros. This routine looks for "%ifdef" and "%ifndef" and "%endif" and -** comments them out. Text in between is also commented out as appropriate. -*/ -static preprocess_input(char *z){ - int i, j, k, n; - int exclude = 0; - int start; - int lineno = 1; - int start_lineno; - for(i=0; z[i]; i++){ - if( z[i]=='\n' ) lineno++; - if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ - if( exclude ){ - exclude--; - if( exclude==0 ){ - for(j=start; jfilename; - ps.errorcnt = 0; - ps.state = INITIALIZE; - - /* Begin by reading the input file */ - fp = fopen(ps.filename,"rb"); - if( fp==0 ){ - ErrorMsg(ps.filename,0,"Can't open this file for reading."); - gp->errorcnt++; - return; - } - fseek(fp,0,2); - filesize = ftell(fp); - rewind(fp); - filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); - gp->errorcnt++; - return; - } - if( fread(filebuf,1,filesize,fp)!=filesize ){ - ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", - filesize); - free(filebuf); - gp->errorcnt++; - return; - } - fclose(fp); - filebuf[filesize] = 0; - - /* Make an initial pass through the file to handle %ifdef and %ifndef */ - preprocess_input(filebuf); - - /* Now scan the text of the input file */ - lineno = 1; - for(cp=filebuf; (c= *cp)!=0; ){ - if( c=='\n' ) lineno++; /* Keep track of the line number */ - if( isspace(c) ){ cp++; continue; } /* Skip all white space */ - if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments */ - cp+=2; - while( (c= *cp)!=0 && c!='\n' ) cp++; - continue; - } - if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ - cp+=2; - while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c ) cp++; - continue; - } - ps.tokenstart = cp; /* Mark the beginning of the token */ - ps.tokenlineno = lineno; /* Linenumber on which token begins */ - if( c=='\"' ){ /* String literals */ - cp++; - while( (c= *cp)!=0 && c!='\"' ){ - if( c=='\n' ) lineno++; - cp++; - } - if( c==0 ){ - ErrorMsg(ps.filename,startline, -"String starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( c=='{' ){ /* A block of C code */ - int level; - cp++; - for(level=1; (c= *cp)!=0 && (level>1 || c!='}'); cp++){ - if( c=='\n' ) lineno++; - else if( c=='{' ) level++; - else if( c=='}' ) level--; - else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ - int prevc; - cp = &cp[2]; - prevc = 0; - while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ - if( c=='\n' ) lineno++; - prevc = c; - cp++; - } - }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ - cp = &cp[2]; - while( (c= *cp)!=0 && c!='\n' ) cp++; - if( c ) lineno++; - }else if( c=='\'' || c=='\"' ){ /* String a character literals */ - int startchar, prevc; - startchar = c; - prevc = 0; - for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ - if( c=='\n' ) lineno++; - if( prevc=='\\' ) prevc = 0; - else prevc = c; - } - } - } - if( c==0 ){ - ErrorMsg(ps.filename,ps.tokenlineno, -"C code starting on this line is not terminated before the end of the file."); - ps.errorcnt++; - nextcp = cp; - }else{ - nextcp = cp+1; - } - }else if( isalnum(c) ){ /* Identifiers */ - while( (c= *cp)!=0 && (isalnum(c) || c=='_') ) cp++; - nextcp = cp; - }else if( c==':' && cp[1]==':' && cp[2]=='=' ){ /* The operator "::=" */ - cp += 3; - nextcp = cp; - }else{ /* All other (one character) operators */ - cp++; - nextcp = cp; - } - c = *cp; - *cp = 0; /* Null terminate the token */ - parseonetoken(&ps); /* Parse the token */ - *cp = c; /* Restore the buffer */ - cp = nextcp; - } - free(filebuf); /* Release the buffer after parsing */ - gp->rule = ps.firstrule; - gp->errorcnt = ps.errorcnt; -} -/*************************** From the file "plink.c" *********************/ -/* -** Routines processing configuration follow-set propagation links -** in the LEMON parser generator. -*/ -static struct plink *plink_freelist = 0; - -/* Allocate a new plink */ -struct plink *Plink_new(){ - struct plink *new; - - if( plink_freelist==0 ){ - int i; - int amt = 100; - plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt ); - if( plink_freelist==0 ){ - fprintf(stderr, - "Unable to allocate memory for a new follow-set propagation link.\n"); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Add a plink to a plink list */ -void Plink_add(plpp,cfp) -struct plink **plpp; -struct config *cfp; -{ - struct plink *new; - new = Plink_new(); - new->next = *plpp; - *plpp = new; - new->cfp = cfp; -} - -/* Transfer every plink on the list "from" to the list "to" */ -void Plink_copy(to,from) -struct plink **to; -struct plink *from; -{ - struct plink *nextpl; - while( from ){ - nextpl = from->next; - from->next = *to; - *to = from; - from = nextpl; - } -} - -/* Delete every plink on the list */ -void Plink_delete(plp) -struct plink *plp; -{ - struct plink *nextpl; - - while( plp ){ - nextpl = plp->next; - plp->next = plink_freelist; - plink_freelist = plp; - plp = nextpl; - } -} -/*********************** From the file "report.c" **************************/ -/* -** Procedures for generating reports and tables in the LEMON parser generator. -*/ - -/* Generate a filename with the given suffix. Space to hold the -** name comes from malloc() and must be freed by the calling -** function. -*/ -PRIVATE char *file_makename(lemp,suffix) -struct lemon *lemp; -char *suffix; -{ - char *name; - char *cp; - - name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 ); - if( name==0 ){ - fprintf(stderr,"Can't allocate space for a filename.\n"); - exit(1); - } - strcpy(name,lemp->filename); - cp = strrchr(name,'.'); - if( cp ) *cp = 0; - strcat(name,suffix); - return name; -} - -/* Open a file with a name based on the name of the input file, -** but with a different (specified) suffix, and return a pointer -** to the stream */ -PRIVATE FILE *file_open(lemp,suffix,mode) -struct lemon *lemp; -char *suffix; -char *mode; -{ - FILE *fp; - - if( lemp->outname ) free(lemp->outname); - lemp->outname = file_makename(lemp, suffix); - fp = fopen(lemp->outname,mode); - if( fp==0 && *mode=='w' ){ - fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); - lemp->errorcnt++; - return 0; - } - return fp; -} - -/* Duplicate the input file without comments and without actions -** on rules */ -void Reprint(lemp) -struct lemon *lemp; -{ - struct rule *rp; - struct symbol *sp; - int i, j, maxlen, len, ncolumns, skip; - printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename); - maxlen = 10; - for(i=0; insymbol; i++){ - sp = lemp->symbols[i]; - len = strlen(sp->name); - if( len>maxlen ) maxlen = len; - } - ncolumns = 76/(maxlen+5); - if( ncolumns<1 ) ncolumns = 1; - skip = (lemp->nsymbol + ncolumns - 1)/ncolumns; - for(i=0; insymbol; j+=skip){ - sp = lemp->symbols[j]; - assert( sp->index==j ); - printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); - } - printf("\n"); - } - for(rp=lemp->rule; rp; rp=rp->next){ - printf("%s",rp->lhs->name); -/* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ - printf(" ::="); - for(i=0; inrhs; i++){ - printf(" %s",rp->rhs[i]->name); -/* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ - } - printf("."); - if( rp->precsym ) printf(" [%s]",rp->precsym->name); -/* if( rp->code ) printf("\n %s",rp->code); */ - printf("\n"); - } -} - -void ConfigPrint(fp,cfp) -FILE *fp; -struct config *cfp; -{ - struct rule *rp; - int i; - rp = cfp->rp; - fprintf(fp,"%s ::=",rp->lhs->name); - for(i=0; i<=rp->nrhs; i++){ - if( i==cfp->dot ) fprintf(fp," *"); - if( i==rp->nrhs ) break; - fprintf(fp," %s",rp->rhs[i]->name); - } -} - -/* #define TEST */ -#ifdef TEST -/* Print a set */ -PRIVATE void SetPrint(out,set,lemp) -FILE *out; -char *set; -struct lemon *lemp; -{ - int i; - char *spacer; - spacer = ""; - fprintf(out,"%12s[",""); - for(i=0; interminal; i++){ - if( SetFind(set,i) ){ - fprintf(out,"%s%s",spacer,lemp->symbols[i]->name); - spacer = " "; - } - } - fprintf(out,"]\n"); -} - -/* Print a plink chain */ -PRIVATE void PlinkPrint(out,plp,tag) -FILE *out; -struct plink *plp; -char *tag; -{ - while( plp ){ - fprintf(out,"%12s%s (state %2d) ","",tag,plp->cfp->stp->index); - ConfigPrint(out,plp->cfp); - fprintf(out,"\n"); - plp = plp->next; - } -} -#endif - -/* Print an action to the given file descriptor. Return FALSE if -** nothing was actually printed. -*/ -int PrintAction(struct action *ap, FILE *fp, int indent){ - int result = 1; - switch( ap->type ){ - case SHIFT: - fprintf(fp,"%*s shift %d",indent,ap->sp->name,ap->x.stp->index); - break; - case REDUCE: - fprintf(fp,"%*s reduce %d",indent,ap->sp->name,ap->x.rp->index); - break; - case ACCEPT: - fprintf(fp,"%*s accept",indent,ap->sp->name); - break; - case ERROR: - fprintf(fp,"%*s error",indent,ap->sp->name); - break; - case CONFLICT: - fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); - break; - case SH_RESOLVED: - case RD_RESOLVED: - case NOT_USED: - result = 0; - break; - } - return result; -} - -/* Generate the "y.output" log file */ -void ReportOutput(lemp) -struct lemon *lemp; -{ - int i; - struct state *stp; - struct config *cfp; - struct action *ap; - FILE *fp; - - fp = file_open(lemp,".out","wb"); - if( fp==0 ) return; - fprintf(fp," \b"); - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - fprintf(fp,"State %d:\n",stp->index); - if( lemp->basisflag ) cfp=stp->bp; - else cfp=stp->cfp; - while( cfp ){ - char buf[20]; - if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); - fprintf(fp," %5s ",buf); - }else{ - fprintf(fp," "); - } - ConfigPrint(fp,cfp); - fprintf(fp,"\n"); -#ifdef TEST - SetPrint(fp,cfp->fws,lemp); - PlinkPrint(fp,cfp->fplp,"To "); - PlinkPrint(fp,cfp->bplp,"From"); -#endif - if( lemp->basisflag ) cfp=cfp->bp; - else cfp=cfp->next; - } - fprintf(fp,"\n"); - for(ap=stp->ap; ap; ap=ap->next){ - if( PrintAction(ap,fp,30) ) fprintf(fp,"\n"); - } - fprintf(fp,"\n"); - } - fclose(fp); - return; -} - -/* Search for the file "name" which is in the same directory as -** the exacutable */ -PRIVATE char *pathsearch(argv0,name,modemask) -char *argv0; -char *name; -int modemask; -{ - char *pathlist; - char *path,*cp; - char c; - extern int access(); - -#ifdef __WIN32__ - cp = strrchr(argv0,'\\'); -#else - cp = strrchr(argv0,'/'); -#endif - if( cp ){ - c = *cp; - *cp = 0; - path = (char *)malloc( strlen(argv0) + strlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); - *cp = c; - }else{ - extern char *getenv(); - pathlist = getenv("PATH"); - if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; - path = (char *)malloc( strlen(pathlist)+strlen(name)+2 ); - if( path!=0 ){ - while( *pathlist ){ - cp = strchr(pathlist,':'); - if( cp==0 ) cp = &pathlist[strlen(pathlist)]; - c = *cp; - *cp = 0; - sprintf(path,"%s/%s",pathlist,name); - *cp = c; - if( c==0 ) pathlist = ""; - else pathlist = &cp[1]; - if( access(path,modemask)==0 ) break; - } - } - } - return path; -} - -/* Given an action, compute the integer value for that action -** which is to be put in the action table of the generated machine. -** Return negative if no action should be generated. -*/ -PRIVATE int compute_action(lemp,ap) -struct lemon *lemp; -struct action *ap; -{ - int act; - switch( ap->type ){ - case SHIFT: act = ap->x.stp->index; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate; break; - case ERROR: act = lemp->nstate + lemp->nrule; break; - case ACCEPT: act = lemp->nstate + lemp->nrule + 1; break; - default: act = -1; break; - } - return act; -} - -#define LINESIZE 1000 -/* The next cluster of routines are for reading the template file -** and writing the results to the generated parser */ -/* The first function transfers data from "in" to "out" until -** a line is seen which begins with "%%". The line number is -** tracked. -** -** if name!=0, then any word that begin with "Parse" is changed to -** begin with *name instead. -*/ -PRIVATE void tplt_xfer(name,in,out,lineno) -char *name; -FILE *in; -FILE *out; -int *lineno; -{ - int i, iStart; - char line[LINESIZE]; - while( fgets(line,LINESIZE,in) && (line[0]!='%' || line[1]!='%') ){ - (*lineno)++; - iStart = 0; - if( name ){ - for(i=0; line[i]; i++){ - if( line[i]=='P' && strncmp(&line[i],"Parse",5)==0 - && (i==0 || !isalpha(line[i-1])) - ){ - if( i>iStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); - fprintf(out,"%s",name); - i += 4; - iStart = i+1; - } - } - } - fprintf(out,"%s",&line[iStart]); - } -} - -/* The next function finds the template file and opens it, returning -** a pointer to the opened file. */ -PRIVATE FILE *tplt_open(lemp) -struct lemon *lemp; -{ - static char templatename[] = "lempar.c"; - char buf[1000]; - FILE *in; - char *tpltname; - char *cp; - - cp = strrchr(lemp->filename,'.'); - if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); - }else{ - sprintf(buf,"%s.lt",lemp->filename); - } - if( access(buf,004)==0 ){ - tpltname = buf; - }else if( access(templatename,004)==0 ){ - tpltname = templatename; - }else{ - tpltname = pathsearch(lemp->argv0,templatename,0); - } - if( tpltname==0 ){ - fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", - templatename); - lemp->errorcnt++; - return 0; - } - in = fopen(tpltname,"rb"); - if( in==0 ){ - fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - lemp->errorcnt++; - return 0; - } - return in; -} - -/* Print a #line directive line to the output file. */ -PRIVATE void tplt_linedir(out,lineno,filename) -FILE *out; -int lineno; -char *filename; -{ - fprintf(out,"#line %d \"",lineno); - while( *filename ){ - if( *filename == '\\' ) putc('\\',out); - putc(*filename,out); - filename++; - } - fprintf(out,"\"\n"); -} - -/* Print a string to the file and keep the linenumber up to date */ -PRIVATE void tplt_print(out,lemp,str,strln,lineno) -FILE *out; -struct lemon *lemp; -char *str; -int strln; -int *lineno; -{ - if( str==0 ) return; - tplt_linedir(out,strln,lemp->filename); - (*lineno)++; - while( *str ){ - if( *str=='\n' ) (*lineno)++; - putc(*str,out); - str++; - } - if( str[-1]!='\n' ){ - putc('\n',out); - (*lineno)++; - } - tplt_linedir(out,*lineno+2,lemp->outname); - (*lineno)+=2; - return; -} - -/* -** The following routine emits code for the destructor for the -** symbol sp -*/ -void emit_destructor_code(out,sp,lemp,lineno) -FILE *out; -struct symbol *sp; -struct lemon *lemp; -int *lineno; -{ - char *cp = 0; - - int linecnt = 0; - if( sp->type==TERMINAL ){ - cp = lemp->tokendest; - if( cp==0 ) return; - tplt_linedir(out,lemp->tokendestln,lemp->filename); - fprintf(out,"{"); - }else if( sp->destructor ){ - cp = sp->destructor; - tplt_linedir(out,sp->destructorln,lemp->filename); - fprintf(out,"{"); - }else if( lemp->vardest ){ - cp = lemp->vardest; - if( cp==0 ) return; - tplt_linedir(out,lemp->vardestln,lemp->filename); - fprintf(out,"{"); - }else{ - assert( 0 ); /* Cannot happen */ - } - for(; *cp; cp++){ - if( *cp=='$' && cp[1]=='$' ){ - fprintf(out,"(yypminor->yy%d)",sp->dtnum); - cp++; - continue; - } - if( *cp=='\n' ) linecnt++; - fputc(*cp,out); - } - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - return; -} - -/* -** Return TRUE (non-zero) if the given symbol has a destructor. -*/ -int has_destructor(sp, lemp) -struct symbol *sp; -struct lemon *lemp; -{ - int ret; - if( sp->type==TERMINAL ){ - ret = lemp->tokendest!=0; - }else{ - ret = lemp->vardest!=0 || sp->destructor!=0; - } - return ret; -} - -/* -** Append text to a dynamically allocated string. If zText is 0 then -** reset the string to be empty again. Always return the complete text -** of the string (which is overwritten with each call). -** -** n bytes of zText are stored. If n==0 then all of zText up to the first -** \000 terminator is stored. zText can contain up to two instances of -** %d. The values of p1 and p2 are written into the first and second -** %d. -** -** If n==-1, then the previous character is overwritten. -*/ -PRIVATE char *append_str(char *zText, int n, int p1, int p2){ - static char *z = 0; - static int alloced = 0; - static int used = 0; - int c; - char zInt[40]; - - if( zText==0 ){ - used = 0; - return z; - } - if( n<=0 ){ - if( n<0 ){ - used += n; - assert( used>=0 ); - } - n = strlen(zText); - } - if( n+sizeof(zInt)*2+used >= alloced ){ - alloced = n + sizeof(zInt)*2 + used + 200; - z = realloc(z, alloced); - } - if( z==0 ) return ""; - while( n-- > 0 ){ - c = *(zText++); - if( c=='%' && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); - p1 = p2; - strcpy(&z[used], zInt); - used += strlen(&z[used]); - zText++; - n--; - }else{ - z[used++] = c; - } - } - z[used] = 0; - return z; -} - -/* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. -*/ -PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ - char *cp, *xp; - int i; - char lhsused = 0; /* True if the LHS element has been used */ - char used[MAXRHS]; /* True for each RHS element which is used */ - - for(i=0; inrhs; i++) used[i] = 0; - lhsused = 0; - - append_str(0,0,0,0); - for(cp=rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ - char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); - saved = *xp; - *xp = 0; - if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ - append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0); - cp = xp; - lhsused = 1; - }else{ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){ - if( cp!=rp->code && cp[-1]=='@' ){ - /* If the argument is of the form @X then substituted - ** the token number of X, not the value of X */ - append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0); - }else{ - append_str("yymsp[%d].minor.yy%d",0, - i-rp->nrhs+1,rp->rhs[i]->dtnum); - } - cp = xp; - used[i] = 1; - break; - } - } - } - *xp = saved; - } - append_str(cp, 1, 0, 0); - } /* End loop */ - - /* Check to make sure the LHS has been used */ - if( rp->lhsalias && !lhsused ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label \"%s\" for \"%s(%s)\" is never used.", - rp->lhsalias,rp->lhs->name,rp->lhsalias); - lemp->errorcnt++; - } - - /* Generate destructor code for RHS symbols which are not used in the - ** reduce code */ - for(i=0; inrhs; i++){ - if( rp->rhsalias[i] && !used[i] ){ - ErrorMsg(lemp->filename,rp->ruleline, - "Label %s for \"%s(%s)\" is never used.", - rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]); - lemp->errorcnt++; - }else if( rp->rhsalias[i]==0 ){ - if( has_destructor(rp->rhs[i],lemp) ){ - append_str(" yy_destructor(%d,&yymsp[%d].minor);\n", 0, - rp->rhs[i]->index,i-rp->nrhs+1); - }else{ - /* No destructor defined for this term */ - } - } - } - cp = append_str(0,0,0,0); - rp->code = Strsafe(cp); -} - -/* -** Generate code which executes when the rule "rp" is reduced. Write -** the code to "out". Make sure lineno stays up-to-date. -*/ -PRIVATE void emit_code(out,rp,lemp,lineno) -FILE *out; -struct rule *rp; -struct lemon *lemp; -int *lineno; -{ - char *cp; - int linecnt = 0; - - /* Generate code to do the reduce action */ - if( rp->code ){ - tplt_linedir(out,rp->line,lemp->filename); - fprintf(out,"{%s",rp->code); - for(cp=rp->code; *cp; cp++){ - if( *cp=='\n' ) linecnt++; - } /* End loop */ - (*lineno) += 3 + linecnt; - fprintf(out,"}\n"); - tplt_linedir(out,*lineno,lemp->outname); - } /* End if( rp->code ) */ - - return; -} - -/* -** Print the definition of the union used for the parser's data stack. -** This union contains fields for every possible data type for tokens -** and nonterminals. In the process of computing and printing this -** union, also set the ".dtnum" field of every terminal and nonterminal -** symbol. -*/ -void print_stack_union(out,lemp,plineno,mhflag) -FILE *out; /* The output stream */ -struct lemon *lemp; /* The main info structure for this parser */ -int *plineno; /* Pointer to the line number */ -int mhflag; /* True if generating makeheaders output */ -{ - int lineno = *plineno; /* The line number of the output */ - char **types; /* A hash table of datatypes */ - int arraysize; /* Size of the "types" array */ - int maxdtlength; /* Maximum length of any ".datatype" field. */ - char *stddt; /* Standardized name for a datatype */ - int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ - char *name; /* Name of the parser */ - - /* Allocate and initialize types[] and allocate stddt[] */ - arraysize = lemp->nsymbol * 2; - types = (char**)malloc( arraysize * sizeof(char*) ); - for(i=0; ivartype ){ - maxdtlength = strlen(lemp->vartype); - } - for(i=0; insymbol; i++){ - int len; - struct symbol *sp = lemp->symbols[i]; - if( sp->datatype==0 ) continue; - len = strlen(sp->datatype); - if( len>maxdtlength ) maxdtlength = len; - } - stddt = (char*)malloc( maxdtlength*2 + 1 ); - if( types==0 || stddt==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - - /* Build a hash table of datatypes. The ".dtnum" field of each symbol - ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is - ** used for terminal symbols. If there is no %default_type defined then - ** 0 is also used as the .dtnum value for nonterminals which do not specify - ** a datatype using the %type directive. - */ - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - char *cp; - if( sp==lemp->errsym ){ - sp->dtnum = arraysize+1; - continue; - } - if( sp->type!=NONTERMINAL || (sp->datatype==0 && lemp->vartype==0) ){ - sp->dtnum = 0; - continue; - } - cp = sp->datatype; - if( cp==0 ) cp = lemp->vartype; - j = 0; - while( isspace(*cp) ) cp++; - while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; - stddt[j] = 0; - hash = 0; - for(j=0; stddt[j]; j++){ - hash = hash*53 + stddt[j]; - } - hash = (hash & 0x7fffffff)%arraysize; - while( types[hash] ){ - if( strcmp(types[hash],stddt)==0 ){ - sp->dtnum = hash + 1; - break; - } - hash++; - if( hash>=arraysize ) hash = 0; - } - if( types[hash]==0 ){ - sp->dtnum = hash + 1; - types[hash] = (char*)malloc( strlen(stddt)+1 ); - if( types[hash]==0 ){ - fprintf(stderr,"Out of memory.\n"); - exit(1); - } - strcpy(types[hash],stddt); - } - } - - /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ - name = lemp->name ? lemp->name : "Parse"; - lineno = *plineno; - if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } - fprintf(out,"#define %sTOKENTYPE %s\n",name, - lemp->tokentype?lemp->tokentype:"void*"); lineno++; - if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } - fprintf(out,"typedef union {\n"); lineno++; - fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; - for(i=0; ierrsym->dtnum); lineno++; - free(stddt); - free(types); - fprintf(out,"} YYMINORTYPE;\n"); lineno++; - *plineno = lineno; -} - -/* -** Return the name of a C datatype able to represent values between -** lwr and upr, inclusive. -*/ -static const char *minimum_size_type(int lwr, int upr){ - if( lwr>=0 ){ - if( upr<=255 ){ - return "unsigned char"; - }else if( upr<65535 ){ - return "unsigned short int"; - }else{ - return "unsigned int"; - } - }else if( lwr>=-127 && upr<=127 ){ - return "signed char"; - }else if( lwr>=-32767 && upr<32767 ){ - return "short"; - }else{ - return "int"; - } -} - -/* -** Each state contains a set of token transaction and a set of -** nonterminal transactions. Each of these sets makes an instance -** of the following structure. An array of these structures is used -** to order the creation of entries in the yy_action[] table. -*/ -struct axset { - struct state *stp; /* A pointer to a state */ - int isTkn; /* True to use tokens. False for non-terminals */ - int nAction; /* Number of actions */ -}; - -/* -** Compare to axset structures for sorting purposes -*/ -static int axset_compare(const void *a, const void *b){ - struct axset *p1 = (struct axset*)a; - struct axset *p2 = (struct axset*)b; - return p2->nAction - p1->nAction; -} - -/* Generate C source code for the parser */ -void ReportTable(lemp, mhflag) -struct lemon *lemp; -int mhflag; /* Output in makeheaders format if true */ -{ - FILE *out, *in; - char line[LINESIZE]; - int lineno; - struct state *stp; - struct action *ap; - struct rule *rp; - struct acttab *pActtab; - int i, j, n; - char *name; - int mnTknOfst, mxTknOfst; - int mnNtOfst, mxNtOfst; - struct axset *ax; - - in = tplt_open(lemp); - if( in==0 ) return; - out = file_open(lemp,".c","wb"); - if( out==0 ){ - fclose(in); - return; - } - lineno = 1; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the include code, if any */ - tplt_print(out,lemp,lemp->include,lemp->includeln,&lineno); - if( mhflag ){ - char *name = file_makename(lemp, ".h"); - fprintf(out,"#include \"%s\"\n", name); lineno++; - free(name); - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate #defines for all tokens */ - if( mhflag ){ - char *prefix; - fprintf(out,"#if INTERFACE\n"); lineno++; - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - lineno++; - } - fprintf(out,"#endif\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the defines */ - fprintf(out,"#define YYCODETYPE %s\n", - minimum_size_type(0, lemp->nsymbol+5)); lineno++; - fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1); lineno++; - fprintf(out,"#define YYACTIONTYPE %s\n", - minimum_size_type(0, lemp->nstate+lemp->nrule+5)); lineno++; - print_stack_union(out,lemp,&lineno,mhflag); - if( lemp->stacksize ){ - if( atoi(lemp->stacksize)<=0 ){ - ErrorMsg(lemp->filename,0, -"Illegal stack size: [%s]. The stack size should be an integer constant.", - lemp->stacksize); - lemp->errorcnt++; - lemp->stacksize = "100"; - } - fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; - }else{ - fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; - } - if( mhflag ){ - fprintf(out,"#if INTERFACE\n"); lineno++; - } - name = lemp->name ? lemp->name : "Parse"; - if( lemp->arg && lemp->arg[0] ){ - int i; - i = strlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; - fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; - fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", - name,lemp->arg,&lemp->arg[i]); lineno++; - fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n", - name,&lemp->arg[i],&lemp->arg[i]); lineno++; - }else{ - fprintf(out,"#define %sARG_SDECL\n",name); lineno++; - fprintf(out,"#define %sARG_PDECL\n",name); lineno++; - fprintf(out,"#define %sARG_FETCH\n",name); lineno++; - fprintf(out,"#define %sARG_STORE\n",name); lineno++; - } - if( mhflag ){ - fprintf(out,"#endif\n"); lineno++; - } - fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; - fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; - if( lemp->has_fallback ){ - fprintf(out,"#define YYFALLBACK 1\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the action table and its associates: - ** - ** yy_action[] A single table containing all actions. - ** yy_lookahead[] A table containing the lookahead for each entry in - ** yy_action. Used to detect hash collisions. - ** yy_shift_ofst[] For each state, the offset into yy_action for - ** shifting terminals. - ** yy_reduce_ofst[] For each state, the offset into yy_action for - ** shifting non-terminals after a reduce. - ** yy_default[] Default action for each state. - */ - - /* Compute the actions on all states and count them up */ - ax = malloc( sizeof(ax[0])*lemp->nstate*2 ); - if( ax==0 ){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - stp->nTknAct = stp->nNtAct = 0; - stp->iDflt = lemp->nstate + lemp->nrule; - stp->iTknOfst = NO_OFFSET; - stp->iNtOfst = NO_OFFSET; - for(ap=stp->ap; ap; ap=ap->next){ - if( compute_action(lemp,ap)>=0 ){ - if( ap->sp->indexnterminal ){ - stp->nTknAct++; - }else if( ap->sp->indexnsymbol ){ - stp->nNtAct++; - }else{ - stp->iDflt = compute_action(lemp, ap); - } - } - } - ax[i*2].stp = stp; - ax[i*2].isTkn = 1; - ax[i*2].nAction = stp->nTknAct; - ax[i*2+1].stp = stp; - ax[i*2+1].isTkn = 0; - ax[i*2+1].nAction = stp->nNtAct; - } - mxTknOfst = mnTknOfst = 0; - mxNtOfst = mnNtOfst = 0; - - /* Compute the action table. In order to try to keep the size of the - ** action table to a minimum, the heuristic of placing the largest action - ** sets first is used. - */ - qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); - pActtab = acttab_alloc(); - for(i=0; instate*2 && ax[i].nAction>0; i++){ - stp = ax[i].stp; - if( ax[i].isTkn ){ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->index>=lemp->nterminal ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iTknOfst = acttab_insert(pActtab); - if( stp->iTknOfstiTknOfst; - if( stp->iTknOfst>mxTknOfst ) mxTknOfst = stp->iTknOfst; - }else{ - for(ap=stp->ap; ap; ap=ap->next){ - int action; - if( ap->sp->indexnterminal ) continue; - if( ap->sp->index==lemp->nsymbol ) continue; - action = compute_action(lemp, ap); - if( action<0 ) continue; - acttab_action(pActtab, ap->sp->index, action); - } - stp->iNtOfst = acttab_insert(pActtab); - if( stp->iNtOfstiNtOfst; - if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst; - } - } - free(ax); - - /* Output the yy_action table */ - fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++; - n = acttab_size(pActtab); - for(i=j=0; insymbol + lemp->nrule + 2; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", action); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_lookahead table */ - fprintf(out,"static const YYCODETYPE yy_lookahead[] = {\n"); lineno++; - for(i=j=0; insymbol; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; - fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the yy_reduce_ofst[] table */ - fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++; - fprintf(out, "static const %s yy_reduce_ofst[] = {\n", - minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - ofst = stp->iNtOfst; - if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", ofst); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - - /* Output the default action table */ - fprintf(out, "static const YYACTIONTYPE yy_default[] = {\n"); lineno++; - n = lemp->nstate; - for(i=j=0; isorted[i]; - if( j==0 ) fprintf(out," /* %5d */ ", i); - fprintf(out, " %4d,", stp->iDflt); - if( j==9 || i==n-1 ){ - fprintf(out, "\n"); lineno++; - j = 0; - }else{ - j++; - } - } - fprintf(out, "};\n"); lineno++; - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of fallback tokens. - */ - if( lemp->has_fallback ){ - for(i=0; interminal; i++){ - struct symbol *p = lemp->symbols[i]; - if( p->fallback==0 ){ - fprintf(out, " 0, /* %10s => nothing */\n", p->name); - }else{ - fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, - p->name, p->fallback->name); - } - lineno++; - } - } - tplt_xfer(lemp->name, in, out, &lineno); - - /* Generate a table containing the symbolic name of every symbol - */ - for(i=0; insymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); - fprintf(out," %-15s",line); - if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } - } - if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate a table containing a text string that describes every - ** rule in the rule set of the grammer. This information is used - ** when tracing REDUCE actions. - */ - for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); - fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name); - for(j=0; jnrhs; j++) fprintf(out," %s",rp->rhs[j]->name); - fprintf(out,"\",\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes every time a symbol is popped from - ** the stack while processing errors or while destroying the parser. - ** (In other words, generate the %destructor actions) - */ - if( lemp->tokendest ){ - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type!=TERMINAL ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - } - for(i=0; insymbol && lemp->symbols[i]->type!=TERMINAL; i++); - if( insymbol ){ - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - - /* Combine duplicate destructors into a single case */ - for(j=i+1; jnsymbol; j++){ - struct symbol *sp2 = lemp->symbols[j]; - if( sp2 && sp2->type!=TERMINAL && sp2->destructor - && sp2->dtnum==sp->dtnum - && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d:\n",sp2->index); lineno++; - sp2->destructor = 0; - } - } - - emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - if( lemp->vardest ){ - struct symbol *dflt_sp = 0; - for(i=0; insymbol; i++){ - struct symbol *sp = lemp->symbols[i]; - if( sp==0 || sp->type==TERMINAL || - sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; - dflt_sp = sp; - } - if( dflt_sp!=0 ){ - emit_destructor_code(out,dflt_sp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes whenever the parser stack overflows */ - tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate the table of rule information - ** - ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. - */ - for(rp=lemp->rule; rp; rp=rp->next){ - fprintf(out," { %d, %d },\n",rp->lhs->index,rp->nrhs); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which execution during each REDUCE action */ - for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code ) translate_code(lemp, rp); - } - for(rp=lemp->rule; rp; rp=rp->next){ - struct rule *rp2; - if( rp->code==0 ) continue; - fprintf(out," case %d:\n",rp->index); lineno++; - for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ - fprintf(out," case %d:\n",rp2->index); lineno++; - rp2->code = 0; - } - } - emit_code(out,rp,lemp,&lineno); - fprintf(out," break;\n"); lineno++; - } - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes if a parse fails */ - tplt_print(out,lemp,lemp->failure,lemp->failureln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when a syntax error occurs */ - tplt_print(out,lemp,lemp->error,lemp->errorln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Generate code which executes when the parser accepts its input */ - tplt_print(out,lemp,lemp->accept,lemp->acceptln,&lineno); - tplt_xfer(lemp->name,in,out,&lineno); - - /* Append any addition code the user desires */ - tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno); - - fclose(in); - fclose(out); - return; -} - -/* Generate a header file for the parser */ -void ReportHeader(lemp) -struct lemon *lemp; -{ - FILE *out, *in; - char *prefix; - char line[LINESIZE]; - char pattern[LINESIZE]; - int i; - - if( lemp->tokenprefix ) prefix = lemp->tokenprefix; - else prefix = ""; - in = file_open(lemp,".h","rb"); - if( in ){ - for(i=1; interminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - if( strcmp(line,pattern) ) break; - } - fclose(in); - if( i==lemp->nterminal ){ - /* No change in the file. Don't rewrite it. */ - return; - } - } - out = file_open(lemp,".h","wb"); - if( out ){ - for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); - } - fclose(out); - } - return; -} - -/* Reduce the size of the action tables, if possible, by making use -** of defaults. -** -** In this version, we take the most frequent REDUCE action and make -** it the default. Only default a reduce if there are more than one. -*/ -void CompressTables(lemp) -struct lemon *lemp; -{ - struct state *stp; - struct action *ap, *ap2; - struct rule *rp, *rp2, *rbest; - int nbest, n; - int i; - - for(i=0; instate; i++){ - stp = lemp->sorted[i]; - nbest = 0; - rbest = 0; - - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type!=REDUCE ) continue; - rp = ap->x.rp; - if( rp==rbest ) continue; - n = 1; - for(ap2=ap->next; ap2; ap2=ap2->next){ - if( ap2->type!=REDUCE ) continue; - rp2 = ap2->x.rp; - if( rp2==rbest ) continue; - if( rp2==rp ) n++; - } - if( n>nbest ){ - nbest = n; - rbest = rp; - } - } - - /* Do not make a default if the number of rules to default - ** is not at least 2 */ - if( nbest<2 ) continue; - - - /* Combine matching REDUCE actions into a single default */ - for(ap=stp->ap; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) break; - } - assert( ap ); - ap->sp = Symbol_new("{default}"); - for(ap=ap->next; ap; ap=ap->next){ - if( ap->type==REDUCE && ap->x.rp==rbest ) ap->type = NOT_USED; - } - stp->ap = Action_sort(stp->ap); - } -} - -/***************** From the file "set.c" ************************************/ -/* -** Set manipulation routines for the LEMON parser generator. -*/ - -static int size = 0; - -/* Set the set size */ -void SetSize(n) -int n; -{ - size = n+1; -} - -/* Allocate a new set */ -char *SetNew(){ - char *s; - int i; - s = (char*)malloc( size ); - if( s==0 ){ - extern void memory_error(); - memory_error(); - } - for(i=0; isize = 1024; - x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); - if( x1a->tbl==0 ){ - free(x1a); - x1a = 0; - }else{ - int i; - x1a->ht = (x1node**)&(x1a->tbl[1024]); - for(i=0; i<1024; i++) x1a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Strsafe_insert(data) -char *data; -{ - x1node *np; - int h; - int ph; - - if( x1a==0 ) return 0; - ph = strhash(data); - h = ph & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x1a->count>=x1a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x1 array; - array.size = size = x1a->size*2; - array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x1node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x1node *oldnp, *newnp; - oldnp = &(x1a->tbl[i]); - h = strhash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x1a->tbl); - *x1a = array; - } - /* Insert the new data */ - h = ph & (x1a->size-1); - np = &(x1a->tbl[x1a->count++]); - np->data = data; - if( x1a->ht[h] ) x1a->ht[h]->from = &(np->next); - np->next = x1a->ht[h]; - x1a->ht[h] = np; - np->from = &(x1a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -char *Strsafe_find(key) -char *key; -{ - int h; - x1node *np; - - if( x1a==0 ) return 0; - h = strhash(key) & (x1a->size-1); - np = x1a->ht[h]; - while( np ){ - if( strcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return a pointer to the (terminal or nonterminal) symbol "x". -** Create a new symbol if this is the first time "x" has been seen. -*/ -struct symbol *Symbol_new(x) -char *x; -{ - struct symbol *sp; - - sp = Symbol_find(x); - if( sp==0 ){ - sp = (struct symbol *)malloc( sizeof(struct symbol) ); - MemoryCheck(sp); - sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; - sp->prec = -1; - sp->assoc = UNK; - sp->firstset = 0; - sp->lambda = B_FALSE; - sp->destructor = 0; - sp->datatype = 0; - Symbol_insert(sp,sp->name); - } - return sp; -} - -/* Compare two symbols for working purposes -** -** Symbols that begin with upper case letters (terminals or tokens) -** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. -** -** We find experimentally that leaving the symbols in their original -** order (the order they appeared in the grammar file) gives the -** smallest parser tables in SQLite. -*/ -int Symbolcmpp(struct symbol **a, struct symbol **b){ - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - return i1-i2; -} - -/* There is one instance of the following structure for each -** associative array of type "x2". -*/ -struct s_x2 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x2node *tbl; /* The data stored here */ - struct s_x2node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x2". -*/ -typedef struct s_x2node { - struct symbol *data; /* The data */ - char *key; /* The key */ - struct s_x2node *next; /* Next entry with the same hash */ - struct s_x2node **from; /* Previous link */ -} x2node; - -/* There is only one instance of the array, which is the following */ -static struct s_x2 *x2a; - -/* Allocate a new associative array */ -void Symbol_init(){ - if( x2a ) return; - x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); - if( x2a ){ - x2a->size = 128; - x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); - if( x2a->tbl==0 ){ - free(x2a); - x2a = 0; - }else{ - int i; - x2a->ht = (x2node**)&(x2a->tbl[128]); - for(i=0; i<128; i++) x2a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Symbol_insert(data,key) -struct symbol *data; -char *key; -{ - x2node *np; - int h; - int ph; - - if( x2a==0 ) return 0; - ph = strhash(key); - h = ph & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x2a->count>=x2a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x2 array; - array.size = size = x2a->size*2; - array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x2node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x2node *oldnp, *newnp; - oldnp = &(x2a->tbl[i]); - h = strhash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x2a->tbl); - *x2a = array; - } - /* Insert the new data */ - h = ph & (x2a->size-1); - np = &(x2a->tbl[x2a->count++]); - np->key = key; - np->data = data; - if( x2a->ht[h] ) x2a->ht[h]->from = &(np->next); - np->next = x2a->ht[h]; - x2a->ht[h] = np; - np->from = &(x2a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct symbol *Symbol_find(key) -char *key; -{ - int h; - x2node *np; - - if( x2a==0 ) return 0; - h = strhash(key) & (x2a->size-1); - np = x2a->ht[h]; - while( np ){ - if( strcmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return the n-th data. Return NULL if n is out of range. */ -struct symbol *Symbol_Nth(n) -int n; -{ - struct symbol *data; - if( x2a && n>0 && n<=x2a->count ){ - data = x2a->tbl[n-1].data; - }else{ - data = 0; - } - return data; -} - -/* Return the size of the array */ -int Symbol_count() -{ - return x2a ? x2a->count : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct symbol **Symbol_arrayof() -{ - struct symbol **array; - int i,size; - if( x2a==0 ) return 0; - size = x2a->count; - array = (struct symbol **)malloc( sizeof(struct symbol *)*size ); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Compare two configurations */ -int Configcmp(a,b) -struct config *a; -struct config *b; -{ - int x; - x = a->rp->index - b->rp->index; - if( x==0 ) x = a->dot - b->dot; - return x; -} - -/* Compare two states */ -PRIVATE int statecmp(a,b) -struct config *a; -struct config *b; -{ - int rc; - for(rc=0; rc==0 && a && b; a=a->bp, b=b->bp){ - rc = a->rp->index - b->rp->index; - if( rc==0 ) rc = a->dot - b->dot; - } - if( rc==0 ){ - if( a ) rc = 1; - if( b ) rc = -1; - } - return rc; -} - -/* Hash a state */ -PRIVATE int statehash(a) -struct config *a; -{ - int h=0; - while( a ){ - h = h*571 + a->rp->index*37 + a->dot; - a = a->bp; - } - return h; -} - -/* Allocate a new state structure */ -struct state *State_new() -{ - struct state *new; - new = (struct state *)malloc( sizeof(struct state) ); - MemoryCheck(new); - return new; -} - -/* There is one instance of the following structure for each -** associative array of type "x3". -*/ -struct s_x3 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x3node *tbl; /* The data stored here */ - struct s_x3node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x3". -*/ -typedef struct s_x3node { - struct state *data; /* The data */ - struct config *key; /* The key */ - struct s_x3node *next; /* Next entry with the same hash */ - struct s_x3node **from; /* Previous link */ -} x3node; - -/* There is only one instance of the array, which is the following */ -static struct s_x3 *x3a; - -/* Allocate a new associative array */ -void State_init(){ - if( x3a ) return; - x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); - if( x3a ){ - x3a->size = 128; - x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); - if( x3a->tbl==0 ){ - free(x3a); - x3a = 0; - }else{ - int i; - x3a->ht = (x3node**)&(x3a->tbl[128]); - for(i=0; i<128; i++) x3a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int State_insert(data,key) -struct state *data; -struct config *key; -{ - x3node *np; - int h; - int ph; - - if( x3a==0 ) return 0; - ph = statehash(key); - h = ph & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x3a->count>=x3a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x3 array; - array.size = size = x3a->size*2; - array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x3node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x3node *oldnp, *newnp; - oldnp = &(x3a->tbl[i]); - h = statehash(oldnp->key) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->key = oldnp->key; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x3a->tbl); - *x3a = array; - } - /* Insert the new data */ - h = ph & (x3a->size-1); - np = &(x3a->tbl[x3a->count++]); - np->key = key; - np->data = data; - if( x3a->ht[h] ) x3a->ht[h]->from = &(np->next); - np->next = x3a->ht[h]; - x3a->ht[h] = np; - np->from = &(x3a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct state *State_find(key) -struct config *key; -{ - int h; - x3node *np; - - if( x3a==0 ) return 0; - h = statehash(key) & (x3a->size-1); - np = x3a->ht[h]; - while( np ){ - if( statecmp(np->key,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Return an array of pointers to all data in the table. -** The array is obtained from malloc. Return NULL if memory allocation -** problems, or if the array is empty. */ -struct state **State_arrayof() -{ - struct state **array; - int i,size; - if( x3a==0 ) return 0; - size = x3a->count; - array = (struct state **)malloc( sizeof(struct state *)*size ); - if( array ){ - for(i=0; itbl[i].data; - } - return array; -} - -/* Hash a configuration */ -PRIVATE int confighash(a) -struct config *a; -{ - int h=0; - h = h*571 + a->rp->index*37 + a->dot; - return h; -} - -/* There is one instance of the following structure for each -** associative array of type "x4". -*/ -struct s_x4 { - int size; /* The number of available slots. */ - /* Must be a power of 2 greater than or */ - /* equal to 1 */ - int count; /* Number of currently slots filled */ - struct s_x4node *tbl; /* The data stored here */ - struct s_x4node **ht; /* Hash table for lookups */ -}; - -/* There is one instance of this structure for every data element -** in an associative array of type "x4". -*/ -typedef struct s_x4node { - struct config *data; /* The data */ - struct s_x4node *next; /* Next entry with the same hash */ - struct s_x4node **from; /* Previous link */ -} x4node; - -/* There is only one instance of the array, which is the following */ -static struct s_x4 *x4a; - -/* Allocate a new associative array */ -void Configtable_init(){ - if( x4a ) return; - x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); - if( x4a ){ - x4a->size = 64; - x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); - if( x4a->tbl==0 ){ - free(x4a); - x4a = 0; - }else{ - int i; - x4a->ht = (x4node**)&(x4a->tbl[64]); - for(i=0; i<64; i++) x4a->ht[i] = 0; - } - } -} -/* Insert a new record into the array. Return TRUE if successful. -** Prior data with the same key is NOT overwritten */ -int Configtable_insert(data) -struct config *data; -{ - x4node *np; - int h; - int ph; - - if( x4a==0 ) return 0; - ph = confighash(data); - h = ph & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,data)==0 ){ - /* An existing entry with the same key is found. */ - /* Fail because overwrite is not allows. */ - return 0; - } - np = np->next; - } - if( x4a->count>=x4a->size ){ - /* Need to make the hash table bigger */ - int i,size; - struct s_x4 array; - array.size = size = x4a->size*2; - array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); - if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ - array.ht = (x4node**)&(array.tbl[size]); - for(i=0; icount; i++){ - x4node *oldnp, *newnp; - oldnp = &(x4a->tbl[i]); - h = confighash(oldnp->data) & (size-1); - newnp = &(array.tbl[i]); - if( array.ht[h] ) array.ht[h]->from = &(newnp->next); - newnp->next = array.ht[h]; - newnp->data = oldnp->data; - newnp->from = &(array.ht[h]); - array.ht[h] = newnp; - } - free(x4a->tbl); - *x4a = array; - } - /* Insert the new data */ - h = ph & (x4a->size-1); - np = &(x4a->tbl[x4a->count++]); - np->data = data; - if( x4a->ht[h] ) x4a->ht[h]->from = &(np->next); - np->next = x4a->ht[h]; - x4a->ht[h] = np; - np->from = &(x4a->ht[h]); - return 1; -} - -/* Return a pointer to data assigned to the given key. Return NULL -** if no such key. */ -struct config *Configtable_find(key) -struct config *key; -{ - int h; - x4node *np; - - if( x4a==0 ) return 0; - h = confighash(key) & (x4a->size-1); - np = x4a->ht[h]; - while( np ){ - if( Configcmp(np->data,key)==0 ) break; - np = np->next; - } - return np ? np->data : 0; -} - -/* Remove all data from the table. Pass each data to the function "f" -** as it is removed. ("f" may be null to avoid this step.) */ -void Configtable_clear(f) -int(*f)(/* struct config * */); -{ - int i; - if( x4a==0 || x4a->count==0 ) return; - if( f ) for(i=0; icount; i++) (*f)(x4a->tbl[i].data); - for(i=0; isize; i++) x4a->ht[i] = 0; - x4a->count = 0; - return; -} diff --git a/v2rayng/badvpn/lime/lime.bootstrap b/v2rayng/badvpn/lime/lime.bootstrap deleted file mode 100644 index 63791c718c..0000000000 --- a/v2rayng/badvpn/lime/lime.bootstrap +++ /dev/null @@ -1,31 +0,0 @@ -There is nothing to see here. Go and look at the file called "metagrammar". - -: $$ = new lime(); -grammar pragma toklist stop : $$->pragma($2, $3); -grammar rewrite stop : $2->update($$); -to grammar -: {$$=array();} -toklist sym : $$[] = $2; -toklist lit : $$[] = $2; -to toklist -sym '=' rhs : $$ = new lime_rewrite($1); $$->add_rhs($3); -rewrite '|' rhs : $$->add_rhs($3); -to rewrite -list : $$ = new lime_rhs($1, ''); -list action : $$ = new lime_rhs($1, $2); -to rhs -action : $$ = new lime_action($1, NULL); -action lambda : $$ = new lime_action($1, $2); -sym : $$ = new lime_glyph($1, NULL); -sym lambda : $$ = new lime_glyph($1, $2); -lit : $$ = new lime_glyph($1, NULL); -to slot -: $$ = new lime_rhs(); -rhs slot : $$->add($2); -to rhs -'{' code '}' : $$ = $2; -to action -: -code php : $$.=$2; -code '{' code '}' : $$.='{'.$3.'}'; -to code diff --git a/v2rayng/badvpn/lime/lime.php b/v2rayng/badvpn/lime/lime.php deleted file mode 100644 index b049225ebd..0000000000 --- a/v2rayng/badvpn/lime/lime.php +++ /dev/null @@ -1,910 +0,0 @@ -code=$code; } -} -class step { - /* - Base class for parse table instructions. The main idea is to make the - subclasses responsible for conflict resolution among themselves. It also - forms a sort of interface to the parse table. - */ - function __construct($sym) { - bug_unless($sym instanceof sym); - $this->sym = $sym; - } - function glyph() { return $this->sym->name; } -} -class error extends step { - function sane() { return false; } - function instruction() { bug("This should not happen."); } - function decide($that) { return $this; /* An error shall remain one. */ } -} -class shift extends step { - function __construct($sym, $q) { - parent::__construct($sym); - $this->q = $q; - } - function sane() { return true; } - function instruction() { return "s $this->q"; } - function decide($that) { - # shift-shift conflicts are impossible. - # shift-accept conflicts are a bug. - # so we can infer: - bug_unless($that instanceof reduce); - - # That being said, the resolution is a matter of precedence. - $shift_prec = $this->sym->right_prec; - $reduce_prec = $that->rule->prec; - - # If we don't have defined precedence levels for both options, - # then we default to shifting: - if (!($shift_prec and $reduce_prec)) return $this; - - # Otherwise, use the step with higher precedence. - if ($shift_prec > $reduce_prec) return $this; - if ($reduce_prec > $shift_prec) return $that; - - # The "nonassoc" works by giving equal precedence to both options, - # which means to put an error instruction in the parse table. - return new error($this->sym); - } -} -class reduce extends step { - function __construct($sym, $rule) { - bug_unless($rule instanceof rule); - parent::__construct($sym); - $this->rule = $rule; - } - function sane() { return true; } - function instruction() { return 'r '.$this->rule->id; } - function decide($that) { - # This means that the input grammar has a reduce-reduce conflict. - # Such things are considered an error in the input. - throw new RRC($this, $that); - #exit(1); - # BISON would go with the first encountered reduce thus: - # return $this; - } -} -class accept extends step { - function __construct($sym) { parent::__construct($sym); } - function sane() { return true; } - function instruction() { return 'a '.$this->sym->name; } -} -class RRC extends Exception { - function __construct($a, $b) { - parent::__construct("Reduce-Reduce Conflict"); - $this->a = $a; - $this->b = $b; - } - function make_noise() { - emit(sprintf( - "Reduce-Reduce Conflict:\n%s\n%s\nLookahead is (%s)", - $this->a->rule->text(), - $this->b->rule->text(), - $this->a->glyph() - )); - } -} -class state { - function __construct($id, $key, $close) { - $this->id = $id; - $this->key = $key; - $this->close = $close; # config key -> object - ksort($this->close); - $this->action = array(); - } - function dump() { - echo " * ".$this->id.' / '.$this->key."\n"; - foreach ($this->close as $config) $config->dump(); - } - function add_shift($sym, $state) { - $this->add_instruction(new shift($sym, $state->id)); - } - function add_reduce($sym, $rule) { - $this->add_instruction(new reduce($sym, $rule)); - } - function add_accept($sym) { - $this->add_instruction(new accept($sym)); - } - function add_instruction($step) { - bug_unless($step instanceof step); - $this->action[] = $step; - } - function find_reductions($lime) { - # rightmost configurations followset yields reduce. - foreach($this->close as $c) { - if ($c->rightmost) { - foreach ($c->follow->all() as $glyph) $this->add_reduce($lime->sym($glyph), $c->rule); - } - } - } - function resolve_conflicts() { - # For each possible lookahead, find one (and only one) step to take. - $table = array(); - foreach ($this->action as $step) { - $glyph = $step->glyph(); - if (isset($table[$glyph])) { - # There's a conflict. The shifts all came first, which - # simplifies the coding for the step->decide() methods. - try { - $table[$glyph] = $table[$glyph]->decide($step); - } catch (RRC $e) { - emit("State $this->id:"); - $e->make_noise(); - } - } else { - # This glyph is yet unprocessed, so the step at hand is - # our best current guess at what the grammar indicates. - $table[$glyph] = $step; - } - } - - # Now that we have the correct steps chosen, this routine is oddly - # also responsible for turning that table into the form that will - # eventually be passed to the parse engine. (So FIXME?) - $out = array(); - foreach ($table as $glyph => $step) { - if ($step->sane()) $out[$glyph] = $step->instruction(); - } - return $out; - } - function segment_config() { - # Filter $this->close into categories based on the symbol_after_the_dot. - $f = array(); - foreach ($this->close as $c) { - $p = $c->symbol_after_the_dot; - if (!$p) continue; - $f[$p->name][] = $c; - } - return $f; - } -} -class sym { - function __construct($name, $id) { - $this->name=$name; - $this->id=$id; - $this->term = true; # Until proven otherwise. - $this->rule = array(); - $this->config = array(); - $this->lambda = false; - $this->first = new set(); - $this->left_prec = $this->right_prec = 0; - } - function summary() { - $out = ''; - foreach ($this->rule as $rule) $out .= $rule->text()."\n"; - return $out; - } -} -class rule { - function __construct($id, $sym, $rhs, $code, $look, $replace) { - $this->id = $id; - $this->sym = $sym; - $this->rhs = $rhs; - $this->code = $code; - $this->look = $look; - bug_unless(is_int($look)); - $this->replace = $replace; - #$this->prec_sym = $prec_sym; - $this->prec = 0; - $this->first = array(); - $this->epsilon = count($rhs); - } - function lhs_glyph() { return $this->sym->name; } - function determine_precedence() { - # We may eventually expand to allow explicit prec_symbol declarations. - # Until then, we'll go with the rightmost terminal, which is what - # BISON does. People probably expect that. The leftmost terminal - # is a reasonable alternative behaviour, but I don't see the big - # deal just now. - - #$prec_sym = $this->prec_sym; - #if (!$prec_sym) - $prec_sym = $this->rightmost_terminal(); - if (!$prec_sym) return; - $this->prec = $prec_sym->left_prec; - } - private function rightmost_terminal() { - $symbol = NULL; - $rhs = $this->rhs; - while ($rhs) { - $symbol = array_pop($rhs); - if ($symbol->term) break; - } - return $symbol; - } - function text() { - $t = "($this->id) ".$this->lhs_glyph().' :='; - foreach($this->rhs as $s) $t .= ' '.$s->name; - return $t; - } - function table(lime_language $lang) { - return array( - 'symbol' => $this->lhs_glyph(), - 'len' => $this->look, - 'replace' => $this->replace, - 'code' => $lang->fixup($this->code), - 'text' => $this->text(), - ); - } - function lambda() { - foreach ($this->rhs as $sym) if (!$sym->lambda) return false; - return true; - } - function find_first() { - $dot = count($this->rhs); - $last = $this->first[$dot] = new set(); - while ($dot) { - $dot--; - $symbol_after_the_dot = $this->rhs[$dot]; - $first = $symbol_after_the_dot->first->all(); - bug_if(empty($first) and !$symbol_after_the_dot->lambda); - $set = new set($first); - if ($symbol_after_the_dot->lambda) { - $set->union($last); - if ($this->epsilon == $dot+1) $this->epsilon = $dot; - } - $last = $this->first[$dot] = $set; - } - } - function teach_symbol_of_first_set() { - $go = false; - foreach ($this->rhs as $sym) { - if ($this->sym->first->union($sym->first)) $go = true; - if (!$sym->lambda) break; - } - return $go; - } - function lambda_from($dot) { - return $this->epsilon <= $dot; - } - function leftmost($follow) { - return new config($this, 0, $follow); - } - function dotted_text($dot) { - $out = $this->lhs_glyph().' :='; - $idx = -1; - foreach($this->rhs as $idx => $s) { - if ($idx == $dot) $out .= ' .'; - $out .= ' '.$s->name; - } - if ($dot > $idx) $out .= ' .'; - return $out; - } -} -class config { - function __construct($rule, $dot, $follow) { - $this->rule=$rule; - $this->dot = $dot; - $this->key = "$rule->id.$dot"; - $this->rightmost = count($rule->rhs) <= $dot; - $this->symbol_after_the_dot = $this->rightmost ? null : $rule->rhs[$dot]; - $this->_blink = array(); - $this->follow = new set($follow); - $this->_flink= array(); - bug_unless($this->rightmost or count($rule)); - } - function text() { - $out = $this->rule->dotted_text($this->dot); - $out .= ' [ '.implode(' ', $this->follow->all()).' ]'; - return $out; - } - function blink($config) { - $this->_blink[] = $config; - } - function next() { - bug_if($this->rightmost); - $c = new config($this->rule, $this->dot+1, array()); - # Anything in the follow set for this config will also be in the next. - # However, we link it backwards because we might wind up selecting a - # pre-existing state, and the housekeeping is easier in the first half - # of the program. We'll fix it before doing the propagation. - $c->blink($this); - return $c; - } - function copy_links_from($that) { - foreach($that->_blink as $c) $this->blink($c); - } - function lambda() { - return $this->rule->lambda_from($this->dot); - } - function simple_follow() { - return $this->rule->first[$this->dot+1]->all(); - } - function epsilon_follows() { - return $this->rule->lambda_from($this->dot+1); - } - function fixlinks() { - foreach ($this->_blink as $that) $that->_flink[] = $this; - $this->blink = array(); - } - function dump() { - echo " * "; - echo $this->key.' : '; - echo $this->rule->dotted_text($this->dot); - echo $this->follow->text(); - foreach ($this->_flink as $c) echo $c->key.' / '; - echo "\n"; - } -} -class lime { - var $parser_class = 'parser'; - function __construct() { - $this->p_next = 1; - $this->sym = array(); - $this->rule = array(); - $this->start_symbol_set = array(); - $this->state = array(); - $this->stop = $this->sym('#'); - #$err = $this->sym('error'); - $err->term = false; - $this->lang = new lime_language_php(); - } - function language() { return $this->lang; } - function build_parser() { - $this->add_start_rule(); - foreach ($this->rule as $r) $r->determine_precedence(); - $this->find_sym_lamdba(); - $this->find_sym_first(); - foreach ($this->rule as $rule) $rule->find_first(); - $initial = $this->find_states(); - $this->fixlinks(); - # $this->dump_configurations(); - $this->find_follow_sets(); - foreach($this->state as $s) $s->find_reductions($this); - $i = $this->resolve_conflicts(); - $a = $this->rule_table(); - $qi = $initial->id; - return $this->lang->ptab_to_class($this->parser_class, compact('a', 'qi', 'i')); - } - function rule_table() { - $s = array(); - foreach ($this->rule as $i => $r) { - $s[$i] = $r->table($this->lang); - } - return $s; - } - function add_rule($symbol, $rhs, $code) { - $this->add_raw_rule($symbol, $rhs, $code, count($rhs), true); - } - function trump_up_bogus_lhs($real) { - return "'$real'".count($this->rule); - } - function add_raw_rule($lhs, $rhs, $code, $look, $replace) { - $sym = $this->sym($lhs); - $sym->term=false; - if (empty($rhs)) $sym->lambda = true; - $rs = array(); - foreach ($rhs as $str) $rs[] = $this->sym($str); - $rid = count($this->rule); - $r = new rule($rid, $sym, $rs, $code, $look, $replace); - $this->rule[$rid] = $r; - $sym->rule[] = $r; - } - function sym($str) { - if (!isset($this->sym[$str])) $this->sym[$str] = new sym($str, count($this->sym)); - return $this->sym[$str]; - } - function summary() { - $out = ''; - foreach ($this->sym as $sym) if (!$sym->term) $out .= $sym->summary(); - return $out; - } - private function find_sym_lamdba() { - do { - $go = false; - foreach ($this->sym as $sym) if (!$sym->lambda) { - foreach ($sym->rule as $rule) if ($rule->lambda()) { - $go = true; - $sym->lambda = true; - } - } - } while ($go); - } - private function teach_terminals_first_set() { - foreach ($this->sym as $sym) if ($sym->term) $sym->first->add($sym->name); - } - private function find_sym_first() { - $this->teach_terminals_first_set(); - do { - $go = false; - foreach ($this->rule as $r) if ($r->teach_symbol_of_first_set()) $go = true; - } while ($go); - } - function add_start_rule() { - $rewrite = new lime_rewrite("'start'"); - $rhs = new lime_rhs(); - $rhs->add(new lime_glyph($this->deduce_start_symbol()->name, NULL)); - #$rhs->add(new lime_glyph($this->stop->name, NULL)); - $rewrite->add_rhs($rhs); - $rewrite->update($this); - } - private function deduce_start_symbol() { - $candidate = current($this->start_symbol_set); - # Did the person try to set a start symbol at all? - if (!$candidate) return $this->first_rule_lhs(); - # Do we actually have such a symbol on the left of a rule? - if ($candidate->terminal) return $this->first_rule_lhs(); - # Ok, it's a decent choice. We need to return the symbol entry. - return $this->sym($candidate); - } - private function first_rule_lhs() { - reset($this->rule); - $r = current($this->rule); - return $r->sym; - } - function find_states() { - /* - Build an initial state. This is a recursive process which digs out - the LR(0) state graph. - */ - $start_glyph = "'start'"; - $sym = $this->sym($start_glyph); - $basis = array(); - foreach($sym->rule as $rule) { - $c = $rule->leftmost(array('#')); - $basis[$c->key] = $c; - } - $initial = $this->get_state($basis); - $initial->add_accept($sym); - return $initial; - } - function get_state($basis) { - $key = array_keys($basis); - sort($key); - $key = implode(' ', $key); - if (isset($this->state[$key])) { - # Copy all the links around... - $state = $this->state[$key]; - foreach($basis as $config) $state->close[$config->key]->copy_links_from($config); - return $state; - } else { - $close = $this->state_closure($basis); - $this->state[$key] = $state = new state(count($this->state), $key, $close); - $this->build_shifts($state); - return $state; - } - } - private function state_closure($q) { - # $q is a list of config. - $close = array(); - while ($config = array_pop($q)) { - if (isset($close[$config->key])) { - $close[$config->key]->copy_links_from($config); - $close[$config->key]->follow->union($config->follow); - continue; - } - $close[$config->key] = $config; - - $symbol_after_the_dot = $config->symbol_after_the_dot; - if (!$symbol_after_the_dot) continue; - - if (! $symbol_after_the_dot->term) { - foreach ($symbol_after_the_dot->rule as $r) { - $station = $r->leftmost($config->simple_follow()); - if ($config->epsilon_follows()) $station->blink($config); - $q[] = $station; - } - # The following turned out to be wrong. Don't do it. - #if ($symbol_after_the_dot->lambda) { - # $q[] = $config->next(); - #} - } - - } - return $close; - } - function build_shifts($state) { - foreach ($state->segment_config() as $glyph => $segment) { - $basis = array(); - foreach ($segment as $preshift) { - $postshift = $preshift->next(); - $basis[$postshift->key] = $postshift; - } - $dest = $this->get_state($basis); - $state->add_shift($this->sym($glyph), $dest); - } - } - function fixlinks() { - foreach ($this->state as $s) foreach ($s->close as $c) $c->fixlinks(); - } - function find_follow_sets() { - $q = array(); - foreach ($this->state as $s) foreach ($s->close as $c) $q[] = $c; - while ($q) { - $c = array_shift($q); - foreach ($c->_flink as $d) { - if ($d->follow->union($c->follow)) $q[] = $d; - } - } - } - private function set_assoc($ss, $l, $r) { - $p = ($this->p_next++)*2; - foreach ($ss as $glyph) { - $s = $this->sym($glyph); - $s->left_prec = $p+$l; - $s->right_prec = $p+$r; - } - } - function left_assoc($ss) { $this->set_assoc($ss, 1, 0); } - function right_assoc($ss) { $this->set_assoc($ss, 0, 1); } - function non_assoc($ss) { $this->set_assoc($ss, 0, 0); } - private function resolve_conflicts() { - # For each state, try to find one and only one - # thing to do for any given lookahead. - $i = array(); - foreach ($this->state as $s) $i[$s->id] = $s->resolve_conflicts(); - return $i; - } - function dump_configurations() { - foreach ($this->state as $q) $q->dump(); - } - function dump_first_sets() { - foreach ($this->sym as $s) { - echo " * "; - echo $s->name.' : '; - echo $s->first->text(); - echo "\n"; - } - } - function add_rule_with_actions($lhs, $rhs) { - # First, make sure this thing is well-formed. - if(!is_object(end($rhs))) $rhs[] = new cf_action(''); - # Now, split it into chunks based on the actions. - $look = -1; - $subrule = array(); - $subsymbol = ''; - while (count($rhs)) { - $it = array_shift($rhs); - $look ++; - if (is_string($it)) { - $subrule[] = $it; - } else { - $code = $it->code; - # It's an action. - # Is it the last one? - if (count($rhs)) { - # no. - $subsymbol = $this->trump_up_bogus_lhs($lhs); - $this->add_raw_rule($subsymbol, $subrule, $code, $look, false); - $subrule = array($subsymbol); - } else { - # yes. - $this->add_raw_rule($lhs, $subrule, $code, $look, true); - } - } - } - } - function pragma($type, $args) { - switch ($type) { - case 'left': - $this->left_assoc($args); - break; - - case 'right': - $this->right_assoc($args); - break; - - case 'nonassoc': - $this->non_assoc($args); - break; - - case 'start': - $this->start_symbol_set = $args; - break; - - case 'class': - $this->parser_class = $args[0]; - break; - - default: - emit(sprintf("Bad Parser Pragma: (%s)", $type)); - exit(1); - } - } -} -class lime_language {} -class lime_language_php extends lime_language { - private function result_code($expr) { return "\$result = $expr;\n"; } - function default_result() { return $this->result_code('reset($tokens)'); } - function result_pos($pos) { return $this->result_code(lime_token_reference($pos)); } - function bind($name, $pos) { return "\$$name =& \$tokens[$pos];\n"; } - function fixup($code) { - $code = preg_replace_callback('/\\$(\d+)/', 'lime_token_reference_callback', $code); - $code = preg_replace('/\\$\\$/', '$result', $code); - return $code; - } - function to_php($code) { - return $code; - } - function ptab_to_class($parser_class, $ptab) { - $code = "class $parser_class extends lime_parser {\n"; - $code .= 'var $qi = '.var_export($ptab['qi'], true).";\n"; - $code .= 'var $i = '.var_export($ptab['i'], true).";\n"; - - - $rc = array(); - $method = array(); - $rules = array(); - foreach($ptab['a'] as $k => $a) { - $symbol = preg_replace('/[^\w]/', '', $a['symbol']); - $rn = ++$rc[$symbol]; - $mn = "reduce_${k}_${symbol}_${rn}"; - $method[$k] = $mn; - $comment = "#\n# $a[text]\n#\n"; - $php = $this->to_php($a['code']); - $code .= "function $mn(".LIME_CALL_PROTOCOL.") {\n$comment$php\n}\n\n"; - - - unset($a['code']); - unset($a['text']); - $rules[$k] = $a; - } - - $code .= 'var $method = '.var_export($method, true).";\n"; - $code .= 'var $a = '.var_export($rules, true).";\n"; - - - - $code .= "}\n"; - #echo $code; - return $code; - } -} -class lime_rhs { - function __construct() { - /** - Construct and add glyphs and actions in whatever order. - Then, add this to a lime_rewrite. - - Don't call install_rule. - The rewrite will do that for you when you "update" with it. - */ - $this->rhs = array(); - } - function add($slot) { - bug_unless($slot instanceof lime_slot); - $this->rhs[] = $slot; - } - function install_rule(lime $lime, $lhs) { - # This is the part that has to break the rule into subrules if necessary. - $rhs = $this->rhs; - # First, make sure this thing is well-formed. - if (!(end($rhs) instanceof lime_action)) $rhs[] = new lime_action('', NULL); - # Now, split it into chunks based on the actions. - - $lang = $lime->language(); - $result_code = $lang->default_result(); - $look = -1; - $subrule = array(); - $subsymbol = ''; - $preamble = ''; - while (count($rhs)) { - $it = array_shift($rhs); - $look ++; - if ($it instanceof lime_glyph) { - $subrule[] = $it->data; - } elseif ($it instanceof lime_action) { - $code = $it->data; - # It's an action. - # Is it the last one? - if (count($rhs)) { - # no. - $subsymbol = $lime->trump_up_bogus_lhs($lhs); - $action = $lang->default_result().$preamble.$code; - $lime->add_raw_rule($subsymbol, $subrule, $action, $look, false); - $subrule = array($subsymbol); - } else { - # yes. - $action = $result_code.$preamble.$code; - $lime->add_raw_rule($lhs, $subrule, $action, $look, true); - } - } else { - impossible(); - } - if ($it->name == '$') $result_code = $lang->result_pos($look); - elseif ($it->name) $preamble .= $lang->bind($it->name, $look); - } - } -} -class lime_rewrite { - function __construct($glyph) { - /** - Construct one of these with the name of the lhs. - Add some rhs-es to it. - Finally, "update" the lime you're building. - */ - $this->glyph = $glyph; - $this->rhs = array(); - } - function add_rhs($rhs) { - bug_unless($rhs instanceof lime_rhs); - $this->rhs[] = $rhs; - } - function update(lime $lime) { - foreach ($this->rhs as $rhs) { - $rhs->install_rule($lime, $this->glyph); - - } - } -} -class lime_slot { - /** - This keeps track of one position in an rhs. - We specialize to handle actions and glyphs. - If there is a name for the slot, we store it here. - Later on, this structure will be consulted in the formation of - actual production rules. - */ - function __construct($data, $name) { - $this->data = $data; - $this->name = $name; - } - function preamble($pos) { - if (strlen($this->name) > 0) { - return "\$$this->name =& \$tokens[$pos];\n"; - } - } -} -class lime_glyph extends lime_slot {} -class lime_action extends lime_slot {} -function lime_bootstrap() { - - /* - - This function isn't too terribly interesting to the casual observer. - You're probably better off looking at parse_lime_grammar() instead. - - Ok, if you insist, I'll explain. - - The input to Lime is a CFG parser definition. That definition is - written in some language. (The Lime language, to be exact.) - Anyway, I have to parse the Lime language and compile it into a - very complex data structure from which a parser is eventually - built. What better way than to use Lime itself to parse its own - language? Well, it's almost that simple, but not quite. - - The Lime language is fairly potent, but a restricted subset of - its features was used to write a metagrammar. Then, I hand-translated - that metagrammar into another form which is easy to snarf up. - In the process of reading that simplified form, this function - builds the same sort of data structure that later gets turned into - a parser. The last step is to run the parser generation algorithm, - eval() the resulting PHP code, and voila! With no hard work, I can - suddenly read and comprehend the full range of the Lime language - without ever having written an algorithm to do so. It feels like magic. - - */ - - $bootstrap = LIME_DIR."/lime.bootstrap"; - $lime = new lime(); - $lime->parser_class = 'lime_metaparser'; - $rhs = array(); - bug_unless(is_readable($bootstrap)); - foreach(file($bootstrap) as $l) { - $a = explode(":", $l, 2); - if (count($a) == 2) { - list($pattern, $code) = $a; - $sl = new lime_rhs(); - $pattern = trim($pattern); - if (strlen($pattern)>0) { - foreach (explode(' ', $pattern) as $glyph) $sl->add(new lime_glyph($glyph, NULL)); - } - $sl->add(new lime_action($code, NULL)); - $rhs[] = $sl; - } else { - $m = preg_match('/^to (\w+)$/', $l, $r); - if ($m == 0) continue; - $g = $r[1]; - $rw = new lime_rewrite($g); - foreach($rhs as $b) $rw->add_rhs($b); - $rw->update($lime); - $rhs = array(); - } - } - $parser_code = $lime->build_parser(); - eval($parser_code); -} - -class voodoo_scanner extends flex_scanner { - /* - - The voodoo is in the way I do lexical processing on grammar definition - files. They contain embedded bits of PHP, and it's important to keep - track of things like strings, comments, and matched braces. It seemed - like an ideal problem to solve with GNU flex, so I wrote a little - scanner in flex and C to dig out the tokens for me. Of course, I need - the tokens in PHP, so I designed a simple binary wrapper for them which - also contains line-number information, guaranteed to help out if you - write a grammar which surprises the parser in any manner. - - */ - function executable() { return LIME_DIR.'/lime_scan_tokens'; } -} - -function parse_lime_grammar($path) { - /* - - This is a good function to read because it teaches you how to interface - with a Lime parser. I've tried to isolate out the bits that aren't - instructive in that regard. - - */ - if (!class_exists('lime_metaparser')) lime_bootstrap(); - - $parse_engine = new parse_engine(new lime_metaparser()); - $scanner = new voodoo_scanner($path); - try { - # The result of parsing a Lime grammar is a Lime object. - $lime = $scanner->feed($parse_engine); - # Calling its build_parser() method gets the output PHP code. - return $lime->build_parser(); - } catch (parse_error $e) { - die ($e->getMessage()." in $path line $scanner->lineno.\n"); - } -} - - -if ($_SERVER['argv']) { - $code = ''; - array_shift($_SERVER['argv']); # Strip out the program name. - foreach ($_SERVER['argv'] as $path) { - $code .= parse_lime_grammar($path); - } - - echo " - -/* - -DON'T EDIT THIS FILE! - -This file was automatically generated by the Lime parser generator. -The real source code you should be looking at is in one or more -grammar files in the Lime format. - -THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar -file that your error happened, because there are enough comments to -help you debug your grammar. - -If you ignore this warning, you're shooting yourself in the brain, -not the foot. - -*/ - -"{" { - lit(); - yy_push_state(code); -} - -. lit(); - - -{ -\n { - out("stop", "."); - yy_pop_state(); -} -[[:space:]] {} -{SYM} tok("sym"); -{LIT} tok("lit"); -. lit(); -} - -{ -"}" { - lit(); - yy_pop_state(); -} -'{SCHAR}*' php(); -\"{DCHAR}*\" php(); -{COM}.* php(); -{BLOCKCMT} php(); -[^{}'"#/]+ php(); -. php(); -} - -%% - -void lit() { - char lit[] = "'.'"; - lit[1] = *yytext; - out(lit, yytext); -} - -void tok(char*t) { - out(t, yytext); -} - -void php() { - out("php", yytext); -} - -void out(char*type, char*value) { - printf("%d\001%s\001%s", yylineno, type, value); - fputc(0, stdout); -} diff --git a/v2rayng/badvpn/lime/metagrammar b/v2rayng/badvpn/lime/metagrammar deleted file mode 100644 index 5d057c0329..0000000000 --- a/v2rayng/badvpn/lime/metagrammar +++ /dev/null @@ -1,58 +0,0 @@ -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# This is the grammar for all other grammar files that will work with the -# Lime LALR(1) Context-Free Grammar Parser Generator. -# You can read this to get an idea how things work, but this file is not -# actually used in the system. Rather, it's an implementation guide for the -# file "lime.bootstrap". - -%class lime_metaparser -%start grammar - -grammar -= {$$ = new lime();} -| grammar/$ pragma/p toklist/t stop {$$->pragma($p, $t);} -| grammar/$ rewrite/r stop {$r->update($$);} -. - -rewrite -= sym/s '=' rhs/r {$$ = new lime_rewrite($s); $$->add_rhs($r);} -| rewrite/$ '|' rhs/r {$$->add_rhs($r);} -. - -slot -= action/a {$$ = new lime_action($a, NULL);} -| action/a lambda/l {$$ = new lime_action($a, $l);} -| sym/s {$$ = new lime_glyph($s, NULL);} -| sym/s lambda/l {$$ = new lime_glyph($s, $l);} -| lit/l {$$ = new lime_glyph($l, NULL);} -. - -rhs -= {$$ = new lime_rhs();} -| rhs/$ slot/s {$$->add($s);} -. - -action = '{' code/$ '}' . - -toklist = {$$=array();} -| toklist/$ sym/s {$$[] = $s;} -| toklist/$ lit/l {$$[] = $l;} -. - -code = {} -| code/$ php/p {$$.=$p;} -| code/$ '{' code/c '}' {$$.='{'.$c.'}';} -. diff --git a/v2rayng/badvpn/lime/parse_engine.php b/v2rayng/badvpn/lime/parse_engine.php deleted file mode 100644 index fd54cc4626..0000000000 --- a/v2rayng/badvpn/lime/parse_engine.php +++ /dev/null @@ -1,252 +0,0 @@ -type = $type; - $this->state = $state; - } -} -class parse_premature_eof extends parse_error { - function __construct() { - parent::__construct("Premature EOF"); - } -} - - -class parse_stack { - function __construct($qi) { - $this->q = $qi; - $this->qs = array(); - $this->ss = array(); - } - function shift($q, $semantic) { - $this->ss[] = $semantic; - $this->qs[] = $this->q; - $this->q = $q; - # echo "Shift $q -- $semantic
\n"; - } - function top_n($n) { - if (!$n) return array(); - return array_slice($this->ss, 0-$n); - } - function pop_n($n) { - if (!$n) return array(); - $qq = array_splice($this->qs, 0-$n); - $this->q = $qq[0]; - return array_splice($this->ss, 0-$n); - } - function occupied() { return !empty($this->ss); } - function index($n) { - if ($n) $this->q = $this->qs[count($this->qs)-$n]; - } - function text() { - return $this->q." : ".implode(' . ', array_reverse($this->qs)); - } -} -class parse_engine { - function __construct($parser) { - $this->parser = $parser; - $this->qi = $parser->qi; - $this->rule = $parser->a; - $this->step = $parser->i; - #$this->prepare_callables(); - $this->reset(); - #$this->debug = false; - } - function reset() { - $this->accept = false; - $this->stack = new parse_stack($this->qi); - } - private function enter_error_tolerant_state() { - while ($this->stack->occupied()) { - if ($this->has_step_for('error')) return true; - $this->drop(); - }; - return false; - } - private function drop() { $this->stack->pop_n(1); } - function eat_eof() { - {/* - - So that I don't get any brilliant misguided ideas: - - The "accept" step happens when we try to eat a start symbol. - That happens because the reductions up the stack at the end - finally (and symetrically) tell the parser to eat a symbol - representing what they've just shifted off the end of the stack - and reduced. However, that doesn't put the parser into any - special different state. Therefore, it's back at the start - state. - - That being said, the parser is ready to reduce an EOF to the - empty program, if given a grammar that allows them. - - So anyway, if you literally tell the parser to eat an EOF - symbol, then after it's done reducing and accepting the prior - program, it's going to think it has another symbol to deal with. - That is the EOF symbol, which means to reduce the empty program, - accept it, and then continue trying to eat the terminal EOF. - - This infinte loop quickly runs out of memory. - - That's why the real EOF algorithm doesn't try to pretend that - EOF is a terminal. Like the invented start symbol, it's special. - - Instead, we pretend to want to eat EOF, but never actually - try to get it into the parse stack. (It won't fit.) In short, - we look up what reduction is indicated at each step in the - process of rolling up the parse stack. - - The repetition is because one reduction is not guaranteed to - cascade into another and clean up the entire parse stack. - Rather, it will instead shift each partial production as it - is forced to completion by the EOF lookahead. - */} - - # We must reduce as if having read the EOF symbol - do { - # and we have to try at least once, because if nothing - # has ever been shifted, then the stack will be empty - # at the start. - list($opcode, $operand) = $this->step_for('#'); - switch ($opcode) { - case 'r': $this->reduce($operand); break; - case 'e': $this->premature_eof(); break; - default: throw new parse_bug(); break; - } - } while ($this->stack->occupied()); - {/* - If the sentence is well-formed according to the grammar, then - this will eventually result in eating a start symbol, which - causes the "accept" instruction to fire. Otherwise, the - step('#') method will indicate an error in the syntax, which - here means a premature EOF. - - Incedentally, some tremendous amount of voodoo with the parse - stack might help find the beginning of some unfinished - production that the sentence was cut off during, but as a - general rule that would require deeper knowledge. - */} - if (!$this->accept) throw new parse_bug(); - return $this->semantic; - } - private function premature_eof() { - $seen = array(); - while ($this->enter_error_tolerant_state()) { - if (isset($seen[$this->state()])) { - // This means that it's pointless to try here. - // We're guaranteed that the stack is occupied. - $this->drop(); - continue; - } - $seen[$this->state()] = true; - - $this->eat('error', NULL); - if ($this->has_step_for('#')) { - // Good. We can continue as normal. - return; - } else { - // That attempt to resolve the error condition - // did not work. There's no point trying to - // figure out how much to slice off the stack. - // The rest of the algorithm will make it happen. - } - } - throw new parse_premature_eof(); - } - private function current_row() { return $this->step[$this->state()]; } - private function step_for($type) { - $row = $this->current_row(); - if (!isset($row[$type])) return array('e', $this->stack->q); - return explode(' ', $row[$type]); - } - private function has_step_for($type) { - $row = $this->current_row(); - return isset($row[$type]); - } - private function state() { return $this->stack->q; } - function eat($type, $semantic) { - # assert('$type == trim($type)'); - # if ($this->debug) echo "Trying to eat a ($type)\n"; - list($opcode, $operand) = $this->step_for($type); - switch ($opcode) { - case 's': - # if ($this->debug) echo "shift $type to state $operand\n"; - $this->stack->shift($operand, $semantic); - # echo $this->stack->text()." shift $type
\n"; - break; - - case 'r': - $this->reduce($operand); - $this->eat($type, $semantic); - # Yes, this is tail-recursive. It's also the simplest way. - break; - - case 'a': - if ($this->stack->occupied()) throw new parse_bug('Accept should happen with empty stack.'); - $this->accept = true; - #if ($this->debug) echo ("Accept\n\n"); - $this->semantic = $semantic; - break; - - case 'e': - # This is thought to be the uncommon, exceptional path, so - # it's OK that this algorithm will cause the stack to - # flutter while the parse engine waits for an edible token. - # if ($this->debug) echo "($type) causes a problem.\n"; - if ($this->enter_error_tolerant_state()) { - $this->eat('error', NULL); - if ($this->has_step_for($type)) $this->eat($type, $semantic); - } else { - # If that didn't work, give up: - throw new parse_error("Parse Error: ($type)($semantic) not expected"); - } - break; - - default: - throw new parse_bug("Bad parse table instruction ".htmlspecialchars($opcode)); - } - } - private function reduce($rule_id) { - $rule = $this->rule[$rule_id]; - $len = $rule['len']; - $semantic = $this->perform_action($rule_id, $this->stack->top_n($len)); - #echo $semantic.br(); - if ($rule['replace']) $this->stack->pop_n($len); - else $this->stack->index($len); - $this->eat($rule['symbol'], $semantic); - } - private function perform_action($rule_id, $slice) { - # we have this weird calling convention.... - $result = null; - $method = $this->parser->method[$rule_id]; - #if ($this->debug) echo "rule $id: $method\n"; - $this->parser->$method($slice, $result); - return $result; - } -} diff --git a/v2rayng/badvpn/lime/set.so.php b/v2rayng/badvpn/lime/set.so.php deleted file mode 100644 index ef87c6cd71..0000000000 --- a/v2rayng/badvpn/lime/set.so.php +++ /dev/null @@ -1,29 +0,0 @@ -data = array_count_values($list); } - function has($item) { return isset($this->data[$item]); } - function add($item) { $this->data[$item] = true; } - function del($item) { unset($this->data[$item]); return $item;} - function all() { return array_keys($this->data); } - function one() { return key($this->data); } - function count() { return count($this->data); } - function pop() { return $this->del($this->one()); } - function union($that) { - $progress = false; - foreach ($that->all() as $item) if (!$this->has($item)) { - $this->add($item); - $progress = true; - } - return $progress; - } - function text() { - return ' { '.implode(' ', $this->all()).' } '; - } -} diff --git a/v2rayng/badvpn/lwip/CHANGELOG b/v2rayng/badvpn/lwip/CHANGELOG deleted file mode 100644 index 8f52e013c8..0000000000 --- a/v2rayng/badvpn/lwip/CHANGELOG +++ /dev/null @@ -1,4329 +0,0 @@ -HISTORY - -(git master) - - * [Enter new changes just after this line - do not remove this line] - - ++ New features: - - 2017-09-10: Joel Cunningham - * sockets: add readv() implementation (task #14610) - - 2017-08-04: Simon Goldschmidt - * Clean up DHCP a bit: no need keep msg_out and msg_in as members in struct - dhcp - they are used in a call stack only (p_out and options_out_len as well) - - 2017-08-04: Simon Goldschmidt - * pbuf: split pbuf_header(s16_t) into pbuf_add_header(size_t) and - pbuf_remove_header(size_t) - - 2017-07-20: Douglas - * sys: deprecate sys_arch_sem_wait and sys_arch_mbox_fetch returning the - time waited rather they are now defined to return != SYS_ARCH_TIMEOUT - on success. - - 2017-07-03: Jakub Schmidtke - * tcp: added support for sending TCP SACKs - - 2017-06-20: Joel Cunningham - * netconn/netdb: added core locking support to netconn_gethostbyname (task #14523) - - 2017-04-25: Simon Goldschmidt - * dhcp: added two hooks for adding and parsing user defined DHCP options - - 2017-04-25: Joel Cunningham - * sockets: added CMSG and IP_PKTINFO for use with recvmsg (task #14247) - - 2017-04-20: Joel Cunningham - * tcp: added Appropriate Byte Counting support (task #14128) - - 2017-04-11: Simon Goldschmidt - * netconn/sockets: remove fatal error handling, fix asynchronous error handling, - ensure data before RST can be received - - 2017-03-02: Joel Cunningham - * netconn/sockets: vectorize netconn_write for TCP, treating a vectored I/O write - atomically in regards to TCP segmentation (patch #8882) - - 2017-03-02: Simon Goldschmidt - * netconn: added nonblocking accept/recv to netconn API (task #14396) - - 2017-02-28: Simon Goldschmidt - * Added LWIP_SINGLE_NETIF for small targets with only one netif - - 2017-02-17: Simon Goldschmidt - * Improved DNS_LOCAL_HOSTLIST interface - - 2017-02-10: David van Moolenbroek - * Implement UDP and RAW multicast support for IPv6 (core API, not netconn/sockets) - - 2017-02-10: Simon Goldschmidt - * tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr) - - 2017-02-04: David van Moolenbroek - - IPv6 scopes support - - 2017-01-20: Joel Cunningham - * sockets: add interface name/index APIs (task #14314) - - 2017-01-08: David van Moolenbroek - * Extensions to RAW API (patch #9208) - - Connected RAW PCBs - - Add raw_sendto_if_src() - - Support IP_HDRINCL socket option - - ++ Bugfixes: - - 2017-09-12: David Lockyer - * select: allocate select_cb from memp for LWIP_MPU_COMPATIBLE = 1 (bug #51990) - - 2017-09-11: Simon Goldschmidt - * tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data) - - 2017-08-11: Joel Cunningham - * lwip_itoa: fix converting the number 0 (previously converted to '\0') (bug #51729) - - 2017-08-08: Dirk Ziegelmeier - * ip4_route_src: parameter order is reversed: ip4_route_src(dest, src) -> ip4_route_src(src, dest) - to make parameter order consistent with other ip*_route*() functions - Same also applies to LWIP_HOOK_IP4_ROUTE_SRC() parameter order. - - 2017-08-04: Joel Cunningham - * tcp: re-work persist timer to fully close window (details in bug #50837) - - 2017-07-26: Simon Goldschmidt - * snmp_msg.c: fix bug #51578 (SNMP failed to decode some values on non 32bit platforms) - - 2017-07-20: Simon Goldschmidt - * compatibility headers: moved from 'src/include/posix' to 'src/include/compat/posix', - 'src/include/compat/stdc' etc. - - 2017-05-09: Joel Cunningham - * tcp: add zero-window probe timeout (bug #50837) - - 2017-04-11: Simon Goldschmidt - * sockets.c: task #14420 (Remove sys_sem_signal from inside SYS_ARCH_PROTECT - crit section) done for LWIP_TCPIP_CORE_LOCKING==1 - - 2017-03-08: Joel Cunningham - * tcp: initialize ssthresh to TCP_SND_BUF (bug #50476) - - 2017-03-01: Simon Goldschmidt - * httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved - is called nested from httpd_post_receive_data() (bug #50424) - - 2017-02-28: David van Moolenbroek/Simon Goldschmidt - * tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb - - 2017-02-24: Simon Goldschmidt - * sockets.c: fixed close race conditions in lwip_select (for LWIP_NETCONN_FULLDUPLEX) - - 2017-02-24: Simon Goldschmidt - * sockets.c: fixed that select ignored invalid/not open sockets in the fd_sets (bug #50392) - - 2017-02-16: Simon Goldschmidt - * LWIP_NETCONN_FULLDUPLEX: fixed shutdown during write (bug #50274) - - 2017-01-18: Dirk Ziegelmeier - * Fix zero-copy RX, see bug bug #50064. PBUF_REFs were not supported as ARP requests. - - 2017-01-11: David van Moolenbroek - * Lots of IPv6 related fixes and improvements - -(STABLE-2.0.1) - - ++ New features: - - 2016-12-31: Simon Goldschmidt - * tcp.h/.c: added function tcp_listen_with_backlog_and_err() to get the error - reason when listening fails (bug #49861) - - 2016-12-20: Erik Andersen - * Add MQTT client - - 2016-12-14: Jan Breuer: - * opt.h, ndc.h/.c: add support for RDNSS option (as per RFC 6106) - - 2016-12-14: David van Moolenbroek - * opt.h, nd6.c: Added LWIP_HOOK_ND6_GET_GW() - - 2016-12-09: Dirk Ziegelmeier - * ip6_frag.c: Implemented support for LWIP_NETIF_TX_SINGLE_PBUF - - 2016-12-09: Simon Goldschmidt - * dns.c: added one-shot multicast DNS queries - - 2016-11-24: Ambroz Bizjak, David van Moolenbroek - * tcp_out.c: Optimize passing contiguous nocopy buffers to tcp_write (bug #46290) - - 2016-11-16: Dirk Ziegelmeier - * sockets.c: added support for IPv6 mapped IPv4 addresses - - ++ Bugfixes: - - 2016-12-16: Thomas Mueller - * api_lib.c: fixed race condition in return value of netconn_gethostbyname() - (and thus also lwip_gethostbyname/_r() and lwip_getaddrinfo()) - - 2016-12-15: David van Moolenbroek - * opt.h, tcp: added LWIP_HOOK_TCP_ISN() to implement less predictable initial - sequence numbers (see contrib/addons/tcp_isn for an example implementation) - - 2016-12-05: Dirk Ziegelmeier - * fixed compiling with IPv4 disabled (IPv6 only case) - - 2016-11-28: Simon Goldschmidt - * api_lib.c: fixed bug #49725 (send-timeout: netconn_write() can return - ERR_OK without all bytes being written) - - 2016-11-28: Ambroz Bizjak - * tcpi_in.c: fixed bug #49717 (window size in received SYN and SYN-ACK - assumed scaled) - - 2016-11-25: Simon Goldschmidt - * dhcp.c: fixed bug #49676 (Possible endless loop when parsing dhcp options) - - 2016-11-23: Dirk Ziegelmeier - * udp.c: fixed bug #49662: multicast traffic is now only received on a UDP PCB - (and therefore on a UDP socket/netconn) when the PCB is bound to IP_ADDR_ANY - - 2016-11-16: Dirk Ziegelmeier - * *: Fixed dual-stack behaviour, IPv6 mapped IPv4 support in socket API - - 2016-11-14: Joel Cunningham - * tcp_out.c: fixed bug #49533 (start persist timer when unsent seg can't fit - in window) - - 2016-11-16: Roberto Barbieri Carrera - * autoip.c: fixed bug #49610 (sometimes AutoIP fails to reuse the same address) - - 2016-11-11: Dirk Ziegelmeier - * sockets.c: fixed bug #49578 (dropping multicast membership does not work - with LWIP_SOCKET_OFFSET) - -(STABLE-2.0.0) - - ++ New features: - - 2016-07-27: Simon Goldschmidt - * opt.h, timeouts.h/.c: added LWIP_TIMERS_CUSTOM to override the default - implementation of timeouts - - 2016-07-xx: Dirk Ziegelmeier - * Large overhaul of doxygen documentation - - 2016-04-05: Simon Goldschmidt - * timers.h/.c: prepare for overriding current timeout implementation: all - stack-internal caclic timers are avaliable in the lwip_cyclic_timers array - - 2016-03-23: Simon Goldschmidt - * tcp: call accept-callback with ERR_MEM when allocating a pcb fails on - passive open to inform the application about this error - ATTENTION: applications have to handle NULL pcb in accept callback! - - 2016-02-22: Ivan Delamer - * Initial 6LoWPAN support - - 2016-02-XX to 2016-03-XX: Dirk Ziegelmeier - * Cleanup TCPIP thread sync methods in a way that it is possibe to use them - in arbitrary code that needs things to be done in TCPIP thread. Used to - decouple netconn, netif, ppp and 6LoWPAN from LWIP core. - - 2016-02-XX: Dirk Ziegelmeier - * Implement dual-stack support in RAW, UDP and TCP. Add new IP address - type IPADDR_ANY_TYPE for this. Netconn/Socket API: Dual-stack is - automatically supported when an IPv6 netconn/socket is created. - - 2015-12-26: Martin Hentschel and Dirk Ziegelmeier - * Rewrite SNMP agent. SNMPv2c + MIB compiler. - - 2015-11-12: Dirk Ziegelmeier - * Decouple SNMP stack from lwIP core and move stack to apps/ directory. - Breaking change: Users have to call snmp_init() now! - - 2015-11-12: Dirk Ziegelmeier - * Implement possibility to declare private memory pools. This is useful to - decouple some apps from the core (SNMP stack) or make contrib app usage - simpler (httpserver_raw) - - 2015-10-09: Simon Goldschmidt - * started to move "private" header files containing implementation details to - "lwip/priv/" include directory to seperate the API from the implementation. - - 2015-10-07: Simon Goldschmidt - * added sntp client as first "supported" application layer protocol implementation - added 'apps' folder - - 2015-09-30: Dirk Ziegelmeier - * snmp_structs.h, mib_structs.c, mib2.c: snmp: fixed ugly inheritance - implementation by aggregating the "base class" (struct mib_node) in all - derived node classes to get more type-safe code - - 2015-09-23: Simon Goldschmidt - * netif.h/.c, nd6.c: task #13729: Convert netif addresses (IPv4 & IPv6) to - ip_addr_t (so they can be used without conversion/temporary storage) - - 2015-09-08: Dirk Ziegelmeier - * snmp: Separate mib2 counter/table callbacks from snmp agent. This both cleans - up the code and should allow integration of a 3rd party agent/mib2. Simple - counters are kept in MIB2_STATS, tree/table change function prototypes moved to - snmp_mib2.h. - - 2015-09-03: Simon Goldschmidt - * opt.h, dns.h/.c: DNS/IPv6: added support for AAAA records - - 2015-09-01: Simon Goldschmidt - * task #12178: hardware checksum capabilities can be configured per netif - (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function) - - 2015-08-30: Simon Goldschmidt - * PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in - contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required) - - 2015-08-30: Simon Goldschmidt - * support IPv4 source based routing: define LWIP_HOOK_IP4_ROUTE_SRC to point - to a routing function - - 2015-08-05: Simon Goldschmidt - * many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF - and IP_MULTICAST_LOOP to be used without IGMP - - 2015-04-24: Simon Goldschmidt - * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to - check for the source of address assignment (replacement for NETIF_FLAG_DHCP) - - 2015-04-10: Simon Goldschmidt - * many files: task #13480: added LWIP_IPV4 define - IPv4 can be disabled, - leaving an IPv6-only stack - - 2015-04-09: Simon Goldschmidt - * nearly all files: task #12722 (improve IPv4/v6 address handling): renamed - ip_addr_t to ip4_addr_t, renamed ipX_addr_t to ip_addr_t and added IP - version; ip_addr_t is used for all generic IP addresses for the API, - ip(4/6)_addr_t are only used internally or when initializing netifs or when - calling version-related functions - - 2015-03-24: Simon Goldschmidt - * opt.h, ip4_addr.h, ip4.c, ip6.c: loopif is not required for loopback traffic - any more but passed through any netif (ENABLE_LOOPBACK has to be enabled) - - 2015-03-23: Simon Goldschmidt - * opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP - addresses on multiple netifs should now be working correctly (if correctly - addressed by routing, that is) - - 2015-03-23: Simon Goldschmidt - * etharp.c: Stable etharp entries that are about to expire are now refreshed - using unicast to prevent unnecessary broadcast. Only if no answer is received - after 15 seconds, broadcast is used. - - 2015-03-06: Philip Gladstone - * netif.h/.c: patch #8359 (Provide utility function to add an IPv6 address to - an interface) - - 2015-03-05: Simon Goldschmidt - * netif.c, ip4.c, dhcp.c, autoip.c: fixed bug #37068 (netif up/down handling - is unclear): correclty separated administrative status of a netif (up/down) - from 'valid address' status - ATTENTION: netif_set_up() now always has to be called, even when dhcp/autoip - is used! - - 2015-02-26: patch by TabascoEye - * netif.c, udp.h/.c: fixed bug #40753 (re-bind UDP pcbs on change of IP address) - - 2015-02-22: chrysn, Simon Goldschmidt - * *.*: Changed nearly all functions taking 'ip(X)_addr_t' pointer to take - const pointers (changed user callbacks: raw_recv_fn, udp_recv_fn; changed - port callbacks: netif_output_fn, netif_igmp_mac_filter_fn) - - 2015-02-19: Ivan Delamer - * netif.h, dhcp.c: Removed unused netif flag for DHCP. The preferred way to evaluate - if DHCP is active is through netif->dhcp field. - - 2015-02-19: Ivan Delamer - * netif.h, slipif.c, ppp.c: Removed unused netif flag for point to point connections - - 2015-02-18: Simon Goldschmidt - * api_lib.c: fixed bug #37958 "netconn API doesn't handle correctly - connections half-closed by peer" - - 2015-02-18: Simon Goldschmidt - * tcp.c: tcp_alloc() prefers killing CLOSING/LAST_ACK over active connections - (see bug #39565) - - 2015-02-16: Claudius Zingerli, Sergio Caprile - * opt.h, dhcp.h/.c: patch #8361 "Add support for NTP option in DHCP" - - 2015-02-14: Simon Goldschmidt - * opt.h, snmp*: added support for write-access community and dedicated - community for sending traps - - 2015-02-13: Simon Goldschmidt - * opt.h, memp.c: added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when - a memp pool was empty and an item is now available - - 2015-02-13: Simon Goldschmidt - * opt.h, pbuf.h/.c, etharp.c: Added the option PBUF_LINK_ENCAPSULATION_HLEN to - allocate additional header space for TX on netifs requiring additional headers - - 2015-02-12: chrysn - * timers.h/.c: introduce sys_timeouts_sleeptime (returns the time left before - the next timeout is due, for NO_SYS==1) - - 2015-02-11: Nick van Ijzendoorn - * opt.h, sockets.h/c: patch #7702 "Include ability to increase the socket number - with defined offset" - - 2015-02-11: Frederick Baksik - * opt.h, def.h, others: patch #8423 "arch/perf.h" should be made an optional item - - 2015-02-11: Simon Goldschmidt - * api_msg.c, opt.h: started to implement fullduplex sockets/netconns - (note that this is highly unstable yet!) - - 2015-01-17: Simon Goldschmidt - * api: allow enabling socket API without (public) netconn API - netconn API is - still used by sockets, but keeping it private (static) should allow better - compiler optimizations - - 2015-01-16: Simon Goldschmidt - * tcp_in.c: fixed bug #20506 "Initial congestion window is very small" again - by implementing the calculation formula from RFC3390 - - 2014-12-10: Simon Goldschmidt - * api: added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread - instead of using one per netconn and per select call - - 2014-12-08: Simon Goldschmidt - * ip6.h: fixed bug #43778: IPv6 header version not set on 16-bit platform - (macro IP6H_VTCFL_SET()) - - 2014-12-08: Simon Goldschmidt - * icmp.c, ip4.c, pbuf.c, udp.c, pbuf.h: task #11472 Support PBUF_REF for RX - (IPv6 and IPv4/v6 reassembly might not work yet) - - 2014-11-06: Simon Goldschmidt - * sockets.c/.h, init.c: lwip_socket_init() is not needed any more - -> compatibility define - - 2014-09-16: Simon Goldschmidt - * dns.c, opt.h: reduced ram usage by parsing DNS responses in place - - 2014-09-16: Simon Goldschmidt - * pbuf.h/.c: added pbuf_take_at() and pbuf_put_at() - - 2014-09-15: Simon Goldschmidt - * dns.c: added source port randomization to make the DNS client more robust - (see bug #43144) - - 2013-09-02: Simon Goldschmidt - * arch.h and many other files: added optional macros PACK_STRUCT_FLD_8() and - PACK_STRUCT_FLD_S() to prevent gcc 4 from warning about struct members that - do not need packing - - 2013-08-19: Simon Goldschmidt - * netif.h: bug #42998: made NETIF_MAX_HWADDR_LEN overridable for some special - networks - - 2013-03-17: Simon Goldschmidt (patch by Ghobad Emadi) - * opt.h, etharp.c: Added LWIP_HOOK_ETHARP_GET_GW to implement IPv4 routing with - multiple gateways - - 2013-04-20: Fatih Asici - * opt.h, etharp.h/.c: patch #7993: Added support for transmitting packets - with VLAN headers via hook function LWIP_HOOK_VLAN_SET and to check them - via hook function LWIP_HOOK_VLAN_CHECK - - 2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko) - * patch #7885: modification of api modules to support FreeRTOS-MPU - (don't pass stack-pointers to other threads) - - 2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab") - * patch #6537/#7858: TCP window scaling support - - 2014-01-17: Jiri Engelthaler - * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and - IPv6 ICMP's - - 2012-08-22: Sylvain Rochet - * New PPP stack for lwIP, developed in ppp-new branch. - Based from pppd 2.4.5, released 2009-11-17, with huge changes to match - code size and memory requirements for embedded devices, including: - - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which - is more or less what pppd sys-* files are, so that we get something working - using the unix port. - - Merged some patchs from lwIP Git repository which add interesting features - or fix bugs. - - Merged some patchs from Debian pppd package which add interesting features - or fix bugs. - - Ported PPP timeout handling to the lwIP timers system - - Disabled all the PPP code using filesystem access, replaced in necessary cases - to configuration variables. - - Disabled all the PPP code forking processes. - - Removed IPX support, lwIP does not support IPX. - - Ported and improved random module from the previous PPP port. - - Removed samba TDB (file-driven database) usage, because it needs a filesystem. - - MS-CHAP required a DES implementation, we added the latest PolarSSL DES - implementation which is under a BSD-ish license. - - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be - used in embedded devices with reduced memory footprint. - - Removed PPP configuration file parsing support. - - Added macro definition EAP_SUPPORT to make EAP support optional. - - Added macro definition CHAP_SUPPORT to make CHAP support optional. - - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional. - - Added macro definition PAP_SUPPORT to make PAP support optional. - - Cleared all Linux syscall calls. - - Disabled demand support using a macro, so that it can be ported later. - - Disabled ECP support using a macro, so that it can be ported later. - - Disabled CCP support using a macro, so that it can be ported later. - - Disabled CBCP support using a macro, so that it can be ported later. - - Disabled LQR support using a macro, so that it can be ported later. - - Print packet debug feature optional, through PRINTPKT_SUPPORT - - Removed POSIX signal usage. - - Fully ported PPPoS code from the previous port. - - Fully ported PPPoE code from the previous port. - - Fully ported VJ compression protocol code from the previous port. - - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF. - - Disabled PPP server support using a macro, so that it can be ported later. - - Switched all PPP debug to lwIP debug system. - - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere, - removed all global variables everywhere, did everything necessary for - the PPP stack to support more than one PPP session (pppd only support - one session per process). - - Removed the statically allocated output buffer, now using PBUF. - - Improved structure size of all PPP modules, deep analyze of code to reduce - variables size to the bare minimum. Switched all boolean type (char type in - most architecture) to compiler generated bitfields. - - Added PPP IPv6 support, glued lwIP IPv6 support to PPP. - - Now using a persistent netif interface which can then be used in lwIP - functions requiring a netif. - - Now initializing PPP in lwip_init() function. - - Reworked completely the PPP state machine, so that we don't end up in - anymore in inconsistent state, especially with PPPoE. - - Improved the way we handle PPP reconnection after disconnect, cleaning - everything required so that we start the PPP connection again from a - clean state. - - Added PPP holdoff support, allow the lwIP user to wait a little bit before - reconnecting, prevents connection flood, especially when using PPPoL2TP. - - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client - feature to lwIP, L2TP being a widely used tunnel protocol. - - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...) - - Added PPP API "sequential" thread-safe API, based from NETIFAPI. - - 2011-07-21: Simon Goldschmidt - * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes - ioctl/FIONREAD return the size of the next pending datagram. - - 2011-05-25: Simon Goldschmidt - * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, - combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 - and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP - code so that the code is more readable. - - 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) - * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to - Ivan! (this is work in progress: we're just post release anyway :-) - - - ++ Bugfixes: - - 2016-08-23: Simon Goldschmidt - * etharp: removed ETHARP_TRUST_IP_MAC since it is insecure and we don't need - it any more after implementing unicast ARP renewal towards arp entry timeout - - 2016-07-20: Simon Goldschmidt - * memp.h/.c: fixed bug #48442 (memp stats don't work for MEMP_MEM_MALLOC) - - 2016-07-21: Simon Goldschmidt (patch by Ambroz Bizjak) - * tcp_in.c, tcp_out.c: fixed bug #48543 (TCP sent callback may prematurely - report sent data when only part of a segment is acked) and don't include - SYN/FIN in snd_buf counter - - 2016-07-19: Simon Goldschmidt - * etharp.c: fixed bug #48477 (ARP input packet might update static entry) - - 2016-07-11: Simon Goldschmidt - * tcp_in.c: fixed bug #48476 (TCP sent callback called wrongly due to picking - up old pcb->acked - - 2016-06-30: Simon Goldschmidt (original patch by Fabian Koch) - * tcp_in.c: fixed bug #48170 (Vulnerable to TCP RST spoofing) - - 2016-05-20: Dirk Ziegelmeier - * sntp.h/.c: Fix return value of sntp_getserver() call to return a pointer - - 2016-04-05: Simon Goldschmidt (patch by Philip Gladstone) - * udp.c: patch #8358: allow more combinations of listening PCB for IPv6 - - 2016-04-05: Simon Goldschmidt - * netconn/socket API: fixed bug# 43739 (Accept not reporting errors about - aborted connections): netconn_accept() returns ERR_ABRT (sockets: ECONNABORTED) - for aborted connections, ERR_CLSD (sockets: EINVAL) if the listening netconn - is closed, which better seems to follow the standard. - - 2016-03-23: Florent Matignon - * dhcp.c: fixed bug #38203: DHCP options are not recorded in all DHCP ack messages - - 2016-03-22: Simon Goldschmidt - * tcp: changed accept handling to be done internally: the application does not - have to call tcp_accepted() any more. Instead, when delaying accept (e.g. sockets - do), call tcp_backlog_delayed()/tcp_backlog_accepted() (fixes bug #46696) - - 2016-03-22: Simon Goldschmidt - * dns.c: ignore dns response parsing errors, only abort resolving for correct - responses or error responses from correct server (bug #47459) - - 2016-03-17: Simon Goldschmidt - * api_msg.c: fixed bug #47448 (netconn/socket leak if RST is received during close) - - 2016-03-17: Joel Cunningham - * api_msg.c: don't fail closing a socket/netconn when failing to allocate the - FIN segment; blocking the calling thread for a while is better than risking - leaking a netconn/socket (see bug #46701) - - 2016-03-16: Joel Cunningham - * tcp_out.c: reset rto timer on fast retransmission - - 2016-03-16: Deomid Ryabkov - * tcp_out.c: fixed bug #46384 Segment size calculation bug with MSS != TCP_MSS - - 2016-03-05: Simon Goldschmidt - * err.h/.c, sockets.c: ERR_IF is not necessarily a fatal error - - 2015-11-19: fix by Kerem Hadimli - * sockets.c: fixed bug #46471: lwip_accept() leaks socket descriptors if new - netconn was already closed because of peer behavior - - 2015-11-12: fix by Valery Ushakov - * tcp_in.c: fixed bug #46365 tcp_accept_null() should call tcp_abort() - - 2015-10-02: Dirk Ziegelmeier/Simon Goldschmidt - * snmp: cleaned up snmp structs API (fixed race conditions from bug #46089, - reduce ram/rom usage of tables): incompatible change for private MIBs - - 2015-09-30: Simon Goldschmidt - * ip4_addr.c: fixed bug #46072: ip4addr_aton() does not check the number range - of all address parts - - 2015-08-28: Simon Goldschmidt - * tcp.c, tcp_in.c: fixed bug #44023: TCP ssthresh value is unclear: ssthresh - is set to the full send window for active open, too, and is updated once - after SYN to ensure the correct send window is used - - 2015-08-28: Simon Goldschmidt - * tcp: fixed bug #45559: Window scaling casts u32_t to u16_t without checks - - 2015-08-26: Simon Goldschmidt - * ip6_frag.h/.c: fixed bug bug #41009: IPv6 reassembly broken on 64-bit platforms: - define IPV6_FRAG_COPYHEADER==1 on these platforms to copy the IPv6 header - instead of referencing it, which gives more room for struct ip6_reass_helper - - 2015-08-25: Simon Goldschmidt - * sockets.c: fixed bug #45827: recvfrom: TCP window is updated with MSG_PEEK - - 2015-08-20: Manoj Kumar - * snmp_msg.h, msg_in.c: fixed bug #43790: Sending octet string of Length >255 - from SNMP agent - - 2015-08-19: Jens Nielsen - * icmp.c, ip4.c, tcp_in.c, udp.c, raw.c: fixed bug #45120: Broadcast & multiple - interfaces handling - - 2015-08-19: Simon Goldschmidt (patch by "Sandra") - * dns.c: fixed bug #45004: dns response without answer might be discarded - - 2015-08-18: Chrysn - * timers.c: patch #8704 fix sys_timeouts_sleeptime function - - 2015-07-01: Erik Ekman - * puf.c: fixed bug #45454 (pbuf_take_at() skips write and returns OK if offset - is at start of pbuf in chain) - - 2015-05-19: Simon Goldschmidt - * dhcp.h/.c: fixed bugs #45140 and #45141 (dhcp was not stopped correctly after - fixing bug #38204) - - 2015-03-21: Simon Goldschmidt (patch by Homyak) - * tcp_in.c: fixed bug #44766 (LWIP_WND_SCALE: tcphdr->wnd was not scaled in - two places) - - 2015-03-21: Simon Goldschmidt - * tcp_impl.h, tcp.c, tcp_in.c: fixed bug #41318 (Bad memory ref in tcp_input() - after tcp_close()) - - 2015-03-21: Simon Goldschmidt - * tcp_in.c: fixed bug #38468 (tcp_sent() not called on half-open connection for - data ACKed with the same ack as FIN) - - 2015-03-21: Simon Goldschmidt (patch by Christoffer Lind) - * dhcp.h/.c: fixed bug #38204 (DHCP lease time not handled correctly) - - 2015-03-20: Simon Goldschmidt - * dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message) - - 2015-03-19: Simon Goldschmidt - * api.h, tcpip.h, api_lib.c, api_msg.c: fixed race conditions in assigning - netconn->last_err (fixed bugs #38121 and #37676) - - 2015-03-09: Simon Goldschmidt - * ip4.c: fixed the IPv4 part of bug #43904 (ip_route() must detect linkup status) - - 2015-03-04: Simon Goldschmidt - * nd6.c: fixed bug #43784 (a host should send at least one Router Solicitation) - - 2015-03-04: Valery Ushakov - * ip6.c: fixed bug #41094 (Byte-order bug in IPv6 fragmentation header test) - - 2015-03-04: Zach Smith - * nd6.c: fixed bug #38153 (nd6_input() byte order issues) - - 2015-02-26: Simon Goldschmidt - * netif.c, tcp.h/.c: fixed bug #44378 (TCP connections are not aborted on netif - remove) - - 2015-02-25: Simon Goldschmidt - * ip4.c, etharp.c: fixed bug #40177 (System hangs when dealing with corrupted - packets), implemented task #12357 (Ensure that malicious packets don't - assert-fail): improved some pbuf_header calls to not assert-fail. - - 2015-02-25: patch by Joel Cunningham - * udp.h/.c, sockets.c: fixed bug #43028 (IP_MULTICAST_TTL affects unicast - datagrams) - - 2015-02-25: patch by Greg Renda - * ip4_frag.c: fixed bug #38210 (ip reassembly while remove oldest datagram) - - 2015-02-25: Simon Goldschmidt - * sockets.c: fixed bug #38165 (socket with mulicast): ensure igmp membership - are dropped when socket (not netconn!) is closed. - - 2015-02-25: Simon Goldschmidt - * ip4.h/.c, udp.c: fixed bug #38061 (wrong multicast routing in IPv4) by - adding an optional default netif for multicast routing - - 2015-02-25: Simon Goldschmidt - * netconn API: fixed that netconn_connect still used message passing for - LWIP_TCPIP_CORE_LOCKING==1 - - 2015-02-22: patch by Jens Nielsen - * icmp.c: fixed bug #38803 (Source address in broadcast ping reply) - - 2015-02-22: Simon Goldschmidt - * udp.h, sockets.c: added proper accessor functions for pcb->multicast_ip - (previously used by get/setsockopt only) - - 2015-02-18: Simon Goldschmidt - * sockets.c: Fixed select not reporting received FIN as 'readable' in certain - rare cases (bug #43779: select(), close(), and TCP retransmission error) - - 2015-02-17: Simon Goldschmidt - * err.h, sockets.c, api_msg.c: fixed bug #38853 "connect() use a wrong errno": - return ERR_ALREADY/EALRADY during connect, ERR_ISCONN/EISCONN when already - connected - - 2015-02-17: Simon Goldschmidt - * tcp_impl.h, tcp_out.c, tcp.c, api_msg.c: fixed bug #37614 "Errors from - ipX_output are not processed". Now tcp_output(_segment) checks for the return - value of ipX_output and does not try to send more on error. A netif driver - can call tcp_txnow() (from tcpip_thread!) to try to send again if TX buffers - are available again. - - 2015-02-14: patches by Freddie Chopin - * snmp*: made community writable, fixed some const pointers - - 2015-02-13: Simon Goldschmidt - * msg_in.c: fixed bug #22070 "MIB_OBJECT_WRITE_ONLY not implemented in SNMP" - - 2015-02-12: Simon Goldschmidt - * ip.h, ip4.c, ip6.c: fixed bug #36403 "ip4_input() and ip6_input() always pass - inp to higher layers": now the accepting netif is passed up, but the input - netif is available through ip_current_input_netif() if required. - - 2015-02-11: patch by hichard - * tcpip.c: fixed bug #43094 "The function tcpip_input() forget to handle IPv6" - - 2015-02-10: Simon Goldschmidt - * netconn API: fixed that netconn_close/netconn_delete still used message passing - for LWIP_TCPIP_CORE_LOCKING==1 - - 2015-02-10: Simon Goldschmidt - * netconn/socket api: fixed bug #44225 "closing TCP socket should time out - eventually", implemented task #6930 "Implement SO_LINGER": closing TCP sockets - times out after 20 seconds or after the configured SND_TIMEOUT or depending - on the linger settings. - - 2015-01-27: Simon Goldschmidt - * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR, - fixed return value of lwip_netconn_do_close on unconnected netconns - - 2015-01-17: Simon Goldschmidt - * sockets.c: fixed bug #43361 select() crashes with stale FDs - - 2015-01-17: Simon Goldschmidt - * sockets.c/.h, memp_std.h: fixed bug #40788 "lwip_setsockopt_internal() crashes" - by rewriting set/getsockopt functions to combine checks with the actual code - and add more NULL checks; this also fixes that CORE_LOCKING used message - passing for set/getsockopt. - - 2014-12-19: Simon Goldschmidt - * opt.h, dhcp.h/.c: prevent dhcp from starting when netif link is down (only - when LWIP_DHCP_CHECK_LINK_UP==1, which is disabled by default for - compatibility reasons) - - 2014-12-17: Simon Goldschmidt - * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for - no-copy data with odd length - - 2014-12-10: Simon Goldschmidt - * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO - take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can - be used to revert to the old 'winsock' style behaviour) - Fixed implementation of SO_ACCEPTCONN to just look at the pcb state - - 2014-12-09: Simon Goldschmidt - * ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded - - 2014-10-21: Simon Goldschmidt (patch by Joel Cunningham and Albert Huitsing) - * sockts.c: fixed bugs #41495 Possible threading issue in select() and #43278 - event_callback() handle context switch when calling sys_sem_signal() - - 2014-10-21: Simon Goldschmidt - * api_msg.c: fixed bug #38219 Assert on TCP netconn_write with sndtimeout set - - 2014-09-16: Kevin Cernekee - * dns.c: patch #8480 Fix handling of dns_seqno wraparound - - 2014-09-16: Simon Goldschmidt - * tcp_out.c: fixed bug #43192 tcp_enqueue_flags() should not check TCP_SND_QUEUELEN - when sending FIN - - 2014-09-03: Simon Goldschmidt - * msg_in.c: fixed bug #39355 SNMP Memory Leak in case of error - - 2014-09-02: Simon Goldschmidt - * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before - listen() will cause a error - - 2014-09-02: Simon Goldschmidt - * sockets.c: fixed bug #42117 lwip_fcntl does not set errno - - 2014-09-02: Simon Goldschmidt - * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list - - 2014-08-20: Simon Goldschmidt - * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to - non-randomized TXIDs - - 2014-06-03: Simon Goldschmidt - * tcp_impl.h, tcp_in.c: fixed bug #37969 SYN packet dropped as short packet in - tcp_input function - - 2014-05-20: Simon Goldschmidt - * tcp_out.c: fixed bug #37184 tcp_write problem for pcbs in the SYN_SENT state - - 2014-05-19: Simon Goldschmidt - * *.h: Fixed bug #35874 reserved identifier violation (removed leading underscores - from header include guards) - - 2014-04-08: Simon Goldschmidt - * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window) - - 2014-04-06: Simon Goldschmidt - * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received - unacceptable ACK - - 2014-04-06: Simon Goldschmidt - * dhcp.c, ip4.c/.h, ip6.c/.h, udp.c/.h, ip.h: Fixed bug #41787 DHCP Discovery - is invalid when an IP is set to thet netif. - - 2014-03-14: Simon Goldschmidt - * tcp_out.c: Fixed bug #36153 TCP Cheksum error if LWIP_CHECKSUM_ON_COPY=1 - - 2014-03-11: Simon Goldschmidt (patch by Mason) - * opt.h, sockets.c: fixed bug #35928 BSD sockets functions must set errno for - POSIX-compliance - - 2014-02-27: Simon Goldschmidt - * dhcp.c: fixed bug #40303 DHCP xid renewed when sending a DHCPREQUEST - - 2014-02-27: Simon Goldschmidt - * raw.c: fixed bug #41680 raw socket can not receive IPv6 packet when - IP_SOF_BROADCAST_RECV==1 - - 2014-02-27: Simon Goldschmidt - * api_msg.c, sockets.c: fixed bug #38404 getpeeraddr returns success on - unconnected/listening TCP sockets - - 2014-02-27: Simon Goldschmidt - * sockets.c: fixed bug #41729 Some socket functions return Exyz instead of -1 - - 2014-02-25: Simon Goldschmidt - * ip4.c: fixed bug #39514 ip_route() may return an IPv6-only interface - - 2014-02-25: Simon Goldschmidt, patch by Fatih Asici - * pbuf.c: fixed bug #39356 Wrong increment in pbuf_memfind() - - 2014-02-25: Simon Goldschmidt - * netif.c/.h, udp.c: fixed bug #39225 udp.c uses netif_matches_ip6_addr() incorrectly; - renamed function netif_matches_ip6_addr() to netif_get_ip6_addr_match() - - 2014-02-25: Simon Goldschmidt - * igmp.c: fixed bug #39145 IGMP membership report for 224.0.0.1 - - 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) - * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) - - 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) - * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry - - 2014-02-20: Simon Goldschmidt - * tcp_out.c: fixed bug #39683 Assertion "seg->tcphdr not aligned" failed with - MEM_ALIGNMENT = 8 - - 2014-02-20: Simon Goldschmidt - * sockets.c: fixed bug #39882 No function shall set errno to 0 - - 2014-02-20: Simon Goldschmidt - * mib_structs.c: fixed bug #40050 SNMP problem with MIB arrays > 255 - - 2014-02-20: Simon Goldschmidt - * api.h, sockets.c: fixed bug #41499 netconn::recv_avail can overflow - - 2014-01-08: Stathis Voukelatos - * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool - creation macro - - 2014-01-18: Brian Fahs - * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize - when necessary - - 2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt - * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback - - 2014-01-16: Stathis Voukelatos - * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0 - - 2014-01-14: "Freddie Chopin" - * snmp.h, mib2.c: fixed constness and spelling of sysdescr - - 2014-01-14: Simon Goldschmidt (patch by Thomas Faber) - * tcpip.c: patch #8241: Fix implicit declaration of ip_input with - LWIP_TCPIP_CORE_LOCKING_INPUT disabled - - 2014-01-14: chrysn - * timers.c: patch #8244 make timeouts usable reliably from outside of the - timeout routine - - 2014-01-10: Simon Goldschmidt - * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly - - 2014-01-10: Simon Goldschmidt - * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1 - - 2014-01-10: Simon Goldschmidt - * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop - - 2013-06-29: Simon Goldschmidt - * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs) - - 2013-06-29: Simon Goldschmidt - * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec - - 2013-04-24: patch by Liam - * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert - - 2013-04-24: Simon Goldschmidt - * igmp.c: fixed possible division by zero - - 2013-04-24: Simon Goldschmidt - * ip6.h, some ipv6 C files: fixed bug #38526 Coverity: Recursive Header Inclusion in ip6.h - - 2013-04-24: Simon Goldschmidt (patch by Emil Ljungdahl): - * netif.c: fixed bug #38586 netif_loop_output() "deadlocks" - - 2013-01-15: Simon Goldschmidt - * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order - - 2013-01-15: Simon Goldschmidt - * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning - - 2013-01-14: Simon Goldschmidt - * dns.c: fixed bug #37705 Possible memory corruption in DNS query - - 2013-01-11: Simon Goldschmidt - * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it - - 2012-08-22: Simon Goldschmidt - * memp.c: fixed bug #37166: memp_sanity check loops itself - - 2012-08-13: Simon Goldschmidt - * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start - dereferences NULL - - 2012-08-13: Simon Goldschmidt - * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps - configured but no interfaces available - - 2012-08-13: Simon Goldschmidt - * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time - - 2012-05-11: Simon Goldschmidt (patch by Marty) - * memp.c: fixed bug #36412: memp.c does not compile when - MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 - - 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) - * ppp.c: fixed bug #36283 (PPP struct used on header size computation and - not packed) - - 2012-05-03: Simon Goldschmidt (patch by David Empson) - * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with - zero length) - - 2012-03-25: Simon Goldschmidt - * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed - for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 - - 2012-03-25: Simon Goldschmidt - * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space - pollution in api_msg.c and netifapi.c - - 2011-08-24: Simon Goldschmidt - * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard - - - -(STABLE-1.4.1) - - ++ New features: - - 2012-03-25: Simon Goldschmidt (idea by Mason) - * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h - which are a simple wrapper to the correct lwIP include files. - - 2012-01-16: Simon Goldschmidt - * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP - - 2011-12-17: Simon Goldschmidt - * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) - (fixes bug #35061) - - 2011-09-27: Simon Goldschmidt - * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) - (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) - - 2011-09-21: Simon Goldschmidt - * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on - send (TCP only, bug #33820) - - 2011-09-21: Simon Goldschmidt - * init.c: Converted runtime-sanity-checks into compile-time checks that can - be disabled (since runtime checks can often not be seen on embedded targets) - - 2011-09-11: Simon Goldschmidt - * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file - to get a clear separation of which functions an application or port may use - (task #11281) - - 2011-09-11: Simon Goldschmidt - * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize - initial local TCP/UDP ports (so that different port ranges are used after - a reboot; bug #33818; this one added tcp_init/udp_init functions again) - - 2011-09-03: Simon Goldschmidt - * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) - - 2011-08-24: Simon Goldschmidt - * opt.h, netif.h/.c: added netif remove callback (bug #32397) - - 2011-07-26: Simon Goldschmidt - * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter - function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) - - 2011-07-21: Simon Goldschmidt (patch by hanhui) - * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: - Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. - Also added code to allow ip_forward() to forward non-broadcast packets to - the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). - - 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) - * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that - pcb->state != LISTEN - - 2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage) - * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static - memory message - - - ++ Bugfixes: - - 2012-09-26: Simon Goldschmidt - * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7843 Fix corner case with dhcp timeouts - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet - - 2012-08-22: Simon Goldschmidt - * memp.c: fixed bug #37166: memp_sanity check loops itself - - 2012-05-08: Simon Goldschmidt - * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was - a debug-check issue only) - - 2012-03-27: Simon Goldschmidt - * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c - - 2012-03-27: Simon Goldschmidt (patch by Mason) - * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the - send MSS - - 2012-03-22: Simon Goldschmidt - * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward - - 2012-03-20: Simon Goldschmidt (patch by Mason) - * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list - - 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) - * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, - possible bug on little endian system - - 2012-02-23: Simon Goldschmidt - * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt - * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() - (bug #35541: PPP Memory Leak) - - 2012-02-16: Simon Goldschmidt - * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt (patch by Stéphane Lesage) - * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed - - 2012-02-15: Simon Goldschmidt - * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with - MEMP_MEM_MALLOC==1 - - 2012-02-12: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on - MSS > pcb->snd_wnd (by not creating segments bigger than half the window) - - 2012-02-11: Simon Goldschmidt - * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait - queue while closing - - 2012-01-22: Simon Goldschmidt - * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) - - 2012-01-21: Simon Goldschmidt - * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb - - 2012-01-20: Simon Goldschmidt - * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths - - 2012-01-20: Simon Goldschmidt - * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy - - 2011-11-25: Simon Goldschmidt - * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt - tcp_active_pcbs in some cases - - 2011-11-23: Simon Goldschmidt - * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with - '#ifndef sys_msleep' - - 2011-11-22: Simon Goldschmidt - * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when - netif is brought down - - 2011-10-28: Simon Goldschmidt - * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks - - 2011-10-23: Simon Goldschmidt - * mem.c: fixed bug #34429: possible memory corruption with - LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 - - 2011-10-18: Simon Goldschmidt - * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard - error value - - 2011-10-18: Simon Goldschmidt - * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small - windows (bug #34176 select after non-blocking send times out) - - 2011-10-18: Simon Goldschmidt - * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't - consider netif->mtu, causes slow network - - 2011-10-18: Simon Goldschmidt - * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code - - 2011-10-18: Simon Goldschmidt - * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS - - 2011-10-17: Simon Goldschmidt - * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api - - 2011-10-13: Simon Goldschmidt - * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no - zero window is received) by starting the persist timer when a zero window is - received, not when we have more data queued for sending than fits into the - window - - 2011-10-13: Simon Goldschmidt - * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex - - 2011-10-13: Simon Goldschmidt - * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is - used and not all protocols are enabled - - 2011-10-12: Simon Goldschmidt - * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 - - 2011-10-09: Simon Goldschmidt - * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect - byte value when pcb->unacked != NULL - - 2011-10-09: Simon Goldschmidt - * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong - - 2011-09-27: Simon Goldschmidt - * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... - - 2011-09-27: Simon Goldschmidt - * tcp_in.c: fixed bug #28288: Data after FIN in oos queue - - 2011-09-27: Simon Goldschmidt - * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf - - 2011-09-24: Simon Goldschmidt - * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 - - 2011-09-23: Simon Goldschmidt - * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for - the last packet including FIN can lose data - - 2011-09-22: Simon Goldschmidt - * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into - account - - 2011-09-21: Simon Goldschmidt - * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks - in init.c - - 2011-09-20: Simon Goldschmidt - * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) - - 2011-09-11: Simon Goldschmidt - * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs - (bug #34019) - - 2011-09-09: Simon Goldschmidt - * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if - udp port matches - - 2011-09-03: Simon Goldschmidt - * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet - is aggregated and sent to application - - 2011-09-01: Simon Goldschmidt - * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared - to other options - - 2011-09-01: Simon Goldschmidt - * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno - - 2011-08-24: Simon Goldschmidt - * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling - accept() on UDP connections - - 2011-08-24: Simon Goldschmidt - * sockets.h: fixed bug #34057 socklen_t should be a typedef - - 2011-08-24: Simon Goldschmidt - * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) - - 2011-08-24: Simon Goldschmidt - * dhcp.c: fixed bug #34122 dhcp: hostname can overflow - - 2011-08-24: Simon Goldschmidt - * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr - - 2011-08-22: Simon Goldschmidt - * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This - merely prevents nagle from not transmitting fast after closing.) - - 2011-07-22: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns - always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now - lwip_send() sends as much as possible for non-blocking sockets - - 2011-07-22: Simon Goldschmidt - * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented - for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level. - - 2011-07-21: Simon Goldschmidt - * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by - sending an ARP request when an ARP entry is used in the last minute before - it would time out. - - 2011-07-04: Simon Goldschmidt - * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. - - 2011-06-26: Simon Goldschmidt - * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by - updating its documentation only. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an - unaligned pointer. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" - - 2011-05-25: Simon Goldschmidt - * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) - - - -(STABLE-1.4.0) - - ++ New features: - - 2011-03-27: Simon Goldschmidt - * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and - calculate it in tcp_zero_window_probe (the only place where it was used). - - 2010-11-21: Simon Goldschmidt - * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif - (fixes bug #31525). - - 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) - * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for - IP_MULTICAST_LOOP at socket- and raw-API level. - - 2010-06-16: Simon Goldschmidt - * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow - link-layer-addressed UDP traffic to be received while a netif is down (just - like DHCP during configuration) - - 2010-05-22: Simon Goldschmidt - * many many files: bug #27352: removed packing from ip_addr_t, the packed - version is now only used in protocol headers. Added global storage for - current src/dest IP address while in input functions. - - 2010-05-16: Simon Goldschmidt - * def.h: task #10391: Add preprocessor-macros for compile-time htonl - calculation (and use them throughout the stack where applicable) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool - instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own - MEMP pool instead of the heap - - 2010-05-13: Simon Goldschmidt - * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added - new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast - packets to more than one pcb. - - 2010-05-02: Simon Goldschmidt - * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending - UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-04-30: Simon Goldschmidt - * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that - take a precalculated checksum, added pbuf_fill_chksum() to copy data - into a pbuf and at the same time calculating the checksum for that data - - 2010-04-29: Simon Goldschmidt - * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying - 2-byte-aligned IP addresses and MAC addresses - - 2010-04-28: Patch by Bill Auerbach - * ip.c: Inline generating IP checksum to save a function call - - 2010-04-14: Simon Goldschmidt - * tcpip.h/.c, timers.c: Added an overridable define to get informed when the - tcpip_thread processes messages or timeouts to implement a watchdog. - - 2010-03-28: Simon Goldschmidt - * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing - fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-03-27: Simon Goldschmidt - * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ - etharp_query to prevent unnecessary function calls (inspired by - patch #7135). - - 2010-03-20: Simon Goldschmidt - * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code - since the linker cannot do this automatically to save space. - - 2010-03-20: Simon Goldschmidt - * opt.h, etharp.c/.h: Added support for static ARP table entries - - 2010-03-14: Simon Goldschmidt - * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum - when creating TCP segments, not when (re-)transmitting them. - - 2010-03-07: Simon Goldschmidt - * sockets.c: bug #28775 (select/event_callback: only check select_cb_list - on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. - This should speed up receiving data on sockets as the select code in - event_callback is only executed when select is waiting. - - 2010-03-06: Simon Goldschmidt - * tcp_out.c: task #7013 (Create option to have all packets delivered to - netif->output in one piece): Always copy to try to create single pbufs - in tcp_write. - - 2010-03-06: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv - by not allocating a netbuf): added function netconn_recv_tcp_pbuf() - for tcp netconns to receive pbufs, not netbufs; use that function - for tcp sockets. - - 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt - * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: - Work on tcp_enqueue: Don't waste memory when chaining segments, - added option TCP_OVERSIZE to prevent creating many small pbufs when - calling tcp_write with many small blocks of data. Instead, pbufs are - allocated larger than needed and the space is used for later calls to - tcp_write. - - 2010-02-21: Simon Goldschmidt - * stats.c/.h: Added const char* name to mem- and memp-stats for easier - debugging. - - 2010-02-21: Simon Goldschmidt - * tcp.h (and usages), added tcp_impl.h: Splitted API and internal - implementation of tcp to make API usage cleare to application programmers - - 2010-02-14: Simon Goldschmidt/Stephane Lesage - * ip_addr.h: Improved some defines working on ip addresses, added faster - macro to copy addresses that cannot be NULL - - 2010-02-13: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- - blocking send operation) - - 2010-02-12: Simon Goldschmidt - * sockets.c/.h: Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - 2010-02-12: Simon Goldschmidt - * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated - memory): added autoip_set_struct() and dhcp_set_struct() to let autoip - and dhcp work with user-allocated structs instead of callin mem_malloc - - 2010-02-12: Simon Goldschmidt/Jeff Barber - * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has - SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT - - 2010-02-12: Simon Goldschmidt - * sys layer: task #10139 (Prefer statically allocated memory): converted - mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; - converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX - to let sys.h use binary semaphores instead of mutexes - as before) - - 2010-02-09: Simon Goldschmidt (Simon Kallweit) - * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 - (Restart system timeout handling) - - 2010-02-09: Simon Goldschmidt - * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into - netif.c) - loopif does not have to be created by the port any more, - just define LWIP_HAVE_LOOPIF to 1. - - 2010-02-08: Simon Goldschmidt - * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa - inet_ntoa_r/ipaddr_ntoa_r - - 2010-02-08: Simon Goldschmidt - * netif.h: Added netif_s/get_igmp_mac_filter() macros - - 2010-02-05: Simon Goldschmidt - * netif.h: Added function-like macros to get/set the hostname on a netif - - 2010-02-04: Simon Goldschmidt - * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to - make changing the actual implementation behind the typedef easier. - - 2010-02-01: Simon Goldschmidt - * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool - for allocating memory when getaddrinfo() is called. - - 2010-01-31: Simon Goldschmidt - * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse - them once instead of parsing for every option. This also removes - the need for mem_malloc from dhcp_recv and makes it possible to - correctly retrieve the BOOTP file. - - 2010-01-30: simon Goldschmidt - * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect - the sockets array. - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, api_msg.c, sockets.c: Added except set support in select - (patch #6860) - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: - Add non-blocking support for connect (partly from patch #6860), - plus many cleanups in socket & netconn API. - - 2010-01-27: Simon Goldschmidt - * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding - to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 - - 2010-01-26: Simon Goldschmidt - * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. - - 2010-01-14: Simon Goldschmidt - * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback - by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() - - 2010-01-13: Simon Goldschmidt - * mem.c: The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - (patch #6966 and bug #26133) - - 2010-01-10: Simon Goldschmidt (Bill Auerbach) - * opt.h, memp.c: patch #6822 (Add option to place memory pools in - separate arrays) - - 2010-01-10: Simon Goldschmidt - * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define - LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) - - 2009-12-31: Simon Goldschmidt - * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h - added timers.c/.h: Separated timer implementation from semaphore/mbox - implementation, moved timer implementation to timers.c/.h, timers are - now only called from tcpip_thread or by explicitly checking them. - (TASK#7235) - - 2009-12-27: Simon Goldschmidt - * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option - LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) - - - ++ Bugfixes: - - 2011-04-20: Simon Goldschmidt - * sys_arch.txt: sys_arch_timeouts() is not needed any more. - - 2011-04-13: Simon Goldschmidt - * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by - using ports in the IANA private/dynamic range (49152 through 65535). - - 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: - * etharp.h/.c: Fixed broken VLAN support. - - 2011-03-27: Simon Goldschmidt - * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp - pcbs) by checking if the pcb was bound (local_port != 0). - - 2011-03-27: Simon Goldschmidt - * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) - - 2011-03-27: Simon Goldschmidt - * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and - raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. - - 2011-03-27: Simon Goldschmidt - * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route - is present never times out) by starting retransmission timer before checking - route. - - 2011-03-22: Simon Goldschmidt - * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only - calling sio_read_abort() if the file descriptor is valid. - - 2011-03-14: Simon Goldschmidt - * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect - more than once can render a socket useless) since it mainly involves changing - "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. - - 2011-03-13: Simon Goldschmidt - * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing - err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: - use EALRADY instead of -1 - - 2011-03-13: Simon Goldschmidt - * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the - connection has been aborted by err_tcp (since this is not a normal closing - procedure). - - 2011-03-13: Simon Goldschmidt - * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind - with pcb->state != CLOSED - - 2011-02-17: Simon Goldschmidt - * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in - documentation - - 2011-02-17: Simon Goldschmidt - * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. - - 2011-01-24: Simon Goldschmidt - * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems - - 2010-12-02: Simon Goldschmidt - * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. - - 2010-11-23: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for - LWIP_SO_RCVBUF and ioctl/FIONREAD. - - 2010-11-23: Simon Goldschmidt - * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at - least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. - - 2010-11-23: Simon Goldschmidt - * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after - refusing 'refused_data' again. - - 2010-11-22: Simon Goldschmidt - * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS - after a successful nonblocking connection. - - 2010-11-22: Simon Goldschmidt - * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr - must be sent link-local - - 2010-11-22: Simon Goldschmidt - * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for - LWIP_TIMERS==0 - - 2010-11-20: Simon Goldschmidt - * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number - - 2010-11-20: Simon Goldschmidt - * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to - resemble other stacks. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else - no-copy TCP writes will never succeed. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does - not match documentation: return ERR_ARG instead of ERR_VAL if not - initialized or wrong argument. - - 2010-10-20: Simon Goldschmidt - * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 - - 2010-10-05: Simon Goldschmidt - * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when - replugging the network cable after an AutoIP address was assigned. - - 2010-08-10: Simon Goldschmidt - * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs - - 2010-08-03: Simon Goldschmidt - * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) - - 2010-08-01: Simon Goldschmidt (patch by Greg Renda) - * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big - endian architectures) - - 2010-07-28: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP - disabled. - - 2010-07-27: Simon Goldschmidt - * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no - harm but never did anything - - 2010-07-21: Simon Goldschmidt - * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not - add IP options) - - 2010-07-16: Kieran Mansley - * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator - - 2010-07-10: Simon Goldschmidt - * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options - - 2010-06-30: Simon Goldschmidt - * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in - netconn_delete) - - 2010-06-28: Kieran Mansley - * timers.c remove unportable printing of C function pointers - - 2010-06-24: Simon Goldschmidt - * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag - NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading - - 2010-06-24: Simon Goldschmidt - * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly - implemented shutdown at socket level. - - 2010-06-21: Simon Goldschmidt - * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has - problems with zero-copy DMA MACs) by adding custom pbufs and implementing - custom pbufs that reference other (original) pbufs. Additionally set - IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. - - 2010-06-15: Simon Goldschmidt - * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses - - 2010-06-14: Simon Goldschmidt - * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses - - 2010-06-12: Simon Goldschmidt - * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop - state - - 2010-05-17: Simon Goldschmidt - * netdb.c: Correctly NULL-terminate h_addr_list - - 2010-05-16: Simon Goldschmidt - * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent - "symbol already defined" i.e. when linking to winsock - - 2010-05-05: Simon Goldschmidt - * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may - overflow) - - 2010-04-21: Simon Goldschmidt - * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening - connection) - - 2010-03-28: Luca Ceresoli - * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers - - 2010-03-27: Luca Ceresoli - * mib2.c: patch #7130: remove meaningless const qualifiers - - 2010-03-26: Simon Goldschmidt - * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too - - 2010-03-26: Simon Goldschmidt - * various files: Fixed compiling with different options disabled (TCP/UDP), - triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled - - 2010-03-25: Simon Goldschmidt - * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly - - 2010-03-25: Simon Goldschmidt - * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side - overrunning our rcv_wnd in ooseq case. - - 2010-03-22: Simon Goldschmidt - * tcp.c: tcp_listen() did not copy the pcb's prio. - - 2010-03-19: Simon Goldschmidt - * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set - - 2010-03-14: Simon Goldschmidt - * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports - where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h - and basing PBUF_LINK_HLEN on it. - - 2010-03-08: Simon Goldschmidt - * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections - when assiging routable address): when checking incoming packets and - aborting existing connection on address change, filter out link-local - addresses. - - 2010-03-06: Simon Goldschmidt - * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING - - 2010-03-06: Simon Goldschmidt - * ipv4/ip.c: Don't try to forward link-local addresses - - 2010-03-06: Simon Goldschmidt - * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- - addresses to gw - - 2010-03-05: Simon Goldschmidt - * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type - and state. - - 2010-03-05: Simon Goldschmidt - * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split - into multiple calls to tcp_write. - - 2010-02-21: Simon Goldschmidt - * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep - the implementation of DNS_USES_STATIC_BUF==1) - - 2010-02-20: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement - close() vs. shutdown(). Now the application does not get any more - recv callbacks after calling tcp_close(). Added tcp_shutdown(). - - 2010-02-19: Simon Goldschmidt - * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent - confusion with realloc() - - 2010-02-15: Simon Goldschmidt/Stephane Lesage - * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK - (fixes bug #28899) - - 2010-02-14: Simon Goldschmidt - * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with - LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and - admin-status of a netif are up - - 2010-02-14: Simon Goldschmidt - * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet - reception and is not really necessary - - 2010-02-14: Simon Goldschmidt - * etharp.c/.h: Fixed ARP input processing: only add a new entry if a - request was directed as us (RFC 826, Packet Reception), otherwise - only update existing entries; internalized some functions - - 2010-02-14: Simon Goldschmidt - * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be - disabled on netif used for PPPoE) by adding a new netif flag - (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet - device but prevents usage of ARP (so that ethernet_input can be used - for PPPoE). - - 2010-02-12: Simon Goldschmidt - * netif.c: netif_set_link_up/down: only do something if the link state - actually changes - - 2010-02-12: Simon Goldschmidt/Stephane Lesage - * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking - connect) - - 2010-02-12: Simon Goldschmidt - * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) - - 2010-02-09: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 - (recv() makes receive window update for data that wasn't received by - application) - - 2010-02-09: Simon Goldschmidt/Stephane Lesage - * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out - or any netconn_recv() error) - - 2010-02-09: Simon Goldschmidt - * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) - - 2010-02-09: Simon Goldschmidt - * netif.c: For loopback packets, adjust the stats- and snmp-counters - for the loopback netif. - - 2010-02-08: Simon Goldschmidt - * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity - since they are not used anywhere else. - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats - (patch from bug #28798) - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and - another bug when LWIP_RAND() returns zero. - - 2010-02-04: Simon Goldschmidt - * nearly every file: Use macros defined in ip_addr.h (some of them new) - to work with IP addresses (preparation for bug #27352 - Change ip_addr - from struct to typedef (u32_t) - and better code). - - 2010-01-31: Simon Goldschmidt - * netif.c: Don't call the link-callback from netif_set_up/down() since - this invalidly retriggers DHCP. - - 2010-01-29: Simon Goldschmidt - * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the - portability file inet.h and its contents from the stack: moved htonX- - functions to def.h (and the new def.c - they are not ipv4 dependent), - let inet.h depend on ip_addr.h and not the other way round. - This fixes bug #28732. - - 2010-01-28: Kieran Mansley - * tcp.c: Ensure ssthresh >= 2*MSS - - 2010-01-27: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv - callback can lead to accessing unallocated memory. As a consequence, - ERR_ABRT means the application has called tcp_abort()! - - 2010-01-25: Simon Goldschmidt - * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY - not implemented in SNMP): write-only or not-accessible are still - returned by getnext (though not by get) - - 2010-01-24: Simon Goldschmidt - * snmp: Renamed the private mib node from 'private' to 'mib_private' to - not use reserved C/C++ keywords - - 2010-01-23: Simon Goldschmidt - * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less - than 1 ms - - 2010-01-21: Simon Goldschmidt - * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called - if tcp_enqueue fails) both in raw- and netconn-API - - 2010-01-19: Simon Goldschmidt - * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp - - 2010-01-18: Iordan Neshev/Simon Goldschmidt - * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some - bugfix backports from 2.4.x. - - 2010-01-18: Simon Goldschmidt - * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong - - 2010-01-17: Simon Goldschmidt - * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): - task #10102: "netconn: clean up conn->err threading issues" by adding - error return value to struct api_msg_msg - - 2010-01-17: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() - to return err_t (bugs #27709 and #28087) - - 2010-01-14: Simon Goldschmidt - * ...: Use typedef for function prototypes throughout the stack. - - 2010-01-13: Simon Goldschmidt - * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive - window = 0) by correctly draining recvmbox/acceptmbox - - 2010-01-11: Simon Goldschmidt - * pap.c: Fixed bug #13315 (PPP PAP authentication can result in - erroneous callbacks) by copying the code from recent pppd - - 2010-01-10: Simon Goldschmidt - * raw.c: Fixed bug #28506 (raw_bind should filter received packets) - - 2010-01-10: Simon Goldschmidt - * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) - - 2010-01-08: Simon Goldschmidt - * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) - - 2010-01-08: Simon Goldschmidt - * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string - passed to dns_local_addhost() might be volatile - - 2010-01-07: Simon Goldschmidt - * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too - - 2010-01-06: Simon Goldschmidt - * netdb.h: Fixed bug #28496: missing include guards in netdb.h - - 2009-12-31: Simon Goldschmidt - * many ppp files: Reorganised PPP source code from ucip structure to pppd - structure to easily compare our code against the pppd code (around v2.3.1) - - 2009-12-27: Simon Goldschmidt - * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted - unit test - - -(STABLE-1.3.2) - - ++ New features: - - 2009-10-27 Simon Goldschmidt/Stephan Lesage - * netifapi.c/.h: Added netifapi_netif_set_addr() - - 2009-10-07 Simon Goldschmidt/Fabian Koch - * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to - support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) - - 2009-08-26 Simon Goldschmidt/Simon Kallweit - * slipif.c/.h: bug #26397: SLIP polling support - - 2009-08-25 Simon Goldschmidt - * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), - New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. - - 2009-08-25 Simon Goldschmidt - * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) - - 2009-08-24 Jakob Stoklund Olesen - * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond - to netif_set_link_up(). - - 2009-08-23 Simon Goldschmidt - * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state - to a human-readable string. - - ++ Bugfixes: - - 2009-12-24: Kieran Mansley - * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing - (BUG#28241) - - 2009-12-06: Simon Goldschmidt - * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can - be statically allocated (like in ucip) - - 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) - * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT - - 2009-12-03: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit - could have non-zero length - - 2009-12-02: Simon Goldschmidt - * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting - tcp_input_pcb until after calling the pcb's callbacks - - 2009-11-29: Simon Goldschmidt - * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- - sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code - - 2009-11-29: Simon Goldschmidt - * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by - queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty - - 2009-11-26: Simon Goldschmidt - * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending - segment - - 2009-11-26: Simon Goldschmidt - * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle - algorithm at PCB level - - 2009-11-22: Simon Goldschmidt - * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent - - 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) - * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when - reusing time-wait pcb - - 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) - * sockets.c: Fixed bug #28062: Data received directly after accepting - does not wake up select - - 2009-11-11: Simon Goldschmidt - * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) - - 2009-10-30: Simon Goldschmidt - * opt.h: Increased default value for TCP_MSS to 536, updated default - value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. - - 2009-10-28: Kieran Mansley - * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code - to follow algorithm from TCP/IP Illustrated - - 2009-10-27: Kieran Mansley - * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK - - 2009-10-25: Simon Goldschmidt - * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if - pcb->recv is NULL to keep rcv_wnd correct) - - 2009-10-25: Simon Goldschmidt - * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state - - 2009-10-23: Simon Goldschmidt (David Empson) - * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes - - 2009-10-21: Simon Goldschmidt - * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and - trailing 1 byte len (SYN/FIN) - - 2009-10-21: Simon Goldschmidt - * tcp_out.c: Fixed bug #27315: zero window probe and FIN - - 2009-10-19: Simon Goldschmidt - * dhcp.c/.h: Minor code simplification (don't store received pbuf, change - conditional code to assert where applicable), check pbuf length before - testing for valid reply - - 2009-10-19: Simon Goldschmidt - * dhcp.c: Removed most calls to udp_connect since they aren't necessary - when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. - - 2009-10-16: Simon Goldschmidt - * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop - valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is - enabled - - 2009-10-15: Simon Goldschmidt (Oleg Tyshev) - * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit - - 2009-10-15: Simon Goldschmidt - * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() - timeout - - 2009-10-15: Simon Goldschmidt - * autoip.c: Fixed bug #27704: autoip starts with wrong address - LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead - of network byte order - - 2009-10-11 Simon Goldschmidt (Jörg Kesten) - * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments - which are not consecutive when retransmitting unacked segments - - 2009-10-09 Simon Goldschmidt - * opt.h: Fixed default values of some stats to only be enabled if used - Fixes bug #27338: sys_stats is defined when NO_SYS = 1 - - 2009-08-30 Simon Goldschmidt - * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK - function" by checking for loopback before calling ip_frag - - 2009-08-25 Simon Goldschmidt - * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27078: Possible memory leak in pppInit() - - 2009-08-23 Simon Goldschmidt - * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result - is error. - - 2009-08-23 Simon Goldschmidt - * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF - Fixed wrong parenthesis, added check in init.c - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms - - 2009-08-23 Simon Goldschmidt - * many ppp files: bug #27267: Added include to string.h where needed - - 2009-08-23 Simon Goldschmidt - * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) - - -(STABLE-1.3.1) - - ++ New features: - - 2009-05-10 Simon Goldschmidt - * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option - LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only - one pbuf to help MACs that don't support scatter-gather DMA. - - 2009-05-09 Simon Goldschmidt - * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming - ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - - 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen - * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive - extended info about the currently received packet. - - 2009-04-27 Simon Goldschmidt - * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 - - 2009-04-25 Simon Goldschmidt - * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next - bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). - - 2009-04-21 Simon Goldschmidt - * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static - hosts table. New configuration options DNS_LOCAL_HOSTLIST and - DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined - as an external function for lookup. - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for - TCP timestamp options, off by default. Rework tcp_enqueue() to - take option flags rather than specified option data - - 2009-02-18 Simon Goldschmidt - * cc.h: Added printf formatter for size_t: SZT_F - - 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) - * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast - pings - - 2009-02-12 Simon Goldschmidt - * init.h: Added LWIP_VERSION to get the current version of the stack - - 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) - * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead - of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc - is otherwise used) - - 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) - * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() - is only used by UDPLITE at present, so conditionalise it. - - 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) - * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP - "seed" address. This should reduce AUTOIP conflicts if - LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. - - 2008-10-02 Jonathan Larmour and Rishi Khan - * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking - socket. - - 2008-06-30 Simon Goldschmidt - * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from - interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows - mem_free to run between mem_malloc iterations. Added illegal counter for - mem stats. - - 2008-06-27 Simon Goldschmidt - * stats.h/.c, some other files: patch #6483: stats module improvement: - Added defines to display each module's statistic individually, added stats - defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. - - 2008-06-17 Simon Goldschmidt - * err.h: patch #6459: Made err_t overridable to use a more efficient type - (define LWIP_ERR_T in cc.h) - - 2008-06-17 Simon Goldschmidt - * slipif.c: patch #6480: Added a configuration option for slipif for symmetry - to loopif - - 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) - * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly - modified version of patch # 6370: Moved loopif code to netif.c so that - loopback traffic is supported on all netifs (all local IPs). - Added option to limit loopback packets for each netifs. - - - ++ Bugfixes: - 2009-08-12 Kieran Mansley - * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when - out of window or out of order properly - - 2009-08-12 Kieran Mansley - * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 - - 2009-07-28 Simon Goldschmidt - * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s - - 2009-07-27 Kieran Mansley - * api.h api_msg.h netdb.h sockets.h: add missing #include directives - - 2009-07-09 Kieran Mansley - * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for - recv_avail and don't increment counters until message successfully - sent to mbox - - 2009-06-25 Kieran Mansley - * api_msg.c api.h: BUG26722: initialise netconn write variables - in netconn_alloc - - 2009-06-25 Kieran Mansley - * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set - - 2009-06-25 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct - simultaneous close behaviour, and make snd_nxt have the same meaning - as in the RFCs. - - 2009-05-12 Simon Goldschmidt - * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on - arp_table / uses etharp_query" by adding etharp_gratuitous() - - 2009-05-12 Simon Goldschmidt - * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options - to the IP header (used by igmp_ip_output_if) - - 2009-05-06 Simon Goldschmidt - * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if - defined) for SWAP_BYTES_IN_WORD to speed up checksumming. - - 2009-05-05 Simon Goldschmidt - * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() - to crash - - 2009-05-04 Simon Goldschmidt - * init.c: snmp was not initialized in lwip_init() - - 2009-05-04 Frédéric Bernon - * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. - - 2009-05-03 Simon Goldschmidt - * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full - (and unsent->next == NULL) - - 2009-05-02 Simon Goldschmidt - * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after - 1.3.0 in CVS only) - fixes compilation of ppp_oe.c - - 2009-05-02 Simon Goldschmidt - * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields - - 2009-05-01 Simon Goldschmidt - * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets - - 2009-05-01 Simon Goldschmidt - * ppp.c: bug #24228: Memory corruption with PPP and DHCP - - 2009-04-29 Frédéric Bernon - * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the - SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception - of broadcast packets even when this option wasn't set. Port maintainers - which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. - If you want this option also filter broadcast on recv operations, you also - have to set IP_SOF_BROADCAST_RECV=1 in opt.h. - - 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen - * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and - DHCP/AUTOIP cooperation - - 2009-04-25 Simon Goldschmidt, Oleg Tyshev - * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd - Fixed by sorting the unsent and unacked queues (segments are inserted at the - right place in tcp_output and tcp_rexmit). - - 2009-04-25 Simon Goldschmidt - * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation - when debugging": memp_sizes contained the wrong sizes (including sanity - regions); memp pools for MEM_USE_POOLS were too small - - 2009-04-24 Simon Goldschmidt, Frédéric Bernon - * inet.c: patch #6765: Fix a small problem with the last changes (incorrect - behavior, with with ip address string not ended by a '\0', a space or a - end of line) - - 2009-04-19 Simon Goldschmidt - * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, - pcb->err is called, not pcb->connected (with an error code). - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with - no-copy-tcpwrite": deallocate option data, only concat segments with same flags - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated - in the header pbuf, not the data pbuf) - - 2009-04-18 Simon Goldschmidt - * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() - - 2009-04-15 Simon Goldschmidt - * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp - - 2009-04-15 Simon Goldschmidt - * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in - - 2009-04-15 Simon Goldschmidt - * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function - ip_hinted_output() (for smaller code mainly) - - 2009-04-15 Simon Goldschmidt - * inet.c: patch #6765: Supporting new line characters in inet_aton() - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; - Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu - is big enough in dhcp_start - - 2009-04-15 Simon Goldschmidt - * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak - - 2009-04-15 Simon Goldschmidt - * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY - - 2009-04-15 Simon Goldschmidt - * sockets.c: bug #26121: set_errno can be overridden - - 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) - * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when - LWIP_TCP==0 - - 2009-04-09 Kieran Mansley (patch from Roy Lee ) - * tcp.h: Patch#6802 Add do-while-clauses to those function like - macros in tcp.h - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window - updates are calculated and sent (BUG20515) - - * tcp_in.c: cope with SYN packets received during established states, - and retransmission of initial SYN. - - * tcp_out.c: set push bit correctly when tcp segments are merged - - 2009-03-27 Kieran Mansley - * tcp_out.c set window correctly on probes (correcting change made - yesterday) - - 2009-03-26 Kieran Mansley - * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping - connections where no reset required (bug #25622) - - * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes - (bug #20779) - - 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) - * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be - too small depending on MEM_ALIGNMENT - - 2009-02-16 Simon Goldschmidt - * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; - converted size argument of netconn_write to 'size_t' - - 2009-02-16 Simon Goldschmidt - * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host - by moving accept callback function pointer to TCP_PCB_COMMON - - 2009-02-12 Simon Goldschmidt - * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" - option) - - 2009-02-11 Simon Goldschmidt - * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) - - 2009-02-11 Simon Goldschmidt - * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: - RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) - - 2009-02-10 Simon Goldschmidt - * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: - Accepts_pending is decrease on a corresponding listen pcb when a connection - in state SYN_RCVD is close. - - 2009-01-28 Jonathan Larmour - * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run - out of pool pbufs. - - 2008-12-19 Simon Goldschmidt - * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 - - 2008-12-10 Tamas Somogyi, Frédéric Bernon - * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and - port uses deleted netbuf. - - 2008-10-18 Simon Goldschmidt - * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length - in tcp_parseopt - - 2008-10-15 Simon Goldschmidt - * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers - by packing the struct ip_reass_helper. - - 2008-10-03 David Woodhouse, Jonathan Larmour - * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. - - 2008-10-02 Jonathan Larmour - * dns.c: Hard-code structure sizes, to avoid issues on some compilers where - padding is included. - - 2008-09-30 Jonathan Larmour - * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an - assertion check that addrlen isn't NULL. - - 2008-09-30 Jonathan Larmour - * tcp.c: Fix bug #24227, wrong error message in tcp_bind. - - 2008-08-26 Simon Goldschmidt - * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and - inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h - - 2008-08-14 Simon Goldschmidt - * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when - tcp_close returns != ERR_OK) - - 2008-07-08 Frédéric Bernon - * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters - in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). - - 2008-06-24 Jonathan Larmour - * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused - if tcp_seg_copy fails. - - 2008-06-17 Simon Goldschmidt - * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) - and created defines for swapping bytes and folding u32 to u16. - - 2008-05-30 Kieran Mansley - * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd - rather than rcv_ann_wnd when deciding if packets are in-window. - Contributed by - - 2008-05-30 Kieran Mansley - * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow - passing as function pointers when MEM_LIBC_MALLOC is defined. - - 2008-05-09 Jonathan Larmour - * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to - stop it being treated as a fatal error. - - 2008-04-15 Simon Goldschmidt - * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP - (flag now cleared) - - 2008-03-27 Simon Goldschmidt - * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free - from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 - in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs - or heap memory from interrupt context - - 2008-03-26 Simon Goldschmidt - * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote - host sent a zero mss as TCP option. - - -(STABLE-1.3.0) - - ++ New features: - - 2008-03-10 Jonathan Larmour - * inet_chksum.c: Allow choice of one of the sample algorithms to be - made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. - - 2008-01-22 Frédéric Bernon - * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in - TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. - - 2008-01-14 Frédéric Bernon - * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable - to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the - tcp_recv callback (see rawapi.txt). - - 2008-01-14 Frédéric Bernon, Marc Chaland - * ip.c: Integrate patch #6369" ip_input : checking before realloc". - - 2008-01-12 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::sem per netconn::op_completed like suggested for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-12 Frédéric Bernon - * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, - DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues - sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 - "Add return value to sys_mbox_post". tcpip_callback is always defined as - "blocking" ("block" parameter = 1). - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-05 Frédéric Bernon - * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: - Introduce changes for task #7490 "Add return value to sys_mbox_post" with some - modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which - indicate the number of pointers query by the mailbox. There is three defines - in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the - netconn::acceptmbox. Port maintainers, you can decide to just add this new - parameter in your implementation, but to ignore it to keep the previous behavior. - The new sys_mbox_trypost function return a value to know if the mailbox is - full or if the message is posted. Take a look to sys_arch.txt for more details. - This new function is used in tcpip_input (so, can be called in an interrupt - context since the function is not blocking), and in recv_udp and recv_raw. - - 2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, - tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the - "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add - documentation in the rawapi.txt file. - - 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer - - 2007-12-31 Frédéric Bernon, Luca Ceresoli - * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets - in autoip". The change in etharp_raw could be removed, since all calls to - etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be - wrong in the future. - - 2007-12-30 Frédéric Bernon, Tom Evans - * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address - Filtering" reported by Tom Evans. - - 2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, - sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API - applications have to call 'tcp_accepted(pcb)' in their accept callback to - keep accepting new connections. - - 2007-12-13 Frédéric Bernon - * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" - by err_t type. Add a new err_t code "ERR_INPROGRESS". - - 2007-12-12 Frédéric Bernon - * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles - are the one which have ram usage. - - 2007-12-05 Frédéric Bernon - * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static - set of variables (=0) or a local one (=1). In this last case, your port should - provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" - which have to do a copy of "h" and return a pointer ont the "per-thread" copy. - - 2007-12-03 Simon Goldschmidt - * ip.c: ip_input: check if a packet is for inp first before checking all other - netifs on netif_list (speeds up packet receiving in most cases) - - 2007-11-30 Simon Goldschmidt - * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access - UDP: move a (connected) pcb selected for input to the front of the list of - pcbs so that it is found faster next time. Same for RAW pcbs that have eaten - a packet. - - 2007-11-28 Simon Goldschmidt - * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS - - 2007-11-25 Simon Goldschmidt - * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy - algorithm. - - 2007-11-24 Simon Goldschmidt - * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c - to the new file netdb.c; included lwip_getaddrinfo. - - 2007-11-21 Simon Goldschmidt - * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss - based on the MTU of the netif used to send. Enabled by default. Disable by - setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. - - 2007-11-19 Frédéric Bernon - * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name - received match the name query), implement DNS_USES_STATIC_BUF (the place where - copy dns payload to parse the response), return an error if there is no place - for a new query, and fix some minor problems. - - 2007-11-16 Simon Goldschmidt - * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c - removed files: core/inet.c, core/inet6.c - Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into - inet and chksum part; changed includes in all lwIP files as appropriate - - 2007-11-16 Simon Goldschmidt - * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential - dns resolver function for netconn api (netconn_gethostbyname) and socket api - (gethostbyname/gethostbyname_r). - - 2007-11-15 Jim Pettinato, Frédéric Bernon - * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name - requests with RAW api interface. Initialization is done in lwip_init() with - build time options. DNS timer is added in tcpip_thread context. DHCP can set - DNS server ip addresses when options are received. You need to set LWIP_DNS=1 - in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get - some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" - list with points to improve. - - 2007-11-06 Simon Goldschmidt - * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly - enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status - for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. - - 2007-11-06 Simon Goldschmidt - * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include - core header files in api.h (ip/tcp/udp/raw.h) to hide the internal - implementation from netconn api applications. - - 2007-11-03 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & - RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled - by default). Netconn API users can use the netconn_recv_bufsize macro to access - it. This is a first release which have to be improve for TCP. Note it used the - netconn::recv_avail which need to be more "thread-safe" (note there is already - the problem for FIONREAD with lwip_ioctl/ioctlsocket). - - 2007-11-01 Frédéric Bernon, Marc Chaland - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: - Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api - layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api - layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. - Note that previous "copy" parameter for "write" APIs is now called "apiflags". - - 2007-10-24 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than - TCP_EVENT_xxx macros to get a code more readable. It could also help to remove - some code (like we have talk in "patch #5919 : Create compile switch to remove - select code"), but it could be done later. - - 2007-10-08 Simon Goldschmidt - * many files: Changed initialization: many init functions are not needed any - more since we now rely on the compiler initializing global and static - variables to zero! - - 2007-10-06 Simon Goldschmidt - * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY - to enqueue the received pbufs so that multiple packets can be reassembled - simultaneously and no static reassembly buffer is needed. - - 2007-10-05 Simon Goldschmidt - * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so - all netifs (or ports) can use it. - - 2007-10-05 Frédéric Bernon - * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the - common function to reduce a little bit the footprint (for all functions using - only the "netif" parameter). - - 2007-10-03 Frédéric Bernon - * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, - netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce - a little bit the footprint (for all functions using only the "netif" parameter). - - 2007-09-15 Frédéric Bernon - * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF - option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for - netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for - IP_MULTICAST_TTL and IP_MULTICAST_IF. - - 2007-09-10 Frédéric Bernon - * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles - even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() - each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can - decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but - call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() - or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. - This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside - snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only - when it's queried (any direct call to "sysuptime" is changed by a call to - snmp_get_sysuptime). - - 2007-09-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, - and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags - if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). - igmp_report_groups() is now called inside netif_set_link_up() (need to have - LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait - the next query message to receive the matching multicast streams). - - 2007-09-08 Frédéric Bernon - * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains - IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). - Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). - Enable to access to these fields with LWIP_TCP=0. - - 2007-09-05 Frédéric Bernon - * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, - ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option - LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). - Be careful, disabling ICMP make your product non-compliant to RFC1122, but - help to reduce footprint, and to reduce "visibility" on the Internet. - - 2007-09-05 Frédéric Bernon, Bill Florac - * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list - for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new - parameters have to be provided: a task name, and a task stack size. For this - one, since it's platform dependant, you could define the best one for you in - your lwipopts.h. For port maintainers, you can just add these new parameters - in your sys_arch.c file, and but it's not mandatory, use them in your OS - specific functions. - - 2007-09-05 Frédéric Bernon - * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings - inside init.c for task #7142 "Sanity check user-configurable values". - - 2007-09-04 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by - memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the - value). It will avoid potential fragmentation problems, use a counter to know - how many times a group is used on an netif, and free it when all applications - leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity - check if LWIP_IGMP!=0). - - 2007-09-03 Frédéric Bernon - * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". - Initialize igmp_mac_filter to NULL in netif_add (this field should be set in - the netif's "init" function). Use the "imr_interface" field (for socket layer) - and/or the "interface" field (for netconn layer), for join/leave operations. - The igmp_join/leavegroup first parameter change from a netif to an ipaddr. - This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). - - 2007-08-30 Frédéric Bernon - * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions - from api/api_lib". Now netbuf API is independant of netconn, and can be used - with other API (application based on raw API, or future "socket2" API). Ports - maintainers just have to add src/api/netbuf.c in their makefile/projects. - - 2007-08-30 Frédéric Bernon, Jonathan Larmour - * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check - user-configurable values". - - 2007-08-29 Frédéric Bernon - * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. - igmp_start is call inside netif_add. Now, igmp initialization is in the same - spirit than the others modules. Modify some IGMP debug traces. - - 2007-08-29 Frédéric Bernon - * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" - Add lwip_init function to regroup all modules initializations, and to provide - a place to add code for task #7142 "Sanity check user-configurable values". - Ports maintainers should remove direct initializations calls from their code, - and add init.c in their makefiles. Note that lwip_init() function is called - inside tcpip_init, but can also be used by raw api users since all calls are - disabled when matching options are disabled. Also note that their is new options - in opt.h, you should configure in your lwipopts.h (they are enabled per default). - - 2007-08-26 Marc Boucher - * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL - since they can under certain circumstances be called with an invalid conn - pointer after the connection has been closed (and conn has been freed). - - 2007-08-25 Frédéric Bernon (Artem Migaev's Patch) - * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". - Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. - - 2007-08-22 Frédéric Bernon - * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK - to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. - - 2007-08-22 Frédéric Bernon - * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & - ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the - name is tcpip_input (we keep the name of 1.2.0 function). - - 2007-08-17 Jared Grubb - * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool - settings into new memp_std.h and optional user file lwippools.h. This adds - more dynamic mempools, and allows the user to create an arbitrary number of - mempools for mem_malloc. - - 2007-08-16 Marc Boucher - * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; - otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely - close the connection. - - 2007-08-16 Marc Boucher - * sockets.c: lwip_accept(): check netconn_peer() error return. - - 2007-08-16 Marc Boucher - * mem.c, mem.h: Added mem_calloc(). - - 2007-08-16 Marc Boucher - * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) - for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG - and starving other message types. - Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API - - 2007-08-16 Marc Boucher - * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf - type and flgs (later renamed to flags). - Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. - Improved lwip_recvfrom(). TCP push now propagated. - - 2007-08-16 Marc Boucher - * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global - provided by etharp. - - 2007-08-16 Marc Boucher - * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, - etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: - Added PPPoE support and various PPP improvements. - - 2007-07-25 Simon Goldschmidt - * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, - making netbuf_copy_partial use this function. - - 2007-07-25 Simon Goldschmidt - * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with - 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and - other stacks. - - 2007-07-13 Jared Grubb (integrated by Frédéric Bernon) - * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add - a link callback in the netif struct, and functions to handle it. Be carefull - for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) - if you want to be sure to be compatible with future changes... - - 2007-06-30 Frédéric Bernon - * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. - - 2007-06-21 Simon Goldschmidt - * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both - LWIP_AUTOIP =0 and =1 to remove redundant code. - - 2007-06-21 Simon Goldschmidt - * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option - MEM_USE_POOLS to use 4 pools with different sized elements instead of a - heap. This both prevents memory fragmentation and gives a higher speed - at the cost of more memory consumption. Turned off by default. - - 2007-06-21 Simon Goldschmidt - * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of - netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into - int to be able to send a bigger buffer than 64K with one time (mainly - used from lwip_send). - - 2007-06-21 Simon Goldschmidt - * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write - into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. - - 2007-06-21 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in - netconn_write from api_lib.c to api_msg.c to also prevent multiple context- - changes on low memory or empty send-buffer. - - 2007-06-18 Simon Goldschmidt - * etharp.c, etharp.h: Changed etharp to use a defined hardware address length - of 6 to avoid loading netif->hwaddr_len every time (since this file is only - used for ethernet and struct eth_addr already had a defined length of 6). - - 2007-06-17 Simon Goldschmidt - * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets - to disable UDP checksum generation on transmit. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid - pointers or parameters, and let the possibility to redefined it in cc.h. Use - this macro to check "conn" parameter in api_msg.c functions. - - 2007-06-11 Simon Goldschmidt - * sockets.c, sockets.h: Added UDP lite support for sockets - - 2007-06-10 Simon Goldschmidt - * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled - by default) to switch off UDP-Lite support if not needed (reduces udp.c code - size) - - 2007-06-09 Dominik Spies (integrated by Frédéric Bernon) - * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: - AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and - LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt - (see TODO mark in the source code). - - 2007-06-09 Simon Goldschmidt - * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for - etharp_output() to match netif->output so etharp_output() can be used - directly as netif->output to save one function call. - - 2007-06-08 Simon Goldschmidt - * netif.h, ethernetif.c, slipif.c, loopif.c: Added define - NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, - added initialization of those to ethernetif, slipif and loopif. - - 2007-05-18 Simon Goldschmidt - * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF - (defaulting to off for now) that can be set to 0 to send fragmented - packets by passing PBUF_REFs down the stack. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP - connections, such present in patch #5959. - - 2007-05-23 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx - code in only one part... - - 2007-05-18 Simon Goldschmidt - * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp - elements to overflow. This is achieved by adding some bytes before and after - each pool element (increasing their size, of course), filling them with a - prominent value and checking them on freeing the element. - Set it to 2 to also check every element in every pool each time memp_malloc() - or memp_free() is called (slower but more helpful). - - 2007-05-10 Simon Goldschmidt - * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for - PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce - code size. - - 2007-05-11 Frédéric Bernon - * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: - Include a function pointer instead of a table index in the message to reduce - footprint. Disable some part of lwip_send and lwip_sendto if some options are - not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). - - 2007-05-10 Simon Goldschmidt - * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus - \ extern "C" {' in all header files. Now you can write your application using - the lwIP stack in C++ and simply #include the core files. Note I have left - out the netif/ppp/*h header files for now, since I don't know which files are - included by applications and which are for internal use only. - - 2007-05-09 Simon Goldschmidt - * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library - memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for - situations where some compilers might inline the copy and save a function - call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). - - 2007-05-08 Simon Goldschmidt - * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) - to be overriden in case the C-library malloc implementation is not protected - against concurrent access. - - 2007-05-04 Simon Goldschmidt (Atte Kojo) - * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending - multiple packets to the same host. - - 2007-05-04 Frédéric Bernon, Jonathan Larmour - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible - to corrupt remote addr/port connection state". Reduce problems "not enought memory" with - netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between - sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. - Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, - these fields are now renamed "addr" & "port". - - 2007-04-11 Jonathan Larmour - * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new - sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return - with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro - by the port in sys_arch.h if desired. - - 2007-04-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API - allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp - clients, using new functions from netifapi.h. Disable as default (no port change to do). - - 2007-04-05 Frédéric Bernon - * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. - - 2007-04-04 Simon Goldschmidt - * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) - use this for and architecture-independent form to tell the compiler you intentionally - are not using this variable. Can be overriden in cc.h. - - 2007-03-28 Frédéric Bernon - * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to - define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded - string, point on one of your's ethernetif field, or alloc a string you will free yourself). - It will be used by DHCP to register a client hostname, but can also be use when you call - snmp_set_sysname. - - 2007-03-28 Frédéric Bernon - * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to - initialize a network interface's flag with. It tell this interface is an ethernet - device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility - Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). - - 2007-03-26 Frédéric Bernon, Jonathan Larmour - * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build - time if you only use PPP or SLIP. The default is enable. Note we don't have to call - etharp_init in your port's initilization sequence if you use tcpip.c, because this call - is done in tcpip_init function. - - 2007-03-22 Frédéric Bernon - * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the - new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in - your lwipopts.h. More, unused counters are not defined in the stats structs, and not - display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined - but never used. Fix msg_in.c with the correct #if test for a stat display. - - 2007-03-21 Kieran Mansley - * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). - Provides callback on netif up/down state change. - - 2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, - ip.c, netif.h, tcpip.c, opt.h: - New configuration option LWIP_IGMP to enable IGMP processing. Based on only one - filter per all network interfaces. Declare a new function in netif to enable to - control the MAC filter (to reduce lwIP traffic processing). - - 2007-03-11 Frédéric Bernon - * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can - be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this - unless you know what you're doing (default are RFC1122 compliant). Note - that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. - - 2007-03-08 Frédéric Bernon - * tcp.h: Keepalive values can be configured at compile time, but don't change - this unless you know what you're doing (default are RFC1122 compliant). - - 2007-03-08 Frédéric Bernon - * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: - Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO - on UDP sockets/netconn. - - 2007-03-08 Simon Goldschmidt - * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. - - 2007-03-06 Frédéric Bernon - * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: - Implement SO_RCVTIMEO on UDP sockets/netconn. - - 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) - * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated - on the stack and remove the API msg type from memp - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * sockets.h, sockets.c: Move socket initialization to new - lwip_socket_init() function. - NOTE: this changes the API with ports. Ports will have to be - updated to call lwip_socket_init() now. - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * api_lib.c: Use memcpy in netbuf_copy_partial. - - - ++ Bug fixes: - - 2008-03-17 Frédéric Bernon, Ed Kerekes - * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have - some problems to fill the IP header on some targets, use now the - ip.h macros to do it). - - 2008-03-13 Frédéric Bernon - * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using - (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a - TCP connection caused a crash. Note that using (lwip_)recvfrom - like this is a bit slow and that using (lwip)getpeername is the - good lwip way to do it (so, using recv is faster on tcp sockets). - - 2008-03-12 Frédéric Bernon, Jonathan Larmour - * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's - recv_raw() does not consume data", and the ping sample (with - LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom - returned the IP payload, without the IP header). - - 2008-03-04 Jonathan Larmour - * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors - and/or warnings on some systems where mem_size_t and size_t differ. - * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. - - 2008-03-04 Kieran Mansley (contributions by others) - * Numerous small compiler error/warning fixes from contributions to - mailing list after 1.3.0 release candidate made. - - 2008-01-25 Cui hengbin (integrated by Frédéric Bernon) - * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. - - 2008-01-15 Kieran Mansley - * tcp_out.c: BUG20511. Modify persist timer to start when we are - prevented from sending by a small send window, not just a zero - send window. - - 2008-01-09 Jonathan Larmour - * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid - conflict with Linux system headers. - - 2008-01-06 Jonathan Larmour - * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP - address entirely on receiving a DHCPNAK, and restarting discovery. - - 2007-12-21 Simon Goldschmidt - * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail - is not protected" by using new macros for interlocked access to modify/test - netconn->recv_avail. - - 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) - * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) - - 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling - of silly window avoidance and prevent lwIP from shrinking the window) - - 2007-12-04 Simon Goldschmidt - * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last - data packet was lost): add assert that all segment lists are empty in - tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED - state from LAST_ACK in tcp_process - - 2007-12-02 Simon Goldschmidt - * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET - If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now - has to be set to 0 in lwipopts.h - - 2007-12-02 Simon Goldschmidt - * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always - allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen - netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. - This is a fix for thread-safety and allocates all items needed for a netconn - when the netconn is created. - - 2007-11-30 Simon Goldschmidt - * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple - netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed - to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same - port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) - - 2007-11-27 Simon Goldschmidt - * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by - letting ip_route only use netifs that are up. - - 2007-11-27 Simon Goldschmidt - * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF - and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and - sockets block most operations once they have seen a fatal error. - - 2007-11-27 Simon Goldschmidt - * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the - netif to send as an argument (to be able to send on netifs that are down). - - 2007-11-26 Simon Goldschmidt - * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs - arrive out-of-order - - 2007-11-21 Simon Goldschmidt - * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early - Fixed the nagle algorithm; nagle now also works for all raw API applications - and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' - - 2007-11-12 Frédéric Bernon - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most - of the netconn_peer and netconn_addr processing is done inside tcpip_thread - context in do_getaddr. - - 2007-11-10 Simon Goldschmidt - * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can - happen any time). Now the packet simply isn't enqueued when out of memory. - - 2007-11-01 Simon Goldschmidt - * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or - TCP_MSS if that is smaller) as long as no MSS option is received from the - remote host. - - 2007-11-01 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) - is now based on TCP_MSS instead of pcb->mss (on passive open now effectively - sending our configured TCP_MSS instead of the one received). - - 2007-11-01 Simon Goldschmidt - * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was - calculated based on the configured TCP_MSS, not on the MSS option received - with SYN+ACK. - - 2007-10-09 Simon Goldschmidt - * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too - short and also was generated wrong if checksum coverage != tot_len; - receive: checksum was calculated wrong if checksum coverage != tot_len - - 2007-10-08 Simon Goldschmidt - * mem.c: lfree was not updated in mem_realloc! - - 2007-10-07 Frédéric Bernon - * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential - crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: - this change cause an API breakage for netconn_addr, since a parameter - type change. Any compiler should cause an error without any changes in - yours netconn_peer calls (so, it can't be a "silent change"). It also - reduce a little bit the footprint for socket layer (lwip_getpeername & - lwip_getsockname use now a common lwip_getaddrname function since - netconn_peer & netconn_addr have the same parameters). - - 2007-09-20 Simon Goldschmidt - * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) - by checking tcp_tw_pcbs also - - 2007-09-19 Simon Goldschmidt - * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) - - 2007-09-15 Mike Kleshov - * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) - - 2007-09-06 Frédéric Bernon - * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove - it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which - already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" - if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. - - 2007-08-30 Frédéric Bernon - * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, - and fix some coding style. - - 2007-08-28 Frédéric Bernon - * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any - kind of packets. These packets are considered like Ethernet packets (payload - pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets - are considered like IP packets (payload pointing to iphdr). - - 2007-08-27 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error - problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state - and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). - - 2007-08-24 Kieran Mansley - * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy - compiler (Paradigm C++) - - 2007-08-09 Frédéric Bernon, Bill Florac - * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. - Introduce IGMP_STATS to centralize statistics management. - - 2007-08-09 Frédéric Bernon, Bill Florac - * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast - packet on a udp pcb binded on an netif's IP address, and not on "any". - - 2007-08-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. - This is mainly on using lookup/lookfor, and some coding styles... - - 2007-07-26 Frédéric Bernon (and "thedoctor") - * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. - - 2007-07-25 Simon Goldschmidt - * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if - tcp_output fails in tcp_close, the code in do_close_internal gets simpler - (tcp_output is called again later from tcp timers). - - 2007-07-25 Simon Goldschmidt - * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old - copy_from_pbuf, which illegally modified the given pbuf. - - 2007-07-25 Simon Goldschmidt - * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: - changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). - - 2007-07-24 Simon Goldschmidt - * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the - correct state (must be CLOSED). - - 2007-07-13 Thomas Taranowski (commited by Jared Grubb) - * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed - allocation. It now returns NULL. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in - all error cases. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, - because current code doesn't follow rawapi.txt documentation. - - 2007-07-13 Kieran Mansley - * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in - out of sequence processing of received packets - - 2007-07-03 Simon Goldschmidt - * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an - assumption is made that this pbuf is in one piece (i.e. not chained). These - assumptions clash with the possibility of converting to fully pool-based - pbuf implementations, where PBUF_RAM pbufs might be chained. - - 2007-07-03 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems - when closing tcp netconns: removed conn->sem, less context switches when - closing, both netconn_close and netconn_delete should safely close tcp - connections. - - 2007-07-02 Simon Goldschmidt - * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, - tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) - to cache ARP table indices with each pcb instead of single-entry cache for - the complete stack. - - 2007-07-02 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent - warnings when assigning to smaller types. - - 2007-06-28 Simon Goldschmidt - * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. - - 2007-06-28 Simon Goldschmidt - * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if - a segment contained chained pbufs) - - 2007-06-28 Frédéric Bernon - * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute - a "pseudo-random" value based on netif's MAC and some autoip fields. It's always - possible to define this macro in your own lwipopts.h to always use C library's - rand(). Note that autoip_create_rand_addr doesn't use this macro. - - 2007-06-28 Frédéric Bernon - * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option - LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications - in api_lib/api_msg (use pointers and not type with table, etc...) - - 2007-06-26 Simon Goldschmidt - * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload - for udp packets with no matching pcb. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match - could get udp input packets if the remote side matched. - - 2007-06-13 Simon Goldschmidt - * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get - changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. - - 2007-06-13 Simon Goldschmidt - * api_msg.c: pcb_new sets conn->err if protocol is not implemented - -> netconn_new_..() does not allocate a new connection for unsupported - protocols. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * api_lib.c: change return expression in netconn_addr and netconn_peer, because - conn->err was reset to ERR_OK without any reasons (and error was lost)... - - 2007-06-13 Frédéric Bernon, Matthias Weisser - * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename - MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid - some macro names collision with some OS macros. - - 2007-06-11 Simon Goldschmidt - * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, - create checksum over the complete packet. On RX, if it's < 8 (and not 0), - discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both - UDP & UDP Lite. - - 2007-06-11 Srinivas Gollakota & Oleg Tyshev - * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" - where TCP flags wasn't initialized in tcp_keepalive. - - 2007-06-03 Simon Goldschmidt - * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function - registered, p->payload was modified without modifying p->len if sending - icmp_dest_unreach() (had no negative effect but was definitively wrong). - - 2007-06-03 Simon Goldschmidt - * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp - re-used the input pbuf even if that didn't have enough space to include the - link headers. Now the space is tested and a new pbuf is allocated for the - echo response packet if the echo request pbuf isn't big enough. - - 2007-06-01 Simon Goldschmidt - * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. - - 2007-05-23 Frédéric Bernon - * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only - allocated by do_listen if success) and netconn_accept errors handling. In - most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" - by ASSERT, except for netconn_delete. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return - an error code if it's impossible to fetch a pbuf on a TCP connection (and not - directly close the recvmbox). - - 2007-05-22 Simon Goldschmidt - * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of - bound but unconnected (and non-listening) tcp_pcbs. - - 2007-05-22 Frédéric Bernon - * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only - used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of - sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features - like "sys_timeout" in their application threads. - - 2007-05-22 Frédéric Bernon - * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see - which parameters are used by which do_xxx function, and to avoid "misusing" - parameters (patch #5938). - - 2007-05-22 Simon Goldschmidt - * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: - changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto - is only 8 bits wide. This affects the api, as there, the protocol was - u16_t, too. - - 2007-05-18 Simon Goldschmidt - * memp.c: addition to patch #5913: smaller pointer was returned but - memp_memory was the same size -> did not save memory. - - 2007-05-16 Simon Goldschmidt - * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns - != ERR_OK. - - 2007-05-16 Simon Goldschmidt - * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same - as the one of the netif used for sending to prevent sending from old - addresses after a netif address gets changed (partly fixes bug #3168). - - 2007-05-16 Frédéric Bernon - * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work - with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in - tcpip_init) because we have to be sure that network interfaces are already - added (mac filter is updated only in igmp_init for the moment). - - 2007-05-16 Simon Goldschmidt - * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls - into sys_arch_sem_wait calls to prevent timers from running while waiting - for the heap. This fixes bug #19167. - - 2007-05-13 Simon Goldschmidt - * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines - for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from - tcp.h to sockets.h. - - 2007-05-07 Simon Goldschmidt - * mem.c: Another attempt to fix bug #17922. - - 2007-05-04 Simon Goldschmidt - * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() - implementation so that it can be reused (don't allocate the target - pbuf inside pbuf_copy()). - - 2007-05-04 Simon Goldschmidt - * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem - to save a little RAM (next pointer of memp is not used while not in pool). - - 2007-05-03 "maq" - * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. - (patch #3574). - - 2007-04-23 Simon Goldschmidt - * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results - in NULL reference for incoming TCP packets". Loopif has to be configured - (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() - (multithreading environments, e.g. netif->input() = tcpip_input()) or - putting packets on a list that is fed to the stack by calling loopif_poll() - (single-thread / NO_SYS / polling environment where e.g. - netif->input() = ip_input). - - 2007-04-17 Jonathan Larmour - * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold - the difference between two u16_t's. - * sockets.h: FD_SETSIZE needs to match number of sockets, which is - MEMP_NUM_NETCONN in sockets.c right now. - - 2007-04-12 Jonathan Larmour - * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). - - 2007-04-12 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission - timer is reset to fix bug#19434, with help from Oleg Tyshev. - - 2007-04-11 Simon Goldschmidt - * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than - previously thought need to be copied (everything but PBUF_ROM!). Cleaned up - pbuf.c: removed functions no needed any more (by etharp). - - 2007-04-11 Kieran Mansley - * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix - "Constant is long" warnings with 16bit compilers. Contributed by - avatar@mmlab.cse.yzu.edu.tw - - 2007-04-05 Frédéric Bernon, Jonathan Larmour - * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on - the mailbox is active". Now, the post is only done during a connect, and do_send, - do_write and do_join_leave_group don't do anything if a previous error was signaled. - - 2007-04-03 Frédéric Bernon - * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output - packets. See patch #5834. - - 2007-03-30 Frédéric Bernon - * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add - missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. - - 2007-03-30 Frédéric Bernon - * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with - others environment defines (these were too "generic"). - - 2007-03-28 Frédéric Bernon - * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call - result and can cause a crash. lwip_send now check netbuf_ref result. - - 2007-03-28 Simon Goldschmidt - * sockets.c Remove "#include " from sockets.c to avoid multiple - definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is - defined. This is the way it should have been already (looking at - doc/sys_arch.txt) - - 2007-03-28 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + - IP and TCP headers *and* physical link headers - - 2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov) - * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause - to send some garbage. It is not a definitive solution, but the patch does solve - the problem for most cases. - - 2007-03-22 Frédéric Bernon - * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). - - 2007-03-22 Frédéric Bernon - * api_lib.c: somes resources couldn't be freed if there was errors during - netconn_new_with_proto_and_callback. - - 2007-03-22 Frédéric Bernon - * ethernetif.c: update netif->input calls to check return value. In older ports, - it's a good idea to upgrade them, even if before, there could be another problem - (access to an uninitialized mailbox). - - 2007-03-21 Simon Goldschmidt - * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed - by casting to unsigned). - - 2007-03-21 Frédéric Bernon - * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from - api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a - dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. - Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a - faster and more reliable communication between api_lib and tcpip. - - 2007-03-21 Frédéric Bernon - * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. - - 2007-03-21 Frédéric Bernon - * api_msg.c, igmp.c, igmp.h: Fix C++ style comments - - 2007-03-21 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + - IP and TCP headers - - 2007-03-21 Kieran Mansley - * Fix all uses of pbuf_header to check the return value. In some - cases just assert if it fails as I'm not sure how to fix them, but - this is no worse than before when they would carry on regardless - of the failure. - - 2007-03-21 Kieran Mansley - * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and - comment out missing header include in icmp.c - - 2007-03-20 Frédéric Bernon - * memp.h, stats.c: Fix stats_display function where memp_names table wasn't - synchronized with memp.h. - - 2007-03-20 Frédéric Bernon - * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, - tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with - network interfaces. Also fix a compiler warning. - - 2007-03-20 Kieran Mansley - * udp.c: Only try and use pbuf_header() to make space for headers if - not a ROM or REF pbuf. - - 2007-03-19 Frédéric Bernon - * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() - and api_msg_post(). - - 2007-03-19 Frédéric Bernon - * Remove unimplemented "memp_realloc" function from memp.h. - - 2007-03-11 Simon Goldschmidt - * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused - memory corruption. - - 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) - * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 - (missing `const' qualifier in socket functions), to get more compatible to - standard POSIX sockets. - - 2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov) - * sockets.c: Add asserts inside bind, connect and sendto to check input - parameters. Remove excessive set_errno() calls after get_socket(), because - errno is set inside of get_socket(). Move last sock_set_errno() inside - lwip_close. - - 2007-03-09 Simon Goldschmidt - * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory - was allocated too small. - - 2007-03-06 Simon Goldschmidt - * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect - the stack from concurrent access. - - 2007-03-06 Frédéric Bernon, Dmitry Potapov - * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy - call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). - - 2007-03-06 Simon Goldschmidt - * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files - if IP_FRAG == 0 and IP_REASSEMBLY == 0 - - 2007-03-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration - option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. - Allow to do ARP processing for incoming packets inside tcpip_thread - (protecting ARP layer against concurrent access). You can also disable - old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. - Older ports have to use tcpip_ethinput. - - 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) - * err.h, err.c: fixed compiler warning "initialization dircards qualifiers - from pointer target type" - - 2007-03-05 Frédéric Bernon - * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, - ETHARP_TRUST_IP_MAC, review SO_REUSE) - - 2007-03-04 Frédéric Bernon - * api_msg.c: Remove some compiler warnings : parameter "pcb" was never - referenced. - - 2007-03-04 Frédéric Bernon - * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from - Dmitry Potapov). - The api_msg struct stay on the stack (not moved to netconn struct). - - 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) - * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if - SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) - Also fixed cast warning in pbuf_alloc() - - 2007-03-04 Simon Goldschmidt - * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt - existing pbuf chain when enqueuing multiple pbufs to a pending ARP request - - 2007-03-03 Frédéric Bernon - * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" - It is static, and never used in udp.c except udp_init(). - - 2007-03-02 Simon Goldschmidt - * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from - tcpip_thread() to tcpip_init(). This way, raw API connections can be - initialized before tcpip_thread is running (e.g. before OS is started) - - 2007-03-02 Frédéric Bernon - * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call - interval. - - 2007-02-28 Kieran Mansley - * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved - outside the region of the pbuf by pbuf_header() - - 2007-02-28 Kieran Mansley - * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero - when supplied timeout is also non-zero - -(STABLE-1.2.0) - - 2006-12-05 Leon Woestenberg - * CHANGELOG: Mention STABLE-1.2.0 release. - - ++ New features: - - 2006-12-01 Christiaan Simons - * mem.h, opt.h: Added MEM_LIBC_MALLOC option. - Note this is a workaround. Currently I have no other options left. - - 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) - * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define - to include/lwip/opt.h. - * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. - Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. - * opt.h: Add above new options. - - 2006-08-18 Christiaan Simons - * tcp_{in,out}.c: added SNMP counters. - * ipv4/ip.c: added SNMP counters. - * ipv4/ip_frag.c: added SNMP counters. - - 2006-08-08 Christiaan Simons - * etharp.{c,h}: added etharp_find_addr() to read - (stable) ethernet/IP address pair from ARP table - - 2006-07-14 Christiaan Simons - * mib_structs.c: added - * include/lwip/snmp_structs.h: added - * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct - - 2006-07-06 Christiaan Simons - * snmp/asn1_{enc,dec}.c added - * snmp/mib2.c added - * snmp/msg_{in,out}.c added - * include/lwip/snmp_asn1.h added - * include/lwip/snmp_msg.h added - * doc/snmp_agent.txt added - - 2006-03-29 Christiaan Simons - * inet.c, inet.h: Added platform byteswap support. - Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and - optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. - - ++ Bug fixes: - - 2006-11-30 Christiaan Simons - * dhcp.c: Fixed false triggers of request_timeout. - - 2006-11-28 Christiaan Simons - * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. - - 2006-10-11 Christiaan Simons - * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: - Partially accepted patch #5449 for ANSI C compatibility / build fixes. - * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol - identifier from 170 to 136 (bug #17574). - - 2006-10-10 Christiaan Simons - * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. - - 2006-08-17 Christiaan Simons - * udp.c: Fixed bug #17200, added check for broadcast - destinations for PCBs bound to a unicast address. - - 2006-08-07 Christiaan Simons - * api_msg.c: Flushing TCP output in do_close() (bug #15926). - - 2006-06-27 Christiaan Simons - * api_msg.c: Applied patch for cold case (bug #11135). - In accept_function() ensure newconn->callback is always initialized. - - 2006-06-15 Christiaan Simons - * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), - facilitate printing of mem_size_t and u16_t statistics. - - 2006-06-14 Christiaan Simons - * api_msg.c: Applied patch #5146 to handle allocation failures - in accept() by Kevin Lawson. - - 2006-05-26 Christiaan Simons - * api_lib.c: Removed conn->sem creation and destruction - from netconn_write() and added sys_sem_new to netconn_new_*. - -(STABLE-1_1_1) - - 2006-03-03 Christiaan Simons - * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap - access and added pbuf_alloc() return value checks. - - 2006-01-01 Leon Woestenberg - * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is - now handled by the checksum routine properly. - - 2006-02-27 Leon Woestenberg - * pbuf.c: Fix alignment; pbuf_init() would not work unless - pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) - - 2005-12-20 Leon Woestenberg - * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch - submitted by Mitrani Hiroshi. - - 2005-12-15 Christiaan Simons - * inet.c: Disabled the added summing routine to preserve code space. - - 2005-12-14 Leon Woestenberg - * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. - Added Curt McDowell's optimized checksumming routine for future - inclusion. Need to create test case for unaliged, aligned, odd, - even length combination of cases on various endianess machines. - - 2005-12-09 Christiaan Simons - * inet.c: Rewrote standard checksum routine in proper portable C. - - 2005-11-25 Christiaan Simons - * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. - * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, - u32_t, s32_t typedefs. This solves most debug word-length assumes. - - 2005-07-17 Leon Woestenberg - * inet.c: Fixed unaligned 16-bit access in the standard checksum - routine by Peter Jolasson. - * slipif.c: Fixed implementation assumption of single-pbuf datagrams. - - 2005-02-04 Leon Woestenberg - * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. - * tcp_{out|in}.c: Applied patch fixing unaligned access. - - 2005-01-04 Leon Woestenberg - * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. - - 2005-01-03 Leon Woestenberg - * udp.c: UDP pcb->recv() was called even when it was NULL. - -(STABLE-1_1_0) - - 2004-12-28 Leon Woestenberg - * etharp.*: Disabled multiple packets on the ARP queue. - This clashes with TCP queueing. - - 2004-11-28 Leon Woestenberg - * etharp.*: Fixed race condition from ARP request to ARP timeout. - Halved the ARP period, doubled the period counts. - ETHARP_MAX_PENDING now should be at least 2. This prevents - the counter from reaching 0 right away (which would allow - too little time for ARP responses to be received). - - 2004-11-25 Leon Woestenberg - * dhcp.c: Decline messages were not multicast but unicast. - * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. - Do not try hard to insert arbitrary packet's source address, - etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. - etharp_query() now always DOES call ETHARP_TRY_HARD so that users - querying an address will see it appear in the cache (DHCP could - suffer from this when a server invalidly gave an in-use address.) - * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are - comparing network addresses (identifiers), not the network masks - themselves. - * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given - IP address actually belongs to the network of the given interface. - - 2004-11-24 Kieran Mansley - * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. - -(STABLE-1_1_0-RC1) - - 2004-10-16 Kieran Mansley - * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, - even if one is already pending, if the rcv_wnd is above a threshold - (currently TCP_WND/2). This avoids waiting for a timer to expire to send a - delayed ACK in order to open the window if the stack is only receiving data. - - 2004-09-12 Kieran Mansley - * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. - - 2004-08-20 Tony Mountifield - * etharp.c: Make sure the first pbuf queued on an ARP entry - is properly ref counted. - - 2004-07-27 Tony Mountifield - * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler - warnings about comparison. - * pbuf.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. Closed an unclosed comment. - * tcp.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. - * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). - * inet.c: Added a couple of casts to quiet the compiler. - No need to test isascii(c) before isdigit(c) or isxdigit(c). - - 2004-07-22 Tony Mountifield - * inet.c: Made data types consistent in inet_ntoa(). - Added casts for return values of checksum routines, to pacify compiler. - * ip_frag.c, tcp_out.c, sockets.c, pbuf.c - Small corrections to some debugging statements, to pacify compiler. - - 2004-07-21 Tony Mountifield - * etharp.c: Removed spurious semicolon and added missing end-of-comment. - * ethernetif.c Updated low_level_output() to match prototype for - netif->linkoutput and changed low_level_input() similarly for consistency. - * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype - of raw_recv() in raw.h and so avoid compiler error. - * sockets.c: Added trivial (int) cast to keep compiler happier. - * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. - -(STABLE-1_0_0) - - ++ Changes: - - 2004-07-05 Leon Woestenberg - * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure - your cc.h file defines this either 1 or 0. If non-defined, - defaults to 1. - * .c: Added and includes where used. - * etharp.c: Made some array indices unsigned. - - 2004-06-27 Leon Woestenberg - * netif.*: Added netif_set_up()/down(). - * dhcp.c: Changes to restart program flow. - - 2004-05-07 Leon Woestenberg - * etharp.c: In find_entry(), instead of a list traversal per candidate, do a - single-pass lookup for different candidates. Should exploit locality. - - 2004-04-29 Leon Woestenberg - * tcp*.c: Cleaned up source comment documentation for Doxygen processing. - * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. - * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by - the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. - - ++ Bug fixes: - - 2004-04-27 Leon Woestenberg - * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution - suggested by Timmy Brolin. Fix for 32-bit processors that cannot access - non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix - is to prefix the 14-bit Ethernet headers with two padding bytes. - - 2004-04-23 Leon Woestenberg - * ip_addr.c: Fix in the ip_addr_isbroadcast() check. - * etharp.c: Fixed the case where the packet that initiates the ARP request - is not queued, and gets lost. Fixed the case where the packets destination - address is already known; we now always queue the packet and perform an ARP - request. - -(STABLE-0_7_0) - - ++ Bug fixes: - - * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. - * Fixed TCP bug in dequeueing of FIN from out of order segment queue. - * Fixed two possible NULL references in rare cases. - -(STABLE-0_6_6) - - ++ Bug fixes: - - * Fixed DHCP which did not include the IP address in DECLINE messages. - - ++ Changes: - - * etharp.c has been hauled over a bit. - -(STABLE-0_6_5) - - ++ Bug fixes: - - * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. - * Packets sent from ARP queue had invalid source hardware address. - - ++ Changes: - - * Pass-by ARP requests do now update the cache. - - ++ New features: - - * No longer dependent on ctype.h. - * New socket options. - * Raw IP pcb support. - -(STABLE-0_6_4) - - ++ Bug fixes: - - * Some debug formatters and casts fixed. - * Numereous fixes in PPP. - - ++ Changes: - - * DEBUGF now is LWIP_DEBUGF - * pbuf_dechain() has been re-enabled. - * Mentioned the changed use of CVS branches in README. - -(STABLE-0_6_3) - - ++ Bug fixes: - - * Fixed pool pbuf memory leak in pbuf_alloc(). - Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. - Reported by Savin Zlobec. - - * PBUF_POOL chains had their tot_len field not set for non-first - pbufs. Fixed in pbuf_alloc(). - - ++ New features: - - * Added PPP stack contributed by Marc Boucher - - ++ Changes: - - * Now drops short packets for ICMP/UDP/TCP protocols. More robust. - - * ARP queueuing now queues the latest packet instead of the first. - This is the RFC recommended behaviour, but can be overridden in - lwipopts.h. - -(0.6.2) - - ++ Bugfixes: - - * TCP has been fixed to deal with the new use of the pbuf->ref - counter. - - * DHCP dhcp_inform() crash bug fixed. - - ++ Changes: - - * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed - pbuf_refresh(). This has sped up pbuf pool operations considerably. - Implemented by David Haas. - -(0.6.1) - - ++ New features: - - * The packet buffer implementation has been enhanced to support - zero-copy and copy-on-demand for packet buffers which have their - payloads in application-managed memory. - Implemented by David Haas. - - Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy - if an outgoing packet can be directly sent on the link, or perform - a copy-on-demand when necessary. - - The application can safely assume the packet is sent, and the RAM - is available to the application directly after calling udp_send() - or similar function. - - ++ Bugfixes: - - * ARP_QUEUEING should now correctly work for all cases, including - PBUF_REF. - Implemented by Leon Woestenberg. - - ++ Changes: - - * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer - to a '0.0.0.0' IP address. - - * The packet buffer implementation is changed. The pbuf->ref counter - meaning has changed, and several pbuf functions have been - adapted accordingly. - - * netif drivers have to be changed to set the hardware address length field - that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). - See the contrib/ports/c16x cs8900 driver as a driver example. - - * netif's have a dhcp field that must be initialized to NULL by the driver. - See the contrib/ports/c16x cs8900 driver as a driver example. - -(0.5.x) This file has been unmaintained up to 0.6.1. All changes are - logged in CVS but have not been explained here. - -(0.5.3) Changes since version 0.5.2 - - ++ Bugfixes: - - * memp_malloc(MEMP_API_MSG) could fail with multiple application - threads because it wasn't protected by semaphores. - - ++ Other changes: - - * struct ip_addr now packed. - - * The name of the time variable in arp.c has been changed to ctime - to avoid conflicts with the time() function. - -(0.5.2) Changes since version 0.5.1 - - ++ New features: - - * A new TCP function, tcp_tmr(), now handles both TCP timers. - - ++ Bugfixes: - - * A bug in tcp_parseopt() could cause the stack to hang because of a - malformed TCP option. - - * The address of new connections in the accept() function in the BSD - socket library was not handled correctly. - - * pbuf_dechain() did not update the ->tot_len field of the tail. - - * Aborted TCP connections were not handled correctly in all - situations. - - ++ Other changes: - - * All protocol header structs are now packed. - - * The ->len field in the tcp_seg structure now counts the actual - amount of data, and does not add one for SYN and FIN segments. - -(0.5.1) Changes since version 0.5.0 - - ++ New features: - - * Possible to run as a user process under Linux. - - * Preliminary support for cross platform packed structs. - - * ARP timer now implemented. - - ++ Bugfixes: - - * TCP output queue length was badly initialized when opening - connections. - - * TCP delayed ACKs were not sent correctly. - - * Explicit initialization of BSS segment variables. - - * read() in BSD socket library could drop data. - - * Problems with memory alignment. - - * Situations when all TCP buffers were used could lead to - starvation. - - * TCP MSS option wasn't parsed correctly. - - * Problems with UDP checksum calculation. - - * IP multicast address tests had endianess problems. - - * ARP requests had wrong destination hardware address. - - ++ Other changes: - - * struct eth_addr changed from u16_t[3] array to u8_t[6]. - - * A ->linkoutput() member was added to struct netif. - - * TCP and UDP ->dest_* struct members where changed to ->remote_*. - - * ntoh* macros are now null definitions for big endian CPUs. - -(0.5.0) Changes since version 0.4.2 - - ++ New features: - - * Redesigned operating system emulation layer to make porting easier. - - * Better control over TCP output buffers. - - * Documenation added. - - ++ Bugfixes: - - * Locking issues in buffer management. - - * Bugfixes in the sequential API. - - * IP forwarding could cause memory leakage. This has been fixed. - - ++ Other changes: - - * Directory structure somewhat changed; the core/ tree has been - collapsed. - -(0.4.2) Changes since version 0.4.1 - - ++ New features: - - * Experimental ARP implementation added. - - * Skeleton Ethernet driver added. - - * Experimental BSD socket API library added. - - ++ Bugfixes: - - * In very intense situations, memory leakage could occur. This has - been fixed. - - ++ Other changes: - - * Variables named "data" and "code" have been renamed in order to - avoid name conflicts in certain compilers. - - * Variable++ have in appliciable cases been translated to ++variable - since some compilers generate better code in the latter case. - -(0.4.1) Changes since version 0.4 - - ++ New features: - - * TCP: Connection attempts time out earlier than data - transmissions. Nagle algorithm implemented. Push flag set on the - last segment in a burst. - - * UDP: experimental support for UDP-Lite extensions. - - ++ Bugfixes: - - * TCP: out of order segments were in some cases handled incorrectly, - and this has now been fixed. Delayed acknowledgements was broken - in 0.4, has now been fixed. Binding to an address that is in use - now results in an error. Reset connections sometimes hung an - application; this has been fixed. - - * Checksum calculation sometimes failed for chained pbufs with odd - lengths. This has been fixed. - - * API: a lot of bug fixes in the API. The UDP API has been improved - and tested. Error reporting and handling has been - improved. Logical flaws and race conditions for incoming TCP - connections has been found and removed. - - * Memory manager: alignment issues. Reallocating memory sometimes - failed, this has been fixed. - - * Generic library: bcopy was flawed and has been fixed. - - ++ Other changes: - - * API: all datatypes has been changed from generic ones such as - ints, to specified ones such as u16_t. Functions that return - errors now have the correct type (err_t). - - * General: A lot of code cleaned up and debugging code removed. Many - portability issues have been fixed. - - * The license was changed; the advertising clause was removed. - - * C64 port added. - - * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri - Kosunen, Mikael Caleres, and Frits Wilmink for reporting and - fixing bugs! - -(0.4) Changes since version 0.3.1 - - * Memory management has been radically changed; instead of - allocating memory from a shared heap, memory for objects that are - rapidly allocated and deallocated is now kept in pools. Allocation - and deallocation from those memory pools is very fast. The shared - heap is still present but is used less frequently. - - * The memory, memory pool, and packet buffer subsystems now support - 4-, 2-, or 1-byte alignment. - - * "Out of memory" situations are handled in a more robust way. - - * Stack usage has been reduced. - - * Easier configuration of lwIP parameters such as memory usage, - TTLs, statistics gathering, etc. All configuration parameters are - now kept in a single header file "lwipopts.h". - - * The directory structure has been changed slightly so that all - architecture specific files are kept under the src/arch - hierarchy. - - * Error propagation has been improved, both in the protocol modules - and in the API. - - * The code for the RTXC architecture has been implemented, tested - and put to use. - - * Bugs have been found and corrected in the TCP, UDP, IP, API, and - the Internet checksum modules. - - * Bugs related to porting between a 32-bit and a 16-bit architecture - have been found and corrected. - - * The license has been changed slightly to conform more with the - original BSD license, including the advertisement clause. - -(0.3.1) Changes since version 0.3 - - * Fix of a fatal bug in the buffer management. Pbufs with allocated - RAM never returned the RAM when the pbuf was deallocated. - - * TCP congestion control, window updates and retransmissions did not - work correctly. This has now been fixed. - - * Bugfixes in the API. - -(0.3) Changes since version 0.2 - - * New and improved directory structure. All include files are now - kept in a dedicated include/ directory. - - * The API now has proper error handling. A new function, - netconn_err(), now returns an error code for the connection in - case of errors. - - * Improvements in the memory management subsystem. The system now - keeps a pointer to the lowest free memory block. A new function, - mem_malloc2() tries to allocate memory once, and if it fails tries - to free some memory and retry the allocation. - - * Much testing has been done with limited memory - configurations. lwIP now does a better job when overloaded. - - * Some bugfixes and improvements to the buffer (pbuf) subsystem. - - * Many bugfixes in the TCP code: - - - Fixed a bug in tcp_close(). - - - The TCP receive window was incorrectly closed when out of - sequence segments was received. This has been fixed. - - - Connections are now timed-out of the FIN-WAIT-2 state. - - - The initial congestion window could in some cases be too - large. This has been fixed. - - - The retransmission queue could in some cases be screwed up. This - has been fixed. - - - TCP RST flag now handled correctly. - - - Out of sequence data was in some cases never delivered to the - application. This has been fixed. - - - Retransmitted segments now contain the correct acknowledgment - number and advertised window. - - - TCP retransmission timeout backoffs are not correctly computed - (ala BSD). After a number of retransmissions, TCP now gives up - the connection. - - * TCP connections now are kept on three lists, one for active - connections, one for listening connections, and one for - connections that are in TIME-WAIT. This greatly speeds up the fast - timeout processing for sending delayed ACKs. - - * TCP now provides proper feedback to the application when a - connection has been successfully set up. - - * More comments have been added to the code. The code has also been - somewhat cleaned up. - -(0.2) Initial public release. diff --git a/v2rayng/badvpn/lwip/CMakeLists.txt b/v2rayng/badvpn/lwip/CMakeLists.txt deleted file mode 100644 index b9e445bd77..0000000000 --- a/v2rayng/badvpn/lwip/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(LWIP_SOURCES - src/core/udp.c - src/core/memp.c - src/core/init.c - src/core/pbuf.c - src/core/tcp.c - src/core/tcp_out.c - src/core/sys.c - src/core/netif.c - src/core/def.c - src/core/mem.c - src/core/tcp_in.c - src/core/stats.c - src/core/ip.c - src/core/timeouts.c - src/core/inet_chksum.c - src/core/ipv4/icmp.c - src/core/ipv4/ip4.c - src/core/ipv4/ip4_addr.c - src/core/ipv4/ip4_frag.c - src/core/ipv6/ip6.c - src/core/ipv6/nd6.c - src/core/ipv6/icmp6.c - src/core/ipv6/ip6_addr.c - src/core/ipv6/ip6_frag.c - custom/sys.c -) -badvpn_add_library(lwip "system" "" "${LWIP_SOURCES}") diff --git a/v2rayng/badvpn/lwip/COPYING b/v2rayng/badvpn/lwip/COPYING deleted file mode 100644 index e23898b5e8..0000000000 --- a/v2rayng/badvpn/lwip/COPYING +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - - diff --git a/v2rayng/badvpn/lwip/FILES b/v2rayng/badvpn/lwip/FILES deleted file mode 100644 index e6e09989d9..0000000000 --- a/v2rayng/badvpn/lwip/FILES +++ /dev/null @@ -1,5 +0,0 @@ -src/ - The source code for the lwIP TCP/IP stack. -doc/ - The documentation for lwIP. -test/ - Some code to test whether the sources do what they should. - -See also the FILES file in each subdirectory. diff --git a/v2rayng/badvpn/lwip/README b/v2rayng/badvpn/lwip/README deleted file mode 100644 index 0884d27bea..0000000000 --- a/v2rayng/badvpn/lwip/README +++ /dev/null @@ -1,100 +0,0 @@ -INTRODUCTION - -lwIP is a small independent implementation of the TCP/IP protocol -suite that has been developed by Adam Dunkels at the Computer and -Networks Architectures (CNA) lab at the Swedish Institute of Computer -Science (SICS). - -The focus of the lwIP TCP/IP implementation is to reduce the RAM usage -while still having a full scale TCP. This making lwIP suitable for use -in embedded systems with tens of kilobytes of free RAM and room for -around 40 kilobytes of code ROM. - - -FEATURES - - * IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over - multiple network interfaces - * ICMP (Internet Control Message Protocol) for network maintenance and debugging - * IGMP (Internet Group Management Protocol) for multicast traffic management - * MLD (Multicast listener discovery for IPv6). Aims to be compliant with - RFC 2710. No support for MLDv2 - * ND (Neighbor discovery and stateless address autoconfiguration for IPv6). - Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - (Address autoconfiguration) - * UDP (User Datagram Protocol) including experimental UDP-lite extensions - * TCP (Transmission Control Protocol) with congestion control, RTT estimation - and fast recovery/fast retransmit - * raw/native API for enhanced performance - * Optional Berkeley-like socket API - * DNS (Domain names resolver) - - -APPLICATIONS - - * HTTP server with SSI and CGI - * SNMPv2c agent with MIB compiler (Simple Network Management Protocol) - * SNTP (Simple network time protocol) - * NetBIOS name service responder - * MDNS (Multicast DNS) responder - * iPerf server implementation - - -LICENSE - -lwIP is freely available under a BSD license. - - -DEVELOPMENT - -lwIP has grown into an excellent TCP/IP stack for embedded devices, -and developers using the stack often submit bug fixes, improvements, -and additions to the stack to further increase its usefulness. - -Development of lwIP is hosted on Savannah, a central point for -software development, maintenance and distribution. Everyone can -help improve lwIP by use of Savannah's interface, Git and the -mailing list. A core team of developers will commit changes to the -Git source tree. - -The lwIP TCP/IP stack is maintained in the 'lwip' Git module and -contributions (such as platform ports) are in the 'contrib' Git module. - -See doc/savannah.txt for details on Git server access for users and -developers. - -The current Git trees are web-browsable: - http://git.savannah.gnu.org/cgit/lwip.git - http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git - -Submit patches and bugs via the lwIP project page: - http://savannah.nongnu.org/projects/lwip/ - -Continuous integration builds (GCC, clang): - https://travis-ci.org/yarrick/lwip-merged - - -DOCUMENTATION - -Self documentation of the source code is regularly extracted from the current -Git sources and is available from this web page: - http://www.nongnu.org/lwip/ - -There is now a constantly growing wiki about lwIP at - http://lwip.wikia.com/wiki/LwIP_Wiki - -Also, there are mailing lists you can subscribe at - http://savannah.nongnu.org/mail/?group=lwip -plus searchable archives: - http://lists.nongnu.org/archive/html/lwip-users/ - http://lists.nongnu.org/archive/html/lwip-devel/ - -lwIP was originally written by Adam Dunkels: - http://dunkels.com/adam/ - -Reading Adam's papers, the files in docs/, browsing the source code -documentation and browsing the mailing list archives is a good way to -become familiar with the design of lwIP. - -Adam Dunkels -Leon Woestenberg diff --git a/v2rayng/badvpn/lwip/UPGRADING b/v2rayng/badvpn/lwip/UPGRADING deleted file mode 100644 index 85be6c90dc..0000000000 --- a/v2rayng/badvpn/lwip/UPGRADING +++ /dev/null @@ -1,275 +0,0 @@ -This file lists major changes between release versions that require -ports or applications to be changed. Use it to update a port or an -application written for an older version of lwIP to correctly work -with newer versions. - - -(git master) - - * [Enter new changes just after this line - do not remove this line] - - ++ Application changes: - - * ip4_route_src: parameter order is reversed: ip4_route_src(dest, src) -> ip4_route_src(src, dest) - to make parameter order consistent with other ip*_route*() functions. - Same also applies to LWIP_HOOK_IP4_ROUTE_SRC() parameter order. - - * pbuf API: pbuf->type (an u8_t holding the enum 'pbuf_type') has changed to only hold a - description of the pbuf (e.g. data following pbuf struct, data volatile, allocation - source heap/pool/etc.). As a consequence, applications can't test pbuf->type any more. - Use pbuf_match_type(pbuf, type) instead. - - * socket API: according to the standard, SO_ERROR now only returns asynchronous errors. - All other/normal/synchronous errors are (and always were) available via 'errno'. - LWIP_SOCKET_SET_ERRNO has been removed - 'errno' is always set - and required! - - * compatibility headers: moved from 'src/include/posix' to 'src/include/compat/posix', - 'src/include/compat/stdc' etc. - - * The IPv6 implementation now supports address scopes. All addresses that have a scope according - to the default policy (link-local unicast addresses, interface-local and link-local multicast - addresses) should now have a zone set on them before being passed to the core API, although - lwIP will currently attempt to select a zone on the caller's behalf when necessary. - Applications that directly assign IPv6 addresses to interfaces (which is NOT recommended) - must now ensure that link-local addresses carry the netif's zone. See the new ip6_zone.h header - file for more information and relevant macros. For now it is still possible to turn off scopes - support through the new LWIP_IPV6_SCOPES option. When upgrading an implementation that uses the - core API directly, it is highly recommended to enable LWIP_IPV6_SCOPES_DEBUG at least for - a while, to ensure e.g. proper address initialization. - - * LWIP_HOOK_DHCP_APPEND_OPTIONS() has changed, see description in opt.h (options_out_len is not - available in struct dhcp any more) - -(2.0.2) - - ++ Application changes: - - * slipif: The way to pass serial port number has changed. netif->num is not - supported any more, netif->state is interpreted as an u8_t port number now - (it's not a POINTER to an u8_t any more!) - -(2.0.1) - - ++ Application changes: - - * UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific - netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare - ip_current_netif() to the desired netif for every packet. - See bug #49662 for an explanation. - -(2.0.0) - - ++ Application changes: - - * Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of - "ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif - has to be set "up" before starting the DHCP client - * Added IPv6 support (dual-stack or IPv4/IPv6 only) - * Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only). - * Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs); - supports SNMPv2c (experimental v3 support) - * Moved some core applications from contrib repository to src/apps (and include/lwip/apps) - - +++ Raw API: - * Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/ - tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb - - +++ Socket API: - * Added an implementation for posix sendmsg() - * Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram - - ++ Port changes - - +++ new files: - * MANY new and moved files! - * Added src/Filelists.mk for use in Makefile projects - * Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv" - to let abc.h only contain the actual application programmer's API - - +++ sys layer: - * Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than - the traditional message passing (although with LWIP_COMPAT_MUTEX you are still - open to priority inversion, so this is not recommended any more) - * Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread - instead of using one per netconn (these semaphores are used even with core locking - enabled as some longer lasting functions like big writes still need to delay) - * Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr() - in def.h (to be overridden in cc.h) instead of config - options for netbiosns, httpd, dns, etc. ... - * New abstraction for hton* and ntoh* functions in def.h. - To override them, use the following in cc.h: - #define lwip_htons(x) - #define lwip_htonl(x) - - +++ new options: - * TODO - - +++ new pools: - * Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools - that share memp.c code but do not have to be made global via lwippools.h - * Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc. - * added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item - is now available - - * Signature of LWIP_HOOK_VLAN_SET macro was changed - - * LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp) - or to move buffers to dedicated memory using compiler attributes - - * Standard C headers are used to define sized types and printf formatters - (disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler - does not support these) - - - ++ Major bugfixes/improvements - - * Added IPv6 support (dual-stack or IPv4/IPv6 only) - * Major rewrite of PPP (incl. keep-up with apache pppd) - see doc/ppp.txt for an upgrading how-to - * Major rewrite of SNMP (incl. MIB parser) - * Fixed timing issues that might have lead to losing a DHCP lease - * Made rx processing path more robust against crafted errors - * TCP window scaling support - * modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads) - * made DNS client more robust - * support PBUF_REF for RX packets - * LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate - threads each (needs LWIP_NETCONN_SEM_PER_THREAD) - * Moved and reordered stats (mainly memp/mib2) - -(1.4.0) - - ++ Application changes: - - * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for - compatibility to old applications, but will be removed in the future). - - * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() - - +++ Raw API: - * Changed the semantics of tcp_close() (since it was rather a - shutdown before): Now the application does *NOT* get any calls to the recv - callback (aside from NULL/closed) after calling tcp_close() - - * When calling tcp_abort() from a raw API TCP callback function, - make sure you return ERR_ABRT to prevent accessing unallocated memory. - (ERR_ABRT now means the applicaiton has called tcp_abort!) - - +++ Netconn API: - * Changed netconn_receive() and netconn_accept() to return - err_t, not a pointer to new data/netconn. - - +++ Socket API: - * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they - now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. - - * Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - +++ all APIs: - * correctly implemented SO(F)_REUSEADDR - - ++ Port changes - - +++ new files: - - * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: - - * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains - the actual application programmer's API - - * Separated timer implementation from sys.h/.c, moved to timers.h/.c; - Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you - still want to use your own timer implementation for NO_SYS==0 (as before). - - +++ sys layer: - - * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ - sys_sem_t; - - * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - - * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use - binary semaphores instead of mutexes - as before) - - +++ new options: - - * Don't waste memory when chaining segments, added option TCP_OVERSIZE to - prevent creating many small pbufs when calling tcp_write with many small - blocks of data. Instead, pbufs are allocated larger than needed and the - space is used for later calls to tcp_write. - - * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs - in tcp_write/udp_send. - - * Added an additional option LWIP_ETHERNET to support ethernet without ARP - (necessary for pure PPPoE) - - * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may - be used to place these pools into user-defined memory by using external - declaration. - - * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT - - +++ new pools: - - * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, - so MEMP_NUM_NETDB has to be set accordingly. - - * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so - MEMP_NUM_LOCALHOSTLIST has to be set accordingly. - - * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have - to be set accordingly. - - * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES - has to be set accordingly - - * Integrated loopif into netif.c - loopif does not have to be created by the - port any more, just define LWIP_HAVE_LOOPIF to 1. - - * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined - in cc.h, e.g. used by igmp) - - * Added printf-formatter X8_F to printf u8_t as hex - - * The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - - * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work - with user-allocated structs instead of calling mem_malloc - - * Added const char* name to mem- and memp-stats for easier debugging. - - * Calculate the TCP/UDP checksum while copying to only fetch data once: - Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum - - * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to - more than one pcb. - - * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned - off any more, if this is set to 0, only one packet (the most recent one) is - queued (like demanded by RFC 1122). - - - ++ Major bugfixes/improvements - - * Implemented tcp_shutdown() to only shut down one end of a connection - * Implemented shutdown() at socket- and netconn-level - * Added errorset support to select() + improved select speed overhead - * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) - * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 - * Use macros defined in ip_addr.h to work with IP addresses - * Implemented many nonblocking socket/netconn functions - * Fixed ARP input processing: only add a new entry if a request was directed as us - * mem_realloc() to mem_trim() to prevent confusion with realloc() - * Some improvements for AutoIP (don't route/forward link-local addresses, don't break - existing connections when assigning a routable address) - * Correctly handle remote side overrunning our rcv_wnd in ooseq case - * Removed packing from ip_addr_t, the packed version is now only used in protocol headers - * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 - * Added support for static ARP table entries - -(STABLE-1.3.2) - - * initial version of this file diff --git a/v2rayng/badvpn/lwip/astylerc b/v2rayng/badvpn/lwip/astylerc deleted file mode 100644 index 3f2209a08b..0000000000 --- a/v2rayng/badvpn/lwip/astylerc +++ /dev/null @@ -1,22 +0,0 @@ -# lwIP astyle formatting options - -# NOT FINISHED - DON'T USE - -# braces and indent -style=otbs -indent=spaces=2 -attach-extern-c -#attach-closing-while -# indentation -indent-switches -#max-continuation-indent=40 -# padding -pad-oper -pad-comma -pad-header -align-pointer=name -# formatting -break-one-line-headers -keep-one-line-blocks -# don't use "other options" (e.g. formatted) in this file -# send them as additional command line options diff --git a/v2rayng/badvpn/lwip/custom/arch/cc.h b/v2rayng/badvpn/lwip/custom/arch/cc.h deleted file mode 100644 index 4af94aa339..0000000000 --- a/v2rayng/badvpn/lwip/custom/arch/cc.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file cc.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_CUSTOM_CC_H -#define LWIP_CUSTOM_CC_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define PACK_STRUCT_BEGIN B_START_PACKED -#define PACK_STRUCT_END B_END_PACKED -#define PACK_STRUCT_STRUCT B_PACKED - -#define LWIP_PLATFORM_DIAG(x) { if (BLog_WouldLog(BLOG_CHANNEL_lwip, BLOG_INFO)) { BLog_Begin(); BLog_Append x; BLog_Finish(BLOG_CHANNEL_lwip, BLOG_INFO); } } -#define LWIP_PLATFORM_ASSERT(x) { fprintf(stderr, "%s: lwip assertion failure: %s\n", __FUNCTION__, (x)); abort(); } - -#define lwip_htons(x) hton16(x) -#define lwip_htonl(x) hton32(x) - -#define LWIP_RAND() ( \ - (((uint32_t)(rand() & 0xFF)) << 24) | \ - (((uint32_t)(rand() & 0xFF)) << 16) | \ - (((uint32_t)(rand() & 0xFF)) << 8) | \ - (((uint32_t)(rand() & 0xFF)) << 0) \ -) - -// for BYTE_ORDER -#if defined(BADVPN_USE_WINAPI) && !defined(_MSC_VER) - #include -#elif defined(BADVPN_LINUX) - #include -#elif defined(BADVPN_FREEBSD) - #include -#else - #define LITTLE_ENDIAN 1234 - #define BIG_ENDIAN 4321 - #if defined(BADVPN_LITTLE_ENDIAN) - #define BYTE_ORDER LITTLE_ENDIAN - #else - #define BYTE_ORDER BIG_ENDIAN - #endif -#endif - -#endif diff --git a/v2rayng/badvpn/lwip/custom/lwipopts.h b/v2rayng/badvpn/lwip/custom/lwipopts.h deleted file mode 100644 index 9605d2fcb9..0000000000 --- a/v2rayng/badvpn/lwip/custom/lwipopts.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file lwipopts.h - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_CUSTOM_LWIPOPTS_H -#define LWIP_CUSTOM_LWIPOPTS_H - -#define NO_SYS 1 -#define LWIP_TIMERS 0 -#define MEM_ALIGNMENT 4 - -#define LWIP_ARP 0 -#define ARP_QUEUEING 0 -#define IP_FORWARD 0 -#define LWIP_ICMP 1 -#define LWIP_RAW 0 -#define LWIP_DHCP 0 -#define LWIP_AUTOIP 0 -#define LWIP_SNMP 0 -#define LWIP_IGMP 0 -#define LWIP_DNS 0 -#define LWIP_UDP 0 -#define LWIP_UDPLITE 0 -#define LWIP_TCP 1 -#define LWIP_CALLBACK_API 1 -#define LWIP_NETIF_API 0 -#define LWIP_NETIF_LOOPBACK 0 -#define LWIP_HAVE_LOOPIF 0 -#define LWIP_HAVE_SLIPIF 0 -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 -#define PPP_SUPPORT 0 -#define LWIP_IPV6 1 -#define LWIP_IPV6_MLD 0 -#define LWIP_IPV6_AUTOCONFIG 0 - -#define MEMP_NUM_TCP_PCB_LISTEN 16 -#define MEMP_NUM_TCP_PCB 1024 -#define TCP_MSS 1460 -#define TCP_SND_BUF 16384 -#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS)) - -#define MEM_LIBC_MALLOC 1 -#define MEMP_MEM_MALLOC 1 - -#define LWIP_PERF 0 -#define SYS_LIGHTWEIGHT_PROT 0 -#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS - -// needed on 64-bit systems, enable it always so that the same configuration -// is used regardless of the platform -#define IPV6_FRAG_COPYHEADER 1 - -/* -#define LWIP_DEBUG 1 -#define IP_DEBUG LWIP_DBG_ON -#define NETIF_DEBUG LWIP_DBG_ON -#define TCP_DEBUG LWIP_DBG_ON -#define TCP_INPUT_DEBUG LWIP_DBG_ON -#define TCP_OUTPUT_DEBUG LWIP_DBG_ON -*/ - -#endif diff --git a/v2rayng/badvpn/lwip/custom/sys.c b/v2rayng/badvpn/lwip/custom/sys.c deleted file mode 100644 index efd14559ac..0000000000 --- a/v2rayng/badvpn/lwip/custom/sys.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file sys.c - * @author Ambroz Bizjak - * - * @section LICENSE - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -u32_t sys_now (void) -{ - return btime_gettime(); -} diff --git a/v2rayng/badvpn/lwip/doc/FILES b/v2rayng/badvpn/lwip/doc/FILES deleted file mode 100644 index e588575085..0000000000 --- a/v2rayng/badvpn/lwip/doc/FILES +++ /dev/null @@ -1,9 +0,0 @@ -doxygen/ - Configuration files and scripts to create the lwIP doxygen source - documentation (found at http://www.nongnu.org/lwip/) - -savannah.txt - How to obtain the current development source code. -contrib.txt - How to contribute to lwIP as a developer. -rawapi.txt - The documentation for the core API of lwIP. - Also provides an overview about the other APIs and multithreading. -sys_arch.txt - The documentation for a system abstraction layer of lwIP. -ppp.txt - Documentation of the PPP interface for lwIP. diff --git a/v2rayng/badvpn/lwip/doc/NO_SYS_SampleCode.c b/v2rayng/badvpn/lwip/doc/NO_SYS_SampleCode.c deleted file mode 100644 index f0af6600b7..0000000000 --- a/v2rayng/badvpn/lwip/doc/NO_SYS_SampleCode.c +++ /dev/null @@ -1,122 +0,0 @@ -void -eth_mac_irq() -{ - /* Service MAC IRQ here */ - - /* Allocate pbuf from pool (avoid using heap in interrupts) */ - struct pbuf* p = pbuf_alloc(PBUF_RAW, eth_data_count, PBUF_POOL); - - if(p != NULL) { - /* Copy ethernet frame into pbuf */ - pbuf_take(p, eth_data, eth_data_count); - - /* Put in a queue which is processed in main loop */ - if(!queue_try_put(&queue, p)) { - /* queue is full -> packet loss */ - pbuf_free(p); - } - } -} - -static err_t -netif_output(struct netif *netif, struct pbuf *p) -{ - LINK_STATS_INC(link.xmit); - - /* Update SNMP stats (only if you use SNMP) */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - int unicast = ((p->payload[0] & 0x01) == 0); - if (unicast) { - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } else { - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - } - - lock_interrupts(); - pbuf_copy_partial(p, mac_send_buffer, p->tot_len, 0); - /* Start MAC transmit here */ - unlock_interrupts(); - - return ERR_OK; -} - -static void -netif_status_callback(struct netif *netif) -{ - printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif))); -} - -static err_t -netif_init(struct netif *netif) -{ - netif->linkoutput = netif_output; - netif->output = etharp_output; - netif->output_ip6 = ethip6_output; - netif->mtu = ETHERNET_MTU; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6; - MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 100000000); - - SMEMCPY(netif->hwaddr, your_mac_address_goes_here, sizeof(netif->hwaddr)); - netif->hwaddr_len = sizeof(netif->hwaddr); - - return ERR_OK; -} - -void -main(void) -{ - struct netif netif; - - lwip_init(); - - netif_add(&netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY, NULL, netif_init, netif_input); - netif.name[0] = 'e'; - netif.name[1] = '0'; - netif_create_ip6_linklocal_address(&netif, 1); - netif.ip6_autoconfig_enabled = 1; - netif_set_status_callback(&netif, netif_status_callback); - netif_set_default(&netif); - netif_set_up(&netif); - - /* Start DHCP and HTTPD */ - dhcp_start(&netif ); - httpd_init(); - - while(1) { - /* Check link state, e.g. via MDIO communication with PHY */ - if(link_state_changed()) { - if(link_is_up()) { - netif_set_link_up(&netif); - } else { - netif_set_link_down(&netif); - } - } - - /* Check for received frames, feed them to lwIP */ - lock_interrupts(); - struct pbuf* p = queue_try_get(&queue); - unlock_interrupts(); - - if(p != NULL) { - LINK_STATS_INC(link.recv); - - /* Update SNMP stats (only if you use SNMP) */ - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - int unicast = ((p->payload[0] & 0x01) == 0); - if (unicast) { - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - } else { - MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); - } - - if(netif.input(p, &netif) != ERR_OK) { - pbuf_free(p); - } - } - - /* Cyclic lwIP timers check */ - sys_check_timeouts(); - - /* your application goes here */ - } -} diff --git a/v2rayng/badvpn/lwip/doc/ZeroCopyRx.c b/v2rayng/badvpn/lwip/doc/ZeroCopyRx.c deleted file mode 100644 index 525b28ff5a..0000000000 --- a/v2rayng/badvpn/lwip/doc/ZeroCopyRx.c +++ /dev/null @@ -1,39 +0,0 @@ -typedef struct my_custom_pbuf -{ - struct pbuf_custom p; - void* dma_descriptor; -} my_custom_pbuf_t; - -LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(my_custom_pbuf_t), "Zero-copy RX PBUF pool"); - -void my_pbuf_free_custom(void* p) -{ - my_custom_pbuf_t* my_puf = (my_custom_pbuf_t*)p; - - LOCK_INTERRUPTS(); - free_rx_dma_descriptor(my_pbuf->dma_descriptor); - LWIP_MEMPOOL_FREE(RX_POOL, my_pbuf); - UNLOCK_INTERRUPTS(); -} - -void eth_rx_irq() -{ - dma_descriptor* dma_desc = get_RX_DMA_descriptor_from_ethernet(); - my_custom_pbuf_t* my_pbuf = (my_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(RX_POOL); - - my_pbuf->p.custom_free_function = my_pbuf_free_custom; - my_pbuf->dma_descriptor = dma_desc; - - invalidate_cpu_cache(dma_desc->rx_data, dma_desc->rx_length); - - struct pbuf* p = pbuf_alloced_custom(PBUF_RAW, - dma_desc->rx_length, - PBUF_REF, - &my_pbuf->p, - dma_desc->rx_data, - dma_desc->max_buffer_size); - - if(netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } -} diff --git a/v2rayng/badvpn/lwip/doc/contrib.txt b/v2rayng/badvpn/lwip/doc/contrib.txt deleted file mode 100644 index 6f0d7bc516..0000000000 --- a/v2rayng/badvpn/lwip/doc/contrib.txt +++ /dev/null @@ -1,58 +0,0 @@ -1 Introduction - -This document describes some guidelines for people participating -in lwIP development. - -2 How to contribute to lwIP - -Here is a short list of suggestions to anybody working with lwIP and -trying to contribute bug reports, fixes, enhancements, platform ports etc. -First of all as you may already know lwIP is a volunteer project so feedback -to fixes or questions might often come late. Hopefully the bug and patch tracking -features of Savannah help us not lose users' input. - -2.1 Source code style: - -1. do not use tabs. -2. indentation is two spaces per level (i.e. per tab). -3. end debug messages with a trailing newline (\n). -4. one space between keyword and opening bracket. -5. no space between function and opening bracket. -6. one space and no newline before opening curly braces of a block. -7. closing curly brace on a single line. -8. spaces surrounding assignment and comparisons. -9. don't initialize static and/or global variables to zero, the compiler takes care of that. -10. use current source code style as further reference. - -2.2 Source code documentation style: - -1. JavaDoc compliant and Doxygen compatible. -2. Function documentation above functions in .c files, not .h files. - (This forces you to synchronize documentation and implementation.) -3. Use current documentation style as further reference. - -2.3 Bug reports and patches: - -1. Make sure you are reporting bugs or send patches against the latest - sources. (From the latest release and/or the current Git sources.) -2. If you think you found a bug make sure it's not already filed in the - bugtracker at Savannah. -3. If you have a fix put the patch on Savannah. If it is a patch that affects - both core and arch specific stuff please separate them so that the core can - be applied separately while leaving the other patch 'open'. The preferred way - is to NOT touch archs you can't test and let maintainers take care of them. - This is a good way to see if they are used at all - the same goes for unix - netifs except tapif. -4. Do not file a bug and post a fix to it to the patch area. Either a bug report - or a patch will be enough. - If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. -5. Patches should be specific to a single change or to related changes. Do not mix bugfixes with spelling and other - trivial fixes unless the bugfix is trivial too. Do not reorganize code and rename identifiers in the same patch you - change behaviour if not necessary. A patch is easier to read and understand if it's to the point and short than - if it's not to the point and long :) so the chances for it to be applied are greater. - -2.4 Platform porters: - -1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and - you think it could benefit others[1] you might want discuss this on the mailing list. You - can also ask for Git access to submit and maintain your port in the contrib Git module. diff --git a/v2rayng/badvpn/lwip/doc/doxygen/generate.bat b/v2rayng/badvpn/lwip/doc/doxygen/generate.bat deleted file mode 100644 index 99afb124be..0000000000 --- a/v2rayng/badvpn/lwip/doc/doxygen/generate.bat +++ /dev/null @@ -1 +0,0 @@ -doxygen lwip.Doxyfile diff --git a/v2rayng/badvpn/lwip/doc/doxygen/generate.sh b/v2rayng/badvpn/lwip/doc/doxygen/generate.sh deleted file mode 100755 index 89344b0e81..0000000000 --- a/v2rayng/badvpn/lwip/doc/doxygen/generate.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -doxygen lwip.Doxyfile diff --git a/v2rayng/badvpn/lwip/doc/doxygen/lwip.Doxyfile b/v2rayng/badvpn/lwip/doc/doxygen/lwip.Doxyfile deleted file mode 100644 index c8aaaabb39..0000000000 --- a/v2rayng/badvpn/lwip/doc/doxygen/lwip.Doxyfile +++ /dev/null @@ -1,2510 +0,0 @@ -# Doxyfile 1.8.11 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "lwIP" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = "2.0.3" - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "Lightweight IP stack" - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = output - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class " \ - "The $name widget " \ - "The $name file " \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = ../../ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = NO - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text " - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = main_page.h ../../src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, -# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.inc \ - *.m \ - *.mm \ - *.dox - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = ../../src/include/netif/ppp/polarssl - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = ../ ../../ - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = main_page.h - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = NO - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse-libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = lwip.chm - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /