mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-11-13 00:14:22 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 583905b7ed | |||
| 6e3f045b9b | |||
| ec41202b3c | |||
| 1ee7dea8b4 | |||
| 2d69350bab | |||
| c984e5b62a | |||
| 5b79b11101 | |||
| 2c22e600f7 | |||
| aef284c474 | |||
| 0443cd9ceb | |||
| 3337422775 | |||
| 3e046fc80e | |||
| 0273bc6921 |
@@ -100,11 +100,11 @@ jobs:
|
||||
|
||||
- name: Build GOST binary (AMD64)
|
||||
working-directory: ./go-gost
|
||||
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o gost-amd64
|
||||
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.version=${{ needs.check-version.outputs.version }}" -o gost-amd64
|
||||
|
||||
- name: Build GOST binary (ARM64)
|
||||
working-directory: ./go-gost
|
||||
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o gost-arm64
|
||||
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w -X main.version=${{ needs.check-version.outputs.version }}" -o gost-arm64
|
||||
|
||||
- name: Compress with UPX
|
||||
working-directory: ./go-gost
|
||||
|
||||
@@ -16,24 +16,13 @@
|
||||
---
|
||||
### Docker Compose部署
|
||||
#### 快速部署
|
||||
面板端(稳定版):
|
||||
面板端:
|
||||
```bash
|
||||
curl -L https://raw.githubusercontent.com/Sagit-chu/flux-panel/main/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
|
||||
```
|
||||
节点端(稳定版):
|
||||
节点端:
|
||||
```bash
|
||||
curl -L https://raw.githubusercontent.com/Sagit-chu/flux-panel/main/install.sh -o install.sh && chmod +x install.sh && ./install.sh
|
||||
|
||||
```
|
||||
|
||||
面板端(开发版):
|
||||
```bash
|
||||
curl -L https://raw.githubusercontent.com/Sagit-chu/flux-panel/beta/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
|
||||
```
|
||||
节点端(开发版):
|
||||
```bash
|
||||
curl -L https://raw.githubusercontent.com/Sagit-chu/flux-panel/beta/install.sh -o install.sh && chmod +x install.sh && ./install.sh
|
||||
|
||||
```
|
||||
|
||||
#### 默认管理员账号
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ func main() {
|
||||
log := xlogger.NewLogger()
|
||||
logger.SetDefault(log)
|
||||
|
||||
wsReporter := socket.StartWebSocketReporterWithConfig(config.Addr, config.Secret, config.Http, config.Tls, config.Socks, "2.0.2")
|
||||
wsReporter := socket.StartWebSocketReporterWithConfig(config.Addr, config.Secret, config.Http, config.Tls, config.Socks, version)
|
||||
defer wsReporter.Stop()
|
||||
service.SetHTTPReportURL(config.Addr, config.Secret)
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
package main
|
||||
|
||||
var (
|
||||
version = "3.1.0"
|
||||
version = "dev"
|
||||
)
|
||||
|
||||
@@ -195,7 +195,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||
// Select a target node, excluding previously tried nodes
|
||||
selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes)
|
||||
target := &chain.Node{}
|
||||
var target *chain.Node
|
||||
if h.hop != nil {
|
||||
target = h.hop.Select(selectCtx,
|
||||
hop.ProtocolSelectOption(proto),
|
||||
|
||||
@@ -225,9 +225,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes)
|
||||
var target *chain.Node
|
||||
if host != "" {
|
||||
target = &chain.Node{
|
||||
Addr: host,
|
||||
}
|
||||
target = chain.NewNode("", host)
|
||||
}
|
||||
if h.hop != nil {
|
||||
target = h.hop.Select(selectCtx,
|
||||
|
||||
+19
-4
@@ -201,11 +201,26 @@ func (p *chainHop) Select(ctx context.Context, opts ...hop.SelectOption) *chain.
|
||||
return nodes[0]
|
||||
}
|
||||
|
||||
// Always go through selector for proper FailFilter evaluation,
|
||||
// even when there's only one node. This ensures failed nodes
|
||||
// can be filtered out properly.
|
||||
// For single-node case: bypass selector/FailFilter to ensure availability.
|
||||
// The marker system still works for metrics, but we don't block requests
|
||||
// based on recent failures - the connection will be attempted regardless.
|
||||
// This matches upstream go-gost/x behavior.
|
||||
if len(nodes) == 1 {
|
||||
return nodes[0]
|
||||
}
|
||||
|
||||
// Multi-node case: use selector with FailFilter for proper failover.
|
||||
// FailFilter will exclude recently-failed nodes, allowing traffic to
|
||||
// be routed to healthy alternatives.
|
||||
if s := p.options.selector; s != nil {
|
||||
return s.Select(ctx, nodes...)
|
||||
if node := s.Select(ctx, nodes...); node != nil {
|
||||
return node
|
||||
}
|
||||
// All nodes filtered out by FailFilter - all are marked as failed.
|
||||
// Return nil to signal "no healthy nodes available" to the caller.
|
||||
// The handler's retry loop will handle this appropriately.
|
||||
log.Debugf("all %d nodes filtered out by FailFilter, no healthy nodes available", len(nodes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fallback: return first node if no selector configured
|
||||
|
||||
@@ -263,9 +263,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
// Select a node, excluding previously tried nodes
|
||||
selectCtx := ctxvalue.ContextWithExcludeNodes(ctx, triedNodes)
|
||||
|
||||
node = &chain.Node{
|
||||
Addr: host,
|
||||
}
|
||||
node = chain.NewNode("", host)
|
||||
if ho.Hop != nil {
|
||||
node = ho.Hop.Select(selectCtx,
|
||||
hop.ClientIPSelectOption(net.ParseIP(ro.ClientIP)),
|
||||
@@ -903,9 +901,7 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (
|
||||
|
||||
node = nil
|
||||
if host != "" {
|
||||
node = &chain.Node{
|
||||
Addr: host,
|
||||
}
|
||||
node = chain.NewNode("", host)
|
||||
}
|
||||
if ho.Hop != nil {
|
||||
node = ho.Hop.Select(selectCtx,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# GO-GOST REGISTRY KNOWLEDGE BASE
|
||||
|
||||
**Generated:** Wed Feb 04 2026
|
||||
|
||||
## OVERVIEW
|
||||
Central registration point for all pluggable GOST components (handlers, listeners, dialers, etc.).
|
||||
Allows the configuration system to resolve string types (e.g., "socks5") to actual Go implementations.
|
||||
|
||||
## STRUCTURE
|
||||
One file per component type, exporting a standard Registry interface.
|
||||
```
|
||||
go-gost/x/registry/
|
||||
├── handler.go # RegisterHandler(name, newFunc)
|
||||
├── listener.go # RegisterListener(name, newFunc)
|
||||
├── dialer.go # RegisterDialer(name, newFunc)
|
||||
└── ... # Same pattern for auth, bypass, admission
|
||||
```
|
||||
|
||||
## WHERE TO LOOK
|
||||
| Task | Location | Notes |
|
||||
|------|----------|-------|
|
||||
| Register a new component | `go-gost/x/registry/{type}.go` | Use `Register{Type}(name, creator)` |
|
||||
| Component lookup | `go-gost/x/registry/{type}.go` | `Get{Type}(name)` returns the creator function |
|
||||
| Default registrations | `go-gost/x/` (init functions) | Most components register themselves in their package `init()` |
|
||||
|
||||
## CONVENTIONS
|
||||
- Thread-safe maps used for storage.
|
||||
- Names are case-sensitive (usually lowercase).
|
||||
- Components must be registered *before* the configuration parser runs (usually done via `import _ "..."` in `main.go`).
|
||||
@@ -24,11 +24,12 @@ func FailFilter[T any](maxFails int, timeout time.Duration) selector.Filter[T] {
|
||||
}
|
||||
|
||||
// Filter filters dead objects.
|
||||
// Note: We intentionally do NOT skip filtering when len(vs) <= 1.
|
||||
// This ensures that even a single dead node gets filtered out,
|
||||
// allowing the caller to know that no healthy nodes are available
|
||||
// and potentially trigger failover behavior.
|
||||
// For single-node case, skip filtering to ensure availability (matches upstream).
|
||||
// For multi-node case, filter out failed nodes to enable failover.
|
||||
func (f *failFilter[T]) Filter(ctx context.Context, vs ...T) []T {
|
||||
if len(vs) <= 1 {
|
||||
return vs
|
||||
}
|
||||
var l []T
|
||||
for _, v := range vs {
|
||||
maxFails := f.maxFails
|
||||
|
||||
Reference in New Issue
Block a user