Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions .circleci/config.yml

This file was deleted.

8 changes: 8 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: "CodeQL config"

queries:
- uses: security-and-quality

query-filters:
- exclude:
id: go/unused-result
23 changes: 23 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 2
updates:
# Go modules
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
day: monday
labels: ["dependencies", "go"]
open-pull-requests-limit: 10
groups:
go-minor-patch:
update-types: [minor, patch]

# GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
labels: ["dependencies", "ci"]
groups:
actions:
patterns: ["*"]
32 changes: 32 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Lint

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
lint:
name: Lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable

- name: Run go vet
run: go vet ./...

- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: latest
args: --timeout 5m
65 changes: 65 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Security

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

permissions:
contents: read
security-events: write

jobs:
govulncheck:
name: Vulnerability Check
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable

- name: Run govulncheck
uses: golang/govulncheck-action@v1

gosec:
name: gosec
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Run gosec
# gosec publishes no floating major tag; Dependabot keeps this current.
uses: securego/gosec@v2.29.0
with:
args: -no-fail -fmt sarif -out gosec-results.sarif ./...

- name: Upload gosec results
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: gosec-results.sarif

codeql:
name: CodeQL
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: go
config-file: .github/codeql/codeql-config.yml

- name: Autobuild
uses: github/codeql-action/autobuild@v4

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
54 changes: 54 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Tests

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: Test (Go ${{ matrix.go }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go:
- "1.25"
- "1.26"
- "stable"

steps:
- uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}

- name: Verify dependencies
run: |
go mod verify
go mod download

- name: Check go mod tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum

- name: Build
run: go build ./...

- name: Run tests
run: go test -v -race -shuffle=on -coverprofile=coverage.out ./...

- name: Upload coverage
if: matrix.go == 'stable'
uses: codecov/codecov-action@v5
with:
files: ./coverage.out
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
8 changes: 8 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: "2"

linters:
exclusions:
rules:
# Legacy helpers kept for reference; tracked for eventual removal.
- linters: [unused]
text: "func (isIPv6|backslashEscape|encodeSmethodArgs) is unused"
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
## Yet another SIP003 plugin for shadowsocks, based on [v2ray](https://github.com/v2fly/v2ray-core)

[![CircleCI](https://circleci.com/gh/shadowsocks/v2ray-plugin.svg?style=shield)](https://circleci.com/gh/shadowsocks/v2ray-plugin)
[![Releases](https://img.shields.io/github/downloads/shadowsocks/v2ray-plugin/total.svg)](https://github.com/shadowsocks/v2ray-plugin/releases)
[![Language: Go](https://img.shields.io/badge/go-1.25.5+-blue.svg)](https://github.com/shadowsocks/v2ray-plugin/search?l=go)
[![Go Report Card](https://goreportcard.com/badge/github.com/shadowsocks/v2ray-plugin)](https://goreportcard.com/report/github.com/shadowsocks/v2ray-plugin)
[![License](https://img.shields.io/github/license/shadowsocks/v2ray-plugin.svg)](LICENSE)

## Build
Expand All @@ -12,7 +10,6 @@ Requires Go 1.25.5 or later. This plugin uses V2Ray core v5.53.0.

* `go build`
* `go test ./...` runs integration tests using local TCP and UDP sockets.
* Alternatively, you can grab the latest nightly from Circle CI by logging into Circle CI or adding `#artifacts` at the end of URL like such: https://circleci.com/gh/shadowsocks/v2ray-plugin/20#artifacts

## Usage

Expand Down
9 changes: 9 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
coverage:
status:
project:
default:
target: auto
threshold: 1%
patch:
default:
target: 80%
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/shadowsocks/v2ray-plugin
go 1.25.5

require (
github.com/golang/protobuf v1.5.4
github.com/v2fly/v2ray-core/v5 v5.53.0
google.golang.org/protobuf v1.36.11
)
Expand All @@ -12,6 +11,7 @@ require (
github.com/adrg/xdg v0.5.3 // indirect
github.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/miekg/dns v1.1.72 // indirect
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"strings"
"syscall"

"github.com/golang/protobuf/proto"
"google.golang.org/protobuf/runtime/protoiface"
"google.golang.org/protobuf/types/known/anypb"

_ "github.com/v2fly/v2ray-core/v5/app/proxyman/inbound"
Expand Down Expand Up @@ -152,7 +152,9 @@ func generateConfig() (*core.Config, error) {
},
})

var transportSettings proto.Message
// serial.ToTypedMessage takes the legacy v1 message interface; use it
// directly instead of the deprecated github.com/golang/protobuf import.
var transportSettings protoiface.MessageV1
var connectionReuse bool
switch *mode {
case "websocket":
Expand Down Expand Up @@ -446,7 +448,7 @@ func main() {

{
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
signal.Notify(osSignals, os.Interrupt, syscall.SIGTERM)
<-osSignals
}
}
31 changes: 18 additions & 13 deletions transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ func TestMain(m *testing.M) {
cmd := exec.Command("go", "build", "-o", testBinary, ".")
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
os.RemoveAll(dir)
_ = os.RemoveAll(dir)
os.Exit(1)
}
code := m.Run()
os.RemoveAll(dir)
_ = os.RemoveAll(dir)
os.Exit(code)
}

Expand Down Expand Up @@ -71,14 +71,14 @@ func unusedPort(t *testing.T, network string) string {
if err != nil {
t.Fatal(err)
}
defer c.Close()
defer func() { _ = c.Close() }()
return fmt.Sprint(c.LocalAddr().(*net.UDPAddr).Port)
}
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer l.Close()
defer func() { _ = l.Close() }()
return fmt.Sprint(l.Addr().(*net.TCPAddr).Port)
}

Expand All @@ -102,17 +102,19 @@ func startPlugin(t *testing.T, args []string, env []string) {
done := make(chan error, 1)
go func() { done <- cmd.Wait() }()
t.Cleanup(func() {
cmd.Process.Signal(os.Interrupt)
_ = cmd.Process.Signal(os.Interrupt)
select {
case err := <-done:
if err != nil {
t.Errorf("plugin exited unexpectedly: %v", err)
}
case <-time.After(3 * time.Second):
cmd.Process.Kill()
<-done
_ = cmd.Process.Kill()
if err := <-done; err != nil {
t.Logf("plugin did not exit after kill: %v", err)
}
}
logFile.Close()
_ = logFile.Close()
if t.Failed() {
data, _ := os.ReadFile(logFile.Name())
t.Logf("plugin output:\n%s", data)
Expand All @@ -126,8 +128,8 @@ func echoThroughPlugin(t *testing.T, addr string) error {
if err != nil {
return err
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(2 * time.Second))
defer func() { _ = conn.Close() }()
_ = conn.SetDeadline(time.Now().Add(2 * time.Second))
payload := "Shadowsocks transport round trip\x00\xff"
if _, err := io.WriteString(conn, payload); err != nil {
return err
Expand Down Expand Up @@ -181,14 +183,17 @@ func testTransport(t *testing.T, transport, serverPassword, clientPassword, clie
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { echo.Close() })
t.Cleanup(func() { _ = echo.Close() })
go func() {
for {
conn, err := echo.Accept()
if err != nil {
return
}
go func() { defer conn.Close(); io.Copy(conn, conn) }()
go func() {
defer func() { _ = conn.Close() }()
_, _ = io.Copy(conn, conn)
}()
}
}()
network := "udp"
Expand Down Expand Up @@ -240,7 +245,7 @@ func waitForListener(t *testing.T, addr string) {
for time.Now().Before(deadline) {
conn, err := net.DialTimeout("tcp", addr, 100*time.Millisecond)
if err == nil {
conn.Close()
_ = conn.Close()
return
}
time.Sleep(20 * time.Millisecond)
Expand Down
Loading