mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-16 17:58:00 +03:00
Compare commits
17 Commits
v1.11.0-be
...
stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
253b41936e | ||
|
|
ce5b4b06b5 | ||
|
|
50f5006c43 | ||
|
|
e42ff22c2e | ||
|
|
578571b972 | ||
|
|
935beca45d | ||
|
|
3e246f1173 | ||
|
|
1bc27a32c2 | ||
|
|
bc2e3960e4 | ||
|
|
9c4ab0bf33 | ||
|
|
27bdef34c7 | ||
|
|
3c00099ed4 | ||
|
|
2babf07f9a | ||
|
|
4795ed712b | ||
|
|
d4cd564dbe | ||
|
|
1676e13d3e | ||
|
|
50576084c6 |
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@@ -170,7 +170,8 @@ jobs:
|
||||
echo "HOME=$HOME" >> "$GITHUB_ENV"
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git tag v${{ needs.calculate_version.outputs.version }}
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
- name: Build
|
||||
if: matrix.goos != 'android'
|
||||
run: |-
|
||||
@@ -230,7 +231,8 @@ jobs:
|
||||
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git tag v${{ needs.calculate_version.outputs.version }}
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
- name: Build library
|
||||
run: |-
|
||||
make lib_install
|
||||
@@ -304,7 +306,8 @@ jobs:
|
||||
/usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git tag v${{ needs.calculate_version.outputs.version }}
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
- name: Build library
|
||||
run: |-
|
||||
make lib_install
|
||||
@@ -393,7 +396,7 @@ jobs:
|
||||
- name: Setup Xcode stable
|
||||
if: matrix.if && github.ref == 'refs/heads/main-next'
|
||||
run: |-
|
||||
sudo xcode-select -s /Applications/Xcode_16.1.app
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app
|
||||
- name: Setup Xcode beta
|
||||
if: matrix.if && github.ref == 'refs/heads/dev-next'
|
||||
run: |-
|
||||
@@ -401,7 +404,8 @@ jobs:
|
||||
- name: Set tag
|
||||
if: matrix.if
|
||||
run: |-
|
||||
git tag v${{ needs.calculate_version.outputs.version }}
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
|
||||
- name: Checkout main branch
|
||||
if: matrix.if && github.ref == 'refs/heads/main-next' && github.event_name != 'workflow_dispatch'
|
||||
@@ -491,6 +495,10 @@ jobs:
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
-authenticationKeyID $ASC_KEY_ID \
|
||||
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
|
||||
- name: Publish to TestFlight
|
||||
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/dev-next'
|
||||
run: |-
|
||||
go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
|
||||
- name: Build image
|
||||
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
@@ -558,7 +566,8 @@ jobs:
|
||||
go install -v .
|
||||
- name: Set tag
|
||||
run: |-
|
||||
git tag v${{ needs.calculate_version.outputs.version }}
|
||||
git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
|
||||
git tag v${{ needs.calculate_version.outputs.version }} -f
|
||||
echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
|
||||
- name: Download builds
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -575,8 +584,16 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
- name: Upload builds
|
||||
if: ${{ env.PUBLISHED == 'false' }}
|
||||
run: |-
|
||||
export PATH="$PATH:$HOME/go/bin"
|
||||
ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist/release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Replace builds
|
||||
if: ${{ env.PUBLISHED != 'false' }}
|
||||
run: |-
|
||||
export PATH="$PATH:$HOME/go/bin"
|
||||
ghr --replace -p 5 "v${VERSION}" dist/release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -22,6 +22,16 @@ linters-settings:
|
||||
|
||||
run:
|
||||
go: "1.23"
|
||||
build-tags:
|
||||
- with_gvisor
|
||||
- with_quic
|
||||
- with_dhcp
|
||||
- with_wireguard
|
||||
- with_ech
|
||||
- with_utls
|
||||
- with_reality_server
|
||||
- with_acme
|
||||
- with_clash_api
|
||||
|
||||
issues:
|
||||
exclude-dirs:
|
||||
|
||||
Submodule clients/android updated: cff12c57dd...b17fb6d857
Submodule clients/apple updated: fa107e3b7c...64a4614aca
@@ -1,30 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/cidertool/asc-go/asc"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
*asc.Client
|
||||
}
|
||||
|
||||
func (c *Client) UpdateBuildForAppStoreVersion(ctx context.Context, id string, buildID *string) (*asc.Response, error) {
|
||||
linkage := newRelationshipDeclaration(buildID, "builds")
|
||||
url := fmt.Sprintf("appStoreVersions/%s/relationships/build", id)
|
||||
return c.patch(ctx, url, newRequestBody(linkage), nil)
|
||||
}
|
||||
|
||||
func newRelationshipDeclaration(id *string, relationshipType string) *asc.RelationshipData {
|
||||
if id == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &asc.RelationshipData{
|
||||
ID: *id,
|
||||
Type: relationshipType,
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/cidertool/asc-go/asc"
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
func (c *Client) newRequest(ctx context.Context, method string, path string, body *requestBody, options ...requestOption) (*http.Request, error) {
|
||||
return clientNewRequest(c.Client, ctx, method, path, body, options...)
|
||||
}
|
||||
|
||||
//go:linkname clientNewRequest github.com/cidertool/asc-go/asc.(*Client).newRequest
|
||||
func clientNewRequest(c *asc.Client, ctx context.Context, method string, path string, body *requestBody, options ...requestOption) (*http.Request, error)
|
||||
|
||||
func (c *Client) do(ctx context.Context, req *http.Request, v interface{}) (*asc.Response, error) {
|
||||
return clientDo(c.Client, ctx, req, v)
|
||||
}
|
||||
|
||||
//go:linkname clientDo github.com/cidertool/asc-go/asc.(*Client).do
|
||||
func clientDo(c *asc.Client, ctx context.Context, req *http.Request, v interface{}) (*asc.Response, error)
|
||||
|
||||
// get sends a GET request to the API as configured.
|
||||
func (c *Client) get(ctx context.Context, url string, query interface{}, v interface{}, options ...requestOption) (*asc.Response, error) {
|
||||
var err error
|
||||
if query != nil {
|
||||
url, err = appendingQueryOptions(url, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
req, err := c.newRequest(ctx, "GET", url, nil, options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.do(ctx, req, v)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// post sends a POST request to the API as configured.
|
||||
func (c *Client) post(ctx context.Context, url string, body *requestBody, v interface{}) (*asc.Response, error) {
|
||||
req, err := c.newRequest(ctx, "POST", url, body, withContentType("application/json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.do(ctx, req, v)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// patch sends a PATCH request to the API as configured.
|
||||
func (c *Client) patch(ctx context.Context, url string, body *requestBody, v interface{}) (*asc.Response, error) {
|
||||
req, err := c.newRequest(ctx, "PATCH", url, body, withContentType("application/json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.do(ctx, req, v)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// delete sends a DELETE request to the API as configured.
|
||||
func (c *Client) delete(ctx context.Context, url string, body *requestBody) (*asc.Response, error) {
|
||||
req, err := c.newRequest(ctx, "DELETE", url, body, withContentType("application/json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// request is a common structure for a request body sent to the API.
|
||||
type requestBody struct {
|
||||
Data interface{} `json:"data"`
|
||||
Included interface{} `json:"included,omitempty"`
|
||||
}
|
||||
|
||||
func newRequestBody(data interface{}) *requestBody {
|
||||
return newRequestBodyWithIncluded(data, nil)
|
||||
}
|
||||
|
||||
func newRequestBodyWithIncluded(data interface{}, included interface{}) *requestBody {
|
||||
return &requestBody{Data: data, Included: included}
|
||||
}
|
||||
|
||||
type requestOption func(*http.Request)
|
||||
|
||||
func withAccept(typ string) requestOption {
|
||||
return func(req *http.Request) {
|
||||
req.Header.Set("Accept", typ)
|
||||
}
|
||||
}
|
||||
|
||||
func withContentType(typ string) requestOption {
|
||||
return func(req *http.Request) {
|
||||
req.Header.Set("Content-Type", typ)
|
||||
}
|
||||
}
|
||||
|
||||
// AddOptions adds the parameters in opt as URL query parameters to s. opt
|
||||
// must be a struct whose fields may contain "url" tags.
|
||||
func appendingQueryOptions(s string, opt interface{}) (string, error) {
|
||||
v := reflect.ValueOf(opt)
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
qs, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
u.RawQuery = qs.Encode()
|
||||
|
||||
return u.String(), nil
|
||||
}
|
||||
@@ -7,13 +7,12 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/asc-go/asc"
|
||||
"github.com/sagernet/sing-box/cmd/internal/build_shared"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
|
||||
"github.com/cidertool/asc-go/asc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -54,20 +53,20 @@ const (
|
||||
groupID = "5c5f3b78-b7a0-40c0-bcad-e6ef87bbefda"
|
||||
)
|
||||
|
||||
func createClient() *Client {
|
||||
func createClient(expireDuration time.Duration) *asc.Client {
|
||||
privateKey, err := os.ReadFile(os.Getenv("ASC_KEY_PATH"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tokenConfig, err := asc.NewTokenConfig(os.Getenv("ASC_KEY_ID"), os.Getenv("ASC_KEY_ISSUER_ID"), time.Minute, privateKey)
|
||||
tokenConfig, err := asc.NewTokenConfig(os.Getenv("ASC_KEY_ID"), os.Getenv("ASC_KEY_ISSUER_ID"), expireDuration, privateKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return &Client{asc.NewClient(tokenConfig.Client())}
|
||||
return asc.NewClient(tokenConfig.Client())
|
||||
}
|
||||
|
||||
func fetchMacOSVersion(ctx context.Context) error {
|
||||
client := createClient()
|
||||
client := createClient(time.Minute)
|
||||
versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
|
||||
FilterPlatform: []string{"MAC_OS"},
|
||||
})
|
||||
@@ -105,71 +104,101 @@ func publishTestflight(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
tag := tagVersion.VersionString()
|
||||
client := createClient()
|
||||
client := createClient(10 * time.Minute)
|
||||
|
||||
log.Info(tag, " list build IDs")
|
||||
buildIDsResponse, _, err := client.TestFlight.ListBuildIDsForBetaGroup(ctx, groupID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buildIDS := common.Map(buildIDsResponse.Data, func(it asc.RelationshipData) string {
|
||||
buildIDs := common.Map(buildIDsResponse.Data, func(it asc.RelationshipData) string {
|
||||
return it.ID
|
||||
})
|
||||
for _, platform := range []asc.Platform{
|
||||
asc.PlatformIOS,
|
||||
asc.PlatformMACOS,
|
||||
asc.PlatformTVOS,
|
||||
} {
|
||||
var platforms []asc.Platform
|
||||
if len(os.Args) == 3 {
|
||||
switch os.Args[2] {
|
||||
case "ios":
|
||||
platforms = []asc.Platform{asc.PlatformIOS}
|
||||
case "macos":
|
||||
platforms = []asc.Platform{asc.PlatformMACOS}
|
||||
case "tvos":
|
||||
platforms = []asc.Platform{asc.PlatformTVOS}
|
||||
default:
|
||||
return E.New("unknown platform: ", os.Args[2])
|
||||
}
|
||||
} else {
|
||||
platforms = []asc.Platform{
|
||||
asc.PlatformIOS,
|
||||
asc.PlatformMACOS,
|
||||
asc.PlatformTVOS,
|
||||
}
|
||||
}
|
||||
for _, platform := range platforms {
|
||||
log.Info(string(platform), " list builds")
|
||||
builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{
|
||||
FilterApp: []string{appID},
|
||||
FilterPreReleaseVersionPlatform: []string{string(platform)},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " list localizations")
|
||||
localizations, _, err := client.TestFlight.ListBetaBuildLocalizationsForBuild(ctx, builds.Data[0].ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localization := common.Find(localizations.Data, func(it asc.BetaBuildLocalization) bool {
|
||||
return *it.Attributes.Locale == "en-US"
|
||||
})
|
||||
if localization.ID == "" {
|
||||
log.Fatal(string(platform), " ", tag, " no en-US localization found")
|
||||
}
|
||||
if localization.Attributes == nil || localization.Attributes.WhatsNew == nil || *localization.Attributes.WhatsNew == "" {
|
||||
log.Info(string(platform), " ", tag, " update localization")
|
||||
_, _, err = client.TestFlight.UpdateBetaBuildLocalization(ctx, localization.ID, common.Ptr(
|
||||
F.ToString("sing-box ", tag),
|
||||
))
|
||||
for {
|
||||
builds, _, err := client.Builds.ListBuilds(ctx, &asc.ListBuildsQuery{
|
||||
FilterApp: []string{appID},
|
||||
FilterPreReleaseVersionPlatform: []string{string(platform)},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !common.Contains(buildIDS, builds.Data[0].ID) {
|
||||
build := builds.Data[0]
|
||||
if common.Contains(buildIDs, build.ID) || time.Since(build.Attributes.UploadedDate.Time) > 5*time.Minute {
|
||||
log.Info(string(platform), " ", tag, " waiting for process")
|
||||
time.Sleep(15 * time.Second)
|
||||
continue
|
||||
}
|
||||
if *build.Attributes.ProcessingState != "VALID" {
|
||||
log.Info(string(platform), " ", tag, " waiting for process: ", *build.Attributes.ProcessingState)
|
||||
time.Sleep(15 * time.Second)
|
||||
continue
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " list localizations")
|
||||
localizations, _, err := client.TestFlight.ListBetaBuildLocalizationsForBuild(ctx, build.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localization := common.Find(localizations.Data, func(it asc.BetaBuildLocalization) bool {
|
||||
return *it.Attributes.Locale == "en-US"
|
||||
})
|
||||
if localization.ID == "" {
|
||||
log.Fatal(string(platform), " ", tag, " no en-US localization found")
|
||||
}
|
||||
if localization.Attributes == nil || localization.Attributes.WhatsNew == nil || *localization.Attributes.WhatsNew == "" {
|
||||
log.Info(string(platform), " ", tag, " update localization")
|
||||
_, _, err = client.TestFlight.UpdateBetaBuildLocalization(ctx, localization.ID, common.Ptr(
|
||||
F.ToString("sing-box ", tagVersion.String()),
|
||||
))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " publish")
|
||||
_, err = client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{builds.Data[0].ID})
|
||||
response, err := client.TestFlight.AddBuildsToBetaGroup(ctx, groupID, []string{build.ID})
|
||||
if response != nil && response.StatusCode == http.StatusUnprocessableEntity {
|
||||
log.Info("waiting for process")
|
||||
time.Sleep(15 * time.Second)
|
||||
continue
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " list submissions")
|
||||
betaSubmissions, _, err := client.TestFlight.ListBetaAppReviewSubmissions(ctx, &asc.ListBetaAppReviewSubmissionsQuery{
|
||||
FilterBuild: []string{build.ID},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " list submissions")
|
||||
betaSubmissions, _, err := client.TestFlight.ListBetaAppReviewSubmissions(ctx, &asc.ListBetaAppReviewSubmissionsQuery{
|
||||
FilterBuild: []string{builds.Data[0].ID},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(betaSubmissions.Data) == 0 {
|
||||
log.Info(string(platform), " ", tag, " create submission")
|
||||
_, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, builds.Data[0].ID)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(betaSubmissions.Data) == 0 {
|
||||
log.Info(string(platform), " ", tag, " create submission")
|
||||
_, _, err = client.TestFlight.CreateBetaAppReviewSubmission(ctx, build.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -187,34 +216,40 @@ func cancelAppStore(ctx context.Context, platform string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := createClient()
|
||||
log.Info(platform, " list versions")
|
||||
versions, _, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
|
||||
FilterPlatform: []string{string(platform)},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
version := common.Find(versions.Data, func(it asc.AppStoreVersion) bool {
|
||||
return *it.Attributes.VersionString == tag
|
||||
})
|
||||
if version.ID == "" {
|
||||
client := createClient(time.Minute)
|
||||
for {
|
||||
log.Info(platform, " list versions")
|
||||
versions, response, err := client.Apps.ListAppStoreVersionsForApp(ctx, appID, &asc.ListAppStoreVersionsQuery{
|
||||
FilterPlatform: []string{string(platform)},
|
||||
})
|
||||
if isRetryable(response) {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
version := common.Find(versions.Data, func(it asc.AppStoreVersion) bool {
|
||||
return *it.Attributes.VersionString == tag
|
||||
})
|
||||
if version.ID == "" {
|
||||
return nil
|
||||
}
|
||||
log.Info(platform, " ", tag, " get submission")
|
||||
submission, response, err := client.Submission.GetAppStoreVersionSubmissionForAppStoreVersion(ctx, version.ID, nil)
|
||||
if response != nil && response.StatusCode == http.StatusNotFound {
|
||||
return nil
|
||||
}
|
||||
if isRetryable(response) {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(platform, " ", tag, " delete submission")
|
||||
_, err = client.Submission.DeleteSubmission(ctx, submission.Data.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " get submission")
|
||||
submission, response, err := client.Submission.GetAppStoreVersionSubmissionForAppStoreVersion(ctx, version.ID, nil)
|
||||
if response != nil && response.StatusCode == http.StatusNotFound {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(platform, " ", tag, " delete submission")
|
||||
_, err = client.Submission.DeleteSubmission(ctx, submission.Data.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareAppStore(ctx context.Context) error {
|
||||
@@ -222,7 +257,7 @@ func prepareAppStore(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := createClient()
|
||||
client := createClient(time.Minute)
|
||||
for _, platform := range []asc.Platform{
|
||||
asc.PlatformIOS,
|
||||
asc.PlatformMACOS,
|
||||
@@ -291,7 +326,7 @@ func prepareAppStore(ctx context.Context) error {
|
||||
log.Fatal(string(platform), " ", tag, " unknown state ", string(*version.Attributes.AppStoreState))
|
||||
}
|
||||
log.Info(string(platform), " ", tag, " update build")
|
||||
response, err = client.UpdateBuildForAppStoreVersion(ctx, version.ID, buildID)
|
||||
response, err = client.Apps.UpdateBuildForAppStoreVersion(ctx, version.ID, buildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -324,7 +359,7 @@ func prepareAppStore(ctx context.Context) error {
|
||||
if localization.ID == "" {
|
||||
log.Info(string(platform), " ", tag, " no en-US localization found")
|
||||
}
|
||||
if localization.Attributes.WhatsNew == nil && *localization.Attributes.WhatsNew == "" {
|
||||
if localization.Attributes == nil || localization.Attributes.WhatsNew == nil || *localization.Attributes.WhatsNew == "" {
|
||||
log.Info(string(platform), " ", tag, " update localization")
|
||||
_, _, err = client.Apps.UpdateAppStoreVersionLocalization(ctx, localization.ID, &asc.AppStoreVersionLocalizationUpdateRequestAttributes{
|
||||
PromotionalText: common.Ptr("Yet another distribution for sing-box, the universal proxy platform."),
|
||||
@@ -343,16 +378,14 @@ func prepareAppStore(ctx context.Context) error {
|
||||
case http.StatusInternalServerError:
|
||||
continue
|
||||
default:
|
||||
response.Write(os.Stderr)
|
||||
log.Info(string(platform), " ", tag, " unexpected response: ", response.Status)
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch response.StatusCode {
|
||||
case http.StatusCreated:
|
||||
break fixSubmit
|
||||
default:
|
||||
response.Write(os.Stderr)
|
||||
log.Info(string(platform), " ", tag, " unexpected response: ", response.Status)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,7 +397,7 @@ func publishAppStore(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := createClient()
|
||||
client := createClient(time.Minute)
|
||||
for _, platform := range []asc.Platform{
|
||||
asc.PlatformIOS,
|
||||
asc.PlatformMACOS,
|
||||
@@ -398,3 +431,15 @@ func publishAppStore(ctx context.Context) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isRetryable(response *asc.Response) bool {
|
||||
if response == nil {
|
||||
return false
|
||||
}
|
||||
switch response.StatusCode {
|
||||
case http.StatusInternalServerError, http.StatusUnprocessableEntity:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func initializeHTTP3Client(instance *box.Box) error {
|
||||
return err
|
||||
}
|
||||
http3Client = &http.Client{
|
||||
Transport: &http3.RoundTripper{
|
||||
Transport: &http3.Transport{
|
||||
Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||
destination := M.ParseSocksaddr(addr)
|
||||
udpConn, dErr := dialer.DialContext(ctx, N.NetworkUDP, destination)
|
||||
|
||||
@@ -63,6 +63,7 @@ type echConnWrapper struct {
|
||||
|
||||
func (c *echConnWrapper) ConnectionState() tls.ConnectionState {
|
||||
state := c.Conn.ConnectionState()
|
||||
//nolint:staticcheck
|
||||
return tls.ConnectionState{
|
||||
Version: state.Version,
|
||||
HandshakeComplete: state.HandshakeComplete,
|
||||
|
||||
@@ -147,6 +147,9 @@ func echKeygen(version uint16, serverName string, conf []myECHKeyConfig, suite [
|
||||
pair.rawConf = b
|
||||
|
||||
secBuf, err := sec.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "serialize ECH private key")
|
||||
}
|
||||
sk := []byte{}
|
||||
sk = be.AppendUint16(sk, uint16(len(secBuf)))
|
||||
sk = append(sk, secBuf...)
|
||||
|
||||
@@ -28,7 +28,7 @@ func (c *echClientConfig) DialEarly(ctx context.Context, conn net.PacketConn, ad
|
||||
}
|
||||
|
||||
func (c *echClientConfig) CreateTransport(conn net.PacketConn, quicConnPtr *quic.EarlyConnection, serverAddr M.Socksaddr, quicConfig *quic.Config) http.RoundTripper {
|
||||
return &http3.RoundTripper{
|
||||
return &http3.Transport{
|
||||
TLSClientConfig: c.config,
|
||||
QUICConfig: quicConfig,
|
||||
Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||
|
||||
@@ -184,7 +184,7 @@ func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn
|
||||
return nil, E.New("reality verification failed")
|
||||
}
|
||||
|
||||
return &utlsConnWrapper{uConn}, nil
|
||||
return &realityClientConnWrapper{uConn}, nil
|
||||
}
|
||||
|
||||
func realityClientFallback(uConn net.Conn, serverName string, fingerprint utls.ClientHelloID) {
|
||||
@@ -249,3 +249,36 @@ func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChain
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type realityClientConnWrapper struct {
|
||||
*utls.UConn
|
||||
}
|
||||
|
||||
func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionState {
|
||||
state := c.Conn.ConnectionState()
|
||||
//nolint:staticcheck
|
||||
return tls.ConnectionState{
|
||||
Version: state.Version,
|
||||
HandshakeComplete: state.HandshakeComplete,
|
||||
DidResume: state.DidResume,
|
||||
CipherSuite: state.CipherSuite,
|
||||
NegotiatedProtocol: state.NegotiatedProtocol,
|
||||
NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual,
|
||||
ServerName: state.ServerName,
|
||||
PeerCertificates: state.PeerCertificates,
|
||||
VerifiedChains: state.VerifiedChains,
|
||||
SignedCertificateTimestamps: state.SignedCertificateTimestamps,
|
||||
OCSPResponse: state.OCSPResponse,
|
||||
TLSUnique: state.TLSUnique,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *realityClientConnWrapper) Upstream() any {
|
||||
return c.UConn
|
||||
}
|
||||
|
||||
// Due to low implementation quality, the reality server intercepted half close and caused memory leaks.
|
||||
// We fixed it by calling Close() directly.
|
||||
func (c *realityClientConnWrapper) CloseWrite() error {
|
||||
return c.Close()
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ type realityConnWrapper struct {
|
||||
|
||||
func (c *realityConnWrapper) ConnectionState() ConnectionState {
|
||||
state := c.Conn.ConnectionState()
|
||||
//nolint:staticcheck
|
||||
return tls.ConnectionState{
|
||||
Version: state.Version,
|
||||
HandshakeComplete: state.HandshakeComplete,
|
||||
@@ -194,3 +195,9 @@ func (c *realityConnWrapper) ConnectionState() ConnectionState {
|
||||
func (c *realityConnWrapper) Upstream() any {
|
||||
return c.Conn
|
||||
}
|
||||
|
||||
// Due to low implementation quality, the reality server intercepted half close and caused memory leaks.
|
||||
// We fixed it by calling Close() directly.
|
||||
func (c *realityConnWrapper) CloseWrite() error {
|
||||
return c.Close()
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ type utlsConnWrapper struct {
|
||||
|
||||
func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
|
||||
state := c.Conn.ConnectionState()
|
||||
//nolint:staticcheck
|
||||
return tls.ConnectionState{
|
||||
Version: state.Version,
|
||||
HandshakeComplete: state.HandshakeComplete,
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
//go:build android && debug
|
||||
|
||||
package constant
|
||||
|
||||
// TODO: remove after fixed
|
||||
// https://github.com/golang/go/issues/68760
|
||||
|
||||
const FixAndroidStack = true
|
||||
@@ -1,5 +0,0 @@
|
||||
//go:build !(android && debug)
|
||||
|
||||
package constant
|
||||
|
||||
const FixAndroidStack = false
|
||||
@@ -2,7 +2,7 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
### 1.10.3
|
||||
### 1.10.7
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
@@ -114,7 +113,7 @@ func (c *CommandClient) Connect() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if C.FixAndroidStack {
|
||||
if sFixAndroidStack {
|
||||
go func() {
|
||||
c.handler.Connected()
|
||||
c.handler.InitializeClashMode(newIterator(modeList), currentMode)
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -98,7 +97,7 @@ func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Eleme
|
||||
}
|
||||
|
||||
func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32) {
|
||||
if C.FixAndroidStack {
|
||||
if sFixAndroidStack {
|
||||
go m.updateDefaultInterface(interfaceName, interfaceIndex32)
|
||||
} else {
|
||||
m.updateDefaultInterface(interfaceName, interfaceIndex32)
|
||||
|
||||
@@ -73,7 +73,7 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
|
||||
}
|
||||
|
||||
func (s *BoxService) Start() error {
|
||||
if C.FixAndroidStack {
|
||||
if sFixAndroidStack {
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
|
||||
@@ -15,43 +15,55 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
sBasePath string
|
||||
sWorkingPath string
|
||||
sTempPath string
|
||||
sUserID int
|
||||
sGroupID int
|
||||
sTVOS bool
|
||||
sBasePath string
|
||||
sWorkingPath string
|
||||
sTempPath string
|
||||
sUserID int
|
||||
sGroupID int
|
||||
sTVOS bool
|
||||
sFixAndroidStack bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
debug.SetPanicOnFault(true)
|
||||
}
|
||||
|
||||
func Setup(basePath string, workingPath string, tempPath string, isTVOS bool) {
|
||||
sBasePath = basePath
|
||||
sWorkingPath = workingPath
|
||||
sTempPath = tempPath
|
||||
sUserID = os.Getuid()
|
||||
sGroupID = os.Getgid()
|
||||
sTVOS = isTVOS
|
||||
os.MkdirAll(sWorkingPath, 0o777)
|
||||
os.MkdirAll(sTempPath, 0o777)
|
||||
type SetupOptions struct {
|
||||
BasePath string
|
||||
WorkingPath string
|
||||
TempPath string
|
||||
Username string
|
||||
IsTVOS bool
|
||||
FixAndroidStack bool
|
||||
}
|
||||
|
||||
func SetupWithUsername(basePath string, workingPath string, tempPath string, username string) error {
|
||||
sBasePath = basePath
|
||||
sWorkingPath = workingPath
|
||||
sTempPath = tempPath
|
||||
sUser, err := user.Lookup(username)
|
||||
if err != nil {
|
||||
return err
|
||||
func Setup(options *SetupOptions) error {
|
||||
sBasePath = options.BasePath
|
||||
sWorkingPath = options.WorkingPath
|
||||
sTempPath = options.TempPath
|
||||
if options.Username != "" {
|
||||
sUser, err := user.Lookup(options.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sUserID, _ = strconv.Atoi(sUser.Uid)
|
||||
sGroupID, _ = strconv.Atoi(sUser.Gid)
|
||||
} else {
|
||||
sUserID = os.Getuid()
|
||||
sGroupID = os.Getgid()
|
||||
}
|
||||
sUserID, _ = strconv.Atoi(sUser.Uid)
|
||||
sGroupID, _ = strconv.Atoi(sUser.Gid)
|
||||
sTVOS = options.IsTVOS
|
||||
|
||||
// TODO: remove after fixed
|
||||
// https://github.com/golang/go/issues/68760
|
||||
sFixAndroidStack = options.FixAndroidStack
|
||||
|
||||
os.MkdirAll(sWorkingPath, 0o777)
|
||||
os.MkdirAll(sTempPath, 0o777)
|
||||
os.Chown(sWorkingPath, sUserID, sGroupID)
|
||||
os.Chown(sTempPath, sUserID, sGroupID)
|
||||
if options.Username != "" {
|
||||
os.Chown(sWorkingPath, sUserID, sGroupID)
|
||||
os.Chown(sTempPath, sUserID, sGroupID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
23
go.mod
23
go.mod
@@ -5,7 +5,6 @@ go 1.20
|
||||
require (
|
||||
berty.tech/go-libtor v1.0.385
|
||||
github.com/caddyserver/certmagic v0.20.0
|
||||
github.com/cidertool/asc-go v0.5.1
|
||||
github.com/cloudflare/circl v1.3.7
|
||||
github.com/cretz/bine v0.2.0
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
@@ -20,6 +19,7 @@ require (
|
||||
github.com/miekg/dns v1.1.62
|
||||
github.com/ooni/go-libtor v1.1.8
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1
|
||||
github.com/sagernet/cors v1.2.1
|
||||
@@ -31,25 +31,25 @@ require (
|
||||
github.com/sagernet/sing v0.5.1
|
||||
github.com/sagernet/sing-dns v0.3.0
|
||||
github.com/sagernet/sing-mux v0.2.1
|
||||
github.com/sagernet/sing-quic v0.3.1
|
||||
github.com/sagernet/sing-quic v0.3.2
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.5
|
||||
github.com/sagernet/sing-tun v0.4.5
|
||||
github.com/sagernet/sing-vmess v0.1.12
|
||||
github.com/sagernet/sing-tun v0.4.6
|
||||
github.com/sagernet/sing-vmess v0.1.13
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/utls v1.6.7
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.5
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.uber.org/zap v1.27.0
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/crypto v0.31.0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/mod v0.20.0
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/sys v0.27.0
|
||||
golang.org/x/sys v0.28.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
google.golang.org/grpc v1.63.2
|
||||
google.golang.org/protobuf v1.33.0
|
||||
@@ -61,7 +61,7 @@ require (
|
||||
require (
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
@@ -71,7 +71,7 @@ require (
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
@@ -94,10 +94,11 @@ require (
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
49
go.sum
49
go.sum
@@ -6,10 +6,8 @@ github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sx
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
|
||||
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cidertool/asc-go v0.5.1 h1:KYki2Y8IXJMOkOXy9y1sdr8tz6IdW2ti770K4bk7WY0=
|
||||
github.com/cidertool/asc-go v0.5.1/go.mod h1:LyrZWU7DeCh8cWrFwXcpl93ixRUUL2aEZV7/0h07FxA=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
@@ -41,10 +39,11 @@ github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
@@ -102,6 +101,8 @@ github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1 h1:qi+ijeREa0yfAaO+NOcZ81gv4uzOfALUIdhkiIFvmG4=
|
||||
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1/go.mod h1:JULDuzTMn2gyZFcjpTVZP4/UuwAdbHJ0bum2RdjXojU=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQEMdlk9oFSKYWRqVuu9qzNiOayIonKmv1gCXY=
|
||||
@@ -129,24 +130,24 @@ github.com/sagernet/sing-dns v0.3.0 h1:uHCIlbCwBxALJwXcEK1d75d7t3vzCSVEQsPfZR1cx
|
||||
github.com/sagernet/sing-dns v0.3.0/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M=
|
||||
github.com/sagernet/sing-mux v0.2.1 h1:N/3MHymfnFZRd29tE3TaXwPUVVgKvxhtOkiCMLp9HVo=
|
||||
github.com/sagernet/sing-mux v0.2.1/go.mod h1:dm3BWL6NvES9pbib7llpylrq7Gq+LjlzG+0RacdxcyE=
|
||||
github.com/sagernet/sing-quic v0.3.1 h1:kLg2n4JPnuzUPg7myJGbfGVJGeXiccXfV+PhXIlkSEc=
|
||||
github.com/sagernet/sing-quic v0.3.1/go.mod h1:g8b5Fj88KRM0H9lpKAxJj0EpkL/Yk06qXJAG7FuZd2I=
|
||||
github.com/sagernet/sing-quic v0.3.2 h1:bFawJFX4KPx0teFfH1toQm5MfDVz/RwsMbLueeiD2l8=
|
||||
github.com/sagernet/sing-quic v0.3.2/go.mod h1:g8b5Fj88KRM0H9lpKAxJj0EpkL/Yk06qXJAG7FuZd2I=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.5 h1:uXxmq/HXh8DIiBGLzpMjCbWnzIAFs+lIxiTOjdgG5qo=
|
||||
github.com/sagernet/sing-shadowtls v0.1.5/go.mod h1:tvrDPTGLrSM46Wnf7mSr+L8NHvgvF8M4YnJF790rZX4=
|
||||
github.com/sagernet/sing-tun v0.4.5 h1:GgZR9pNRem0TigZw1AgdrCE/v2oRexjmyAytvp89kW0=
|
||||
github.com/sagernet/sing-tun v0.4.5/go.mod h1:1WQVMelJQjrtlzhzHwwPTSa7n41b3zSWP2DeJqWxruk=
|
||||
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
||||
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
|
||||
github.com/sagernet/sing-tun v0.4.6 h1:TBBr3akUqC0o6Vrwet9D56IDHylfM67hYJkVAfdlvCQ=
|
||||
github.com/sagernet/sing-tun v0.4.6/go.mod h1:1WQVMelJQjrtlzhzHwwPTSa7n41b3zSWP2DeJqWxruk=
|
||||
github.com/sagernet/sing-vmess v0.1.13 h1:/GSfD1Rt6/mVfE80WFHNBykNT7KJNWWmvcMP9DoElEs=
|
||||
github.com/sagernet/sing-vmess v0.1.13/go.mod h1:D+g+lhv4iOk1Pn08pd3MtUd72khL5+wgEE3xVH8J+ow=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
|
||||
github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8=
|
||||
github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc=
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.5 h1:aBEsxJUMEONwOZqKPIkuAcv4zJV5p6XlzEN04CF0FXc=
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.5/go.mod h1:jGXij2Gn2wbrWuYNUmmNhf1dwcZtvyAvQoe8Xd8MbUo=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
@@ -178,8 +179,8 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
@@ -188,8 +189,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -198,14 +199,14 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -213,6 +214,8 @@ golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
|
||||
@@ -61,8 +61,8 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
}
|
||||
if len(options.Down) > 0 {
|
||||
receiveBps, err = humanize.ParseBytes(options.Down)
|
||||
if receiveBps == 0 {
|
||||
return nil, E.New("invalid down speed format: ", options.Down)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "invalid down speed format: ", options.Down)
|
||||
}
|
||||
} else {
|
||||
receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
|
||||
|
||||
@@ -63,8 +63,8 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
}
|
||||
if len(options.Down) > 0 {
|
||||
receiveBps, err = humanize.ParseBytes(options.Down)
|
||||
if receiveBps == 0 {
|
||||
return nil, E.New("invalid down speed format: ", options.Down)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "invalid down speed format: ", options.Down)
|
||||
}
|
||||
} else {
|
||||
receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
|
||||
|
||||
@@ -163,7 +163,7 @@ func (w *WireGuard) start() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wgDevice := device.NewDevice(w.tunDevice, bind, &device.Logger{
|
||||
wgDevice := device.NewDevice(w.ctx, w.tunDevice, bind, &device.Logger{
|
||||
Verbosef: func(format string, args ...interface{}) {
|
||||
w.logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
},
|
||||
|
||||
@@ -345,9 +345,6 @@ func NewRouter(
|
||||
return nil, err
|
||||
}
|
||||
router.networkMonitor = networkMonitor
|
||||
networkMonitor.RegisterCallback(func() {
|
||||
_ = router.interfaceFinder.Update()
|
||||
})
|
||||
interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{
|
||||
InterfaceFinder: router.interfaceFinder,
|
||||
OverrideAndroidVPN: options.OverrideAndroidVPN,
|
||||
|
||||
@@ -71,15 +71,15 @@ func isGeositeDNSRule(rule option.DefaultDNSRule) bool {
|
||||
}
|
||||
|
||||
func isProcessRule(rule option.DefaultRule) bool {
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
|
||||
}
|
||||
|
||||
func isProcessDNSRule(rule option.DefaultDNSRule) bool {
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
|
||||
}
|
||||
|
||||
func isProcessHeadlessRule(rule option.DefaultHeadlessRule) bool {
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.PackageName) > 0
|
||||
return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0
|
||||
}
|
||||
|
||||
func notPrivateNode(code string) bool {
|
||||
|
||||
Reference in New Issue
Block a user