From f16ef0097565f4835fb1fd04074c9310fa22a30b Mon Sep 17 00:00:00 2001 From: fatedier Date: Thu, 21 Mar 2024 17:34:09 +0800 Subject: [PATCH] set CompatibilityMode for android (#4091) --- Makefile.cross-compiles | 2 +- Release.md | 1 + cmd/frpc/main.go | 2 + cmd/frps/main.go | 5 +-- pkg/util/net/dns.go | 4 +- pkg/util/system/system.go | 22 +++++++++++ pkg/util/system/system_android.go | 66 +++++++++++++++++++++++++++++++ server/service.go | 2 + 8 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 pkg/util/system/system.go create mode 100644 pkg/util/system/system_android.go diff --git a/Makefile.cross-compiles b/Makefile.cross-compiles index 1040ef2..8887cad 100644 --- a/Makefile.cross-compiles +++ b/Makefile.cross-compiles @@ -2,7 +2,7 @@ export PATH := $(PATH):`go env GOPATH`/bin export GO111MODULE=on LDFLAGS := -s -w -os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 +os-archs=darwin:amd64 darwin:arm64 freebsd:amd64 linux:amd64 linux:arm linux:arm64 windows:amd64 windows:arm64 linux:mips64 linux:mips64le linux:mips:softfloat linux:mipsle:softfloat linux:riscv64 android:arm64 all: build diff --git a/Release.md b/Release.md index ca58a04..9682800 100644 --- a/Release.md +++ b/Release.md @@ -17,6 +17,7 @@ This will create 8 proxies such as `tcp-6000, tcp-6001, ... tcp-6007`. * Health check supports custom request headers. +* Enable compatibility mode for the Android system to solve the issues of incorrect log time caused by time zone problems and default DNS resolution failures. ### Fixes diff --git a/cmd/frpc/main.go b/cmd/frpc/main.go index f9a6c25..f7651bc 100644 --- a/cmd/frpc/main.go +++ b/cmd/frpc/main.go @@ -17,8 +17,10 @@ package main import ( _ "github.com/fatedier/frp/assets/frpc" "github.com/fatedier/frp/cmd/frpc/sub" + "github.com/fatedier/frp/pkg/util/system" ) func main() { + system.EnableCompatibilityMode() sub.Execute() } diff --git a/cmd/frps/main.go b/cmd/frps/main.go index 34676a2..3cb398d 100644 --- a/cmd/frps/main.go +++ b/cmd/frps/main.go @@ -15,13 +15,12 @@ package main import ( - "github.com/fatedier/golib/crypto" - _ "github.com/fatedier/frp/assets/frps" _ "github.com/fatedier/frp/pkg/metrics" + "github.com/fatedier/frp/pkg/util/system" ) func main() { - crypto.DefaultSalt = "frp" + system.EnableCompatibilityMode() Execute() } diff --git a/pkg/util/net/dns.go b/pkg/util/net/dns.go index 5e1d5cc..441b1e6 100644 --- a/pkg/util/net/dns.go +++ b/pkg/util/net/dns.go @@ -26,8 +26,8 @@ func SetDefaultDNSAddress(dnsAddress string) { // Change default dns server net.DefaultResolver = &net.Resolver{ PreferGo: true, - Dial: func(ctx context.Context, network, address string) (net.Conn, error) { - return net.Dial("udp", dnsAddress) + Dial: func(ctx context.Context, network, _ string) (net.Conn, error) { + return net.Dial(network, dnsAddress) }, } } diff --git a/pkg/util/system/system.go b/pkg/util/system/system.go new file mode 100644 index 0000000..ae40e85 --- /dev/null +++ b/pkg/util/system/system.go @@ -0,0 +1,22 @@ +// Copyright 2024 The frp Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !android + +package system + +// EnableCompatibilityMode enables compatibility mode for different system. +// For example, on Android, the inability to obtain the correct time zone will result in incorrect log time output. +func EnableCompatibilityMode() { +} diff --git a/pkg/util/system/system_android.go b/pkg/util/system/system_android.go new file mode 100644 index 0000000..bfcf401 --- /dev/null +++ b/pkg/util/system/system_android.go @@ -0,0 +1,66 @@ +// Copyright 2024 The frp Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package system + +import ( + "context" + "net" + "os/exec" + "strings" + "time" +) + +func EnableCompatibilityMode() { + fixTimezone() + fixDNSResolver() +} + +// fixTimezone is used to try our best to fix timezone issue on some Android devices. +func fixTimezone() { + out, err := exec.Command("/system/bin/getprop", "persist.sys.timezone").Output() + if err != nil { + return + } + loc, err := time.LoadLocation(strings.TrimSpace(string(out))) + if err != nil { + return + } + time.Local = loc +} + +// fixDNSResolver will first attempt to resolve google.com to check if the current DNS is available. +// If it is not available, it will default to using 8.8.8.8 as the DNS server. +// This is a workaround for the issue that golang can't get the default DNS servers on Android. +func fixDNSResolver() { + // First, we attempt to resolve a domain. If resolution is successful, no modifications are necessary. + // In real-world scenarios, users may have already configured /etc/resolv.conf, or compiled directly + // in the Android environment instead of using cross-platform compilation, so this issue does not arise. + if net.DefaultResolver != nil { + timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + _, err := net.DefaultResolver.LookupHost(timeoutCtx, "google.com") + if err == nil { + return + } + } + // If the resolution fails, use 8.8.8.8 as the DNS server. + // Note: If there are other methods to obtain the default DNS servers, the default DNS servers should be used preferentially. + net.DefaultResolver = &net.Resolver{ + PreferGo: true, + Dial: func(ctx context.Context, network, _ string) (net.Conn, error) { + return net.Dial(network, "8.8.8.8:53") + }, + } +} diff --git a/server/service.go b/server/service.go index 4fdb216..325f7f6 100644 --- a/server/service.go +++ b/server/service.go @@ -26,6 +26,7 @@ import ( "strconv" "time" + "github.com/fatedier/golib/crypto" "github.com/fatedier/golib/net/mux" fmux "github.com/hashicorp/yamux" quic "github.com/quic-go/quic-go" @@ -61,6 +62,7 @@ const ( ) func init() { + crypto.DefaultSalt = "frp" // Disable quic-go's receive buffer warning. os.Setenv("QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING", "true") // Disable quic-go's ECN support by default. It may cause issues on certain operating systems.