mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
Compare commits
12 Commits
eb07c7a79e
...
8e2baf40f1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8e2baf40f1 | ||
![]() |
c24c40dfee | ||
![]() |
32e52ce1ed | ||
![]() |
ed46438359 | ||
![]() |
0b5490d5a3 | ||
![]() |
2d73ef511d | ||
![]() |
63e6c85f6f | ||
![]() |
8946a6d2d0 | ||
![]() |
d3132645fb | ||
![]() |
373f158fe0 | ||
![]() |
ce36835fab | ||
![]() |
619fa671d7 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -159,7 +159,7 @@ jobs:
|
|||||||
uses: goreleaser/goreleaser-action@v6
|
uses: goreleaser/goreleaser-action@v6
|
||||||
with:
|
with:
|
||||||
distribution: goreleaser-pro
|
distribution: goreleaser-pro
|
||||||
version: 2.5.1
|
version: nightly
|
||||||
install-only: true
|
install-only: true
|
||||||
- name: Extract signing key
|
- name: Extract signing key
|
||||||
run: |-
|
run: |-
|
||||||
|
@ -95,10 +95,12 @@ archives:
|
|||||||
builds:
|
builds:
|
||||||
- main
|
- main
|
||||||
- android
|
- android
|
||||||
format: tar.gz
|
formats:
|
||||||
|
- tar.gz
|
||||||
format_overrides:
|
format_overrides:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
format: zip
|
formats:
|
||||||
|
- zip
|
||||||
wrap_in_directory: true
|
wrap_in_directory: true
|
||||||
files:
|
files:
|
||||||
- LICENSE
|
- LICENSE
|
||||||
|
13
box.go
13
box.go
@ -165,7 +165,15 @@ func New(options Options) (*Box, error) {
|
|||||||
} else {
|
} else {
|
||||||
tag = F.ToString(i)
|
tag = F.ToString(i)
|
||||||
}
|
}
|
||||||
err = endpointManager.Create(ctx,
|
endpointCtx := ctx
|
||||||
|
if tag != "" {
|
||||||
|
// TODO: remove this
|
||||||
|
endpointCtx = adapter.WithContext(endpointCtx, &adapter.InboundContext{
|
||||||
|
Outbound: tag,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
err = endpointManager.Create(
|
||||||
|
endpointCtx,
|
||||||
router,
|
router,
|
||||||
logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
|
logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
|
||||||
tag,
|
tag,
|
||||||
@ -183,7 +191,8 @@ func New(options Options) (*Box, error) {
|
|||||||
} else {
|
} else {
|
||||||
tag = F.ToString(i)
|
tag = F.ToString(i)
|
||||||
}
|
}
|
||||||
err = inboundManager.Create(ctx,
|
err = inboundManager.Create(
|
||||||
|
ctx,
|
||||||
router,
|
router,
|
||||||
logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
|
logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
|
||||||
tag,
|
tag,
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 0576fd75a67e56048c29d00ef539b4f8f05aec2a
|
Subproject commit aefe3c029096ddac5189a20a8203a68858152f0a
|
@ -1 +1 @@
|
|||||||
Subproject commit a828bb3a93b57d0c1b13d74246f0675c5244466d
|
Subproject commit ae5818ee5a24af965dc91f80bffa16e1e6c109c1
|
@ -18,6 +18,7 @@ func (d *DefaultDialer) dialParallelInterface(ctx context.Context, dialer net.Di
|
|||||||
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
||||||
return nil, false, E.New("no available network interface")
|
return nil, false, E.New("no available network interface")
|
||||||
}
|
}
|
||||||
|
defaultInterface := d.networkManager.InterfaceMonitor().DefaultInterface()
|
||||||
if fallbackDelay == 0 {
|
if fallbackDelay == 0 {
|
||||||
fallbackDelay = N.DefaultFallbackDelay
|
fallbackDelay = N.DefaultFallbackDelay
|
||||||
}
|
}
|
||||||
@ -31,7 +32,9 @@ func (d *DefaultDialer) dialParallelInterface(ctx context.Context, dialer net.Di
|
|||||||
results := make(chan dialResult) // unbuffered
|
results := make(chan dialResult) // unbuffered
|
||||||
startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
|
startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
|
||||||
perNetDialer := dialer
|
perNetDialer := dialer
|
||||||
perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
|
if defaultInterface == nil || iif.Index != defaultInterface.Index {
|
||||||
|
perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
|
||||||
|
}
|
||||||
conn, err := perNetDialer.DialContext(ctx, network, addr)
|
conn, err := perNetDialer.DialContext(ctx, network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
select {
|
select {
|
||||||
@ -89,6 +92,7 @@ func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Context, d
|
|||||||
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
||||||
return nil, false, E.New("no available network interface")
|
return nil, false, E.New("no available network interface")
|
||||||
}
|
}
|
||||||
|
defaultInterface := d.networkManager.InterfaceMonitor().DefaultInterface()
|
||||||
if fallbackDelay == 0 {
|
if fallbackDelay == 0 {
|
||||||
fallbackDelay = N.DefaultFallbackDelay
|
fallbackDelay = N.DefaultFallbackDelay
|
||||||
}
|
}
|
||||||
@ -103,7 +107,9 @@ func (d *DefaultDialer) dialParallelInterfaceFastFallback(ctx context.Context, d
|
|||||||
results := make(chan dialResult) // unbuffered
|
results := make(chan dialResult) // unbuffered
|
||||||
startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
|
startRacer := func(ctx context.Context, primary bool, iif adapter.NetworkInterface) {
|
||||||
perNetDialer := dialer
|
perNetDialer := dialer
|
||||||
perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
|
if defaultInterface == nil || iif.Index != defaultInterface.Index {
|
||||||
|
perNetDialer.Control = control.Append(perNetDialer.Control, control.BindToInterface(nil, iif.Name, iif.Index))
|
||||||
|
}
|
||||||
conn, err := perNetDialer.DialContext(ctx, network, addr)
|
conn, err := perNetDialer.DialContext(ctx, network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
select {
|
select {
|
||||||
@ -149,10 +155,13 @@ func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context, listene
|
|||||||
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
||||||
return nil, E.New("no available network interface")
|
return nil, E.New("no available network interface")
|
||||||
}
|
}
|
||||||
|
defaultInterface := d.networkManager.InterfaceMonitor().DefaultInterface()
|
||||||
var errors []error
|
var errors []error
|
||||||
for _, primaryInterface := range primaryInterfaces {
|
for _, primaryInterface := range primaryInterfaces {
|
||||||
perNetListener := listener
|
perNetListener := listener
|
||||||
perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, primaryInterface.Name, primaryInterface.Index))
|
if defaultInterface == nil || primaryInterface.Index != defaultInterface.Index {
|
||||||
|
perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, primaryInterface.Name, primaryInterface.Index))
|
||||||
|
}
|
||||||
conn, err := perNetListener.ListenPacket(ctx, network, addr)
|
conn, err := perNetListener.ListenPacket(ctx, network, addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
@ -161,7 +170,9 @@ func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context, listene
|
|||||||
}
|
}
|
||||||
for _, fallbackInterface := range fallbackInterfaces {
|
for _, fallbackInterface := range fallbackInterfaces {
|
||||||
perNetListener := listener
|
perNetListener := listener
|
||||||
perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, fallbackInterface.Name, fallbackInterface.Index))
|
if defaultInterface == nil || fallbackInterface.Index != defaultInterface.Index {
|
||||||
|
perNetListener.Control = control.Append(perNetListener.Control, control.BindToInterface(nil, fallbackInterface.Name, fallbackInterface.Index))
|
||||||
|
}
|
||||||
conn, err := perNetListener.ListenPacket(ctx, network, addr)
|
conn, err := perNetListener.ListenPacket(ctx, network, addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
icon: material/alert-decagram
|
icon: material/alert-decagram
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 1.11.5
|
||||||
|
|
||||||
|
* Fixes and improvements
|
||||||
|
|
||||||
|
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we violated the rules (TestFlight users are not affected)._
|
||||||
|
|
||||||
### 1.11.4
|
### 1.11.4
|
||||||
|
|
||||||
* Fixes and improvements
|
* Fixes and improvements
|
||||||
|
@ -7,6 +7,10 @@ icon: material/apple
|
|||||||
SFI/SFM/SFT allows users to manage and run local or remote sing-box configuration files, and provides
|
SFI/SFM/SFT allows users to manage and run local or remote sing-box configuration files, and provides
|
||||||
platform-specific function implementation, such as TUN transparent proxy implementation.
|
platform-specific function implementation, such as TUN transparent proxy implementation.
|
||||||
|
|
||||||
|
!!! failure ""
|
||||||
|
|
||||||
|
We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we violated the rules (TestFlight users are not affected).
|
||||||
|
|
||||||
## :material-graph: Requirements
|
## :material-graph: Requirements
|
||||||
|
|
||||||
* iOS 15.0+ / macOS 13.0+ / Apple tvOS 17.0+
|
* iOS 15.0+ / macOS 13.0+ / Apple tvOS 17.0+
|
||||||
|
@ -31,12 +31,11 @@ The protocol version, `1` or `2`.
|
|||||||
|
|
||||||
### Application support
|
### Application support
|
||||||
|
|
||||||
| Project | UoT v1 | UoT v2 |
|
| Project | UoT v1 | UoT v2 |
|
||||||
|--------------|----------------------|-------------------------------------------------------------------------------------------------------------------|
|
|--------------|----------------------|----------------------|
|
||||||
| sing-box | v0 (2022/08/11) | v1.2-beta9 |
|
| sing-box | v0 (2022/08/11) | v1.2-beta9 |
|
||||||
| Xray-core | v1.5.7 (2022/06/05) | [f57ec13](https://github.com/XTLS/Xray-core/commit/f57ec1388084df041a2289bacab14e446bf1b357) (Not released) |
|
| Clash.Meta | v1.12.0 (2022/07/02) | v1.14.3 (2023/03/31) |
|
||||||
| Clash.Meta | v1.12.0 (2022/07/02) | [8cb67b6](https://github.com/MetaCubeX/Clash.Meta/commit/8cb67b6480649edfa45dcc9ac89ce0789651e8b3) (Not released) |
|
| Shadowrocket | v2.2.12 (2022/08/13) | / |
|
||||||
| Shadowrocket | v2.2.12 (2022/08/13) | / |
|
|
||||||
|
|
||||||
### Protocol details
|
### Protocol details
|
||||||
|
|
||||||
@ -50,7 +49,13 @@ The client requests the magic address to the upper layer proxy protocol to indic
|
|||||||
|------|----------|-------|--------|----------|
|
|------|----------|-------|--------|----------|
|
||||||
| u8 | variable | u16be | u16be | variable |
|
| u8 | variable | u16be | u16be | variable |
|
||||||
|
|
||||||
**ATYP / address / port**: Uses the SOCKS address format.
|
**ATYP / address / port**: Uses the SOCKS address format, but with different address types:
|
||||||
|
|
||||||
|
| ATYP | Address type |
|
||||||
|
|--------|--------------|
|
||||||
|
| `0x00` | IPv4 Address |
|
||||||
|
| `0x01` | IPv6 Address |
|
||||||
|
| `0x02` | Domain Name |
|
||||||
|
|
||||||
#### Protocol version 2
|
#### Protocol version 2
|
||||||
|
|
||||||
|
@ -71,15 +71,15 @@ func (s *Server) downloadExternalUI() error {
|
|||||||
if response.StatusCode != http.StatusOK {
|
if response.StatusCode != http.StatusOK {
|
||||||
return E.New("download external ui failed: ", response.Status)
|
return E.New("download external ui failed: ", response.Status)
|
||||||
}
|
}
|
||||||
err = s.downloadZIP(filepath.Base(downloadURL), response.Body, s.externalUI)
|
err = s.downloadZIP(response.Body, s.externalUI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
removeAllInDirectory(s.externalUI)
|
removeAllInDirectory(s.externalUI)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) downloadZIP(name string, body io.Reader, output string) error {
|
func (s *Server) downloadZIP(body io.Reader, output string) error {
|
||||||
tempFile, err := filemanager.CreateTemp(s.ctx, name)
|
tempFile, err := filemanager.CreateTemp(s.ctx, "external-ui.zip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,12 @@ func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Eleme
|
|||||||
|
|
||||||
func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32, isExpensive bool, isConstrained bool) {
|
func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32, isExpensive bool, isConstrained bool) {
|
||||||
if sFixAndroidStack {
|
if sFixAndroidStack {
|
||||||
go m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
<-done
|
||||||
} else {
|
} else {
|
||||||
m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
|
m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -26,7 +26,7 @@ require (
|
|||||||
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff
|
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff
|
||||||
github.com/sagernet/quic-go v0.49.0-beta.1
|
github.com/sagernet/quic-go v0.49.0-beta.1
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||||
github.com/sagernet/sing v0.6.1
|
github.com/sagernet/sing v0.6.3
|
||||||
github.com/sagernet/sing-dns v0.4.0
|
github.com/sagernet/sing-dns v0.4.0
|
||||||
github.com/sagernet/sing-mux v0.3.1
|
github.com/sagernet/sing-mux v0.3.1
|
||||||
github.com/sagernet/sing-quic v0.4.0
|
github.com/sagernet/sing-quic v0.4.0
|
||||||
|
4
go.sum
4
go.sum
@ -119,8 +119,8 @@ github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8W
|
|||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||||
github.com/sagernet/sing v0.6.1 h1:mJ6e7Ir2wtCoGLbdnnXWBsNJu5YHtbXmv66inoE0zFA=
|
github.com/sagernet/sing v0.6.3 h1:J1spMc6LMlqUvRjWjvNMAcbvACDneqxB9zxfLuS0UTE=
|
||||||
github.com/sagernet/sing v0.6.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
github.com/sagernet/sing v0.6.3/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||||
github.com/sagernet/sing-dns v0.4.0 h1:+mNoOuR3nljjouCH+qMg4zHI1+R9T2ReblGFkZPEndc=
|
github.com/sagernet/sing-dns v0.4.0 h1:+mNoOuR3nljjouCH+qMg4zHI1+R9T2ReblGFkZPEndc=
|
||||||
github.com/sagernet/sing-dns v0.4.0/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8=
|
github.com/sagernet/sing-dns v0.4.0/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8=
|
||||||
github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=
|
github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
"github.com/sagernet/sing/common/udpnat2"
|
"github.com/sagernet/sing/common/udpnat2"
|
||||||
@ -80,7 +81,7 @@ func (i *Inbound) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||||
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, M.Socksaddr{}, nil)
|
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, i.listener.UDPAddr(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||||
@ -104,7 +105,6 @@ func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
|
|||||||
|
|
||||||
func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||||
i.logger.InfoContext(ctx, "inbound packet connection from ", source)
|
i.logger.InfoContext(ctx, "inbound packet connection from ", source)
|
||||||
i.logger.InfoContext(ctx, "inbound packet connection to ", destination)
|
|
||||||
var metadata adapter.InboundContext
|
var metadata adapter.InboundContext
|
||||||
metadata.Inbound = i.Tag()
|
metadata.Inbound = i.Tag()
|
||||||
metadata.InboundType = i.Type()
|
metadata.InboundType = i.Type()
|
||||||
@ -123,8 +123,11 @@ func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
|||||||
destination.Port = i.overrideDestination.Port
|
destination.Port = i.overrideDestination.Port
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
i.logger.InfoContext(ctx, "inbound packet connection to ", destination)
|
||||||
metadata.Destination = destination
|
metadata.Destination = destination
|
||||||
metadata.OriginDestination = i.listener.UDPAddr()
|
if i.overrideOption != 0 {
|
||||||
|
conn = bufio.NewDestinationNATPacketConn(bufio.NewNetPacketConn(conn), i.listener.UDPAddr(), destination)
|
||||||
|
}
|
||||||
i.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
i.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
inbound.router, err = mux.NewRouterWithOptions(router, logger, common.PtrValueOrDefault(options.Multiplex))
|
inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -149,22 +149,17 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
|
|||||||
} else {
|
} else {
|
||||||
originDestination = metadata.Destination
|
originDestination = metadata.Destination
|
||||||
}
|
}
|
||||||
if metadata.Destination != M.SocksaddrFrom(destinationAddress, metadata.Destination.Port) {
|
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
|
||||||
|
natConn.UpdateDestination(destinationAddress)
|
||||||
|
} else if metadata.Destination != M.SocksaddrFrom(destinationAddress, metadata.Destination.Port) {
|
||||||
if metadata.UDPDisableDomainUnmapping {
|
if metadata.UDPDisableDomainUnmapping {
|
||||||
remotePacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
remotePacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
||||||
} else {
|
} else {
|
||||||
remotePacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
remotePacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
|
|
||||||
natConn.UpdateDestination(destinationAddress)
|
|
||||||
}
|
|
||||||
} else if metadata.RouteOriginalDestination.IsValid() && metadata.RouteOriginalDestination != metadata.Destination {
|
} else if metadata.RouteOriginalDestination.IsValid() && metadata.RouteOriginalDestination != metadata.Destination {
|
||||||
if metadata.UDPDisableDomainUnmapping {
|
remotePacketConn = bufio.NewDestinationNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
|
||||||
remotePacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
|
|
||||||
} else {
|
|
||||||
remotePacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var udpTimeout time.Duration
|
var udpTimeout time.Duration
|
||||||
if metadata.UDPTimeout > 0 {
|
if metadata.UDPTimeout > 0 {
|
||||||
@ -279,13 +274,17 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
|
|||||||
func (m *ConnectionManager) packetConnectionCopy(ctx context.Context, source N.PacketReader, destination N.PacketWriter, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) {
|
func (m *ConnectionManager) packetConnectionCopy(ctx context.Context, source N.PacketReader, destination N.PacketWriter, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) {
|
||||||
_, err := bufio.CopyPacket(destination, source)
|
_, err := bufio.CopyPacket(destination, source)
|
||||||
if !direction {
|
if !direction {
|
||||||
if E.IsClosedOrCanceled(err) {
|
if err == nil {
|
||||||
|
m.logger.DebugContext(ctx, "packet upload finished")
|
||||||
|
} else if E.IsClosedOrCanceled(err) {
|
||||||
m.logger.TraceContext(ctx, "packet upload closed")
|
m.logger.TraceContext(ctx, "packet upload closed")
|
||||||
} else {
|
} else {
|
||||||
m.logger.DebugContext(ctx, "packet upload closed: ", err)
|
m.logger.DebugContext(ctx, "packet upload closed: ", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if E.IsClosedOrCanceled(err) {
|
if err == nil {
|
||||||
|
m.logger.DebugContext(ctx, "packet download finished")
|
||||||
|
} else if E.IsClosedOrCanceled(err) {
|
||||||
m.logger.TraceContext(ctx, "packet download closed")
|
m.logger.TraceContext(ctx, "packet download closed")
|
||||||
} else {
|
} else {
|
||||||
m.logger.DebugContext(ctx, "packet download closed: ", err)
|
m.logger.DebugContext(ctx, "packet download closed: ", err)
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
var _ net.Conn = (*GunConn)(nil)
|
var _ net.Conn = (*GunConn)(nil)
|
||||||
|
|
||||||
type GunConn struct {
|
type GunConn struct {
|
||||||
|
rawReader io.Reader
|
||||||
reader *std_bufio.Reader
|
reader *std_bufio.Reader
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
flusher http.Flusher
|
flusher http.Flusher
|
||||||
@ -31,9 +32,10 @@ type GunConn struct {
|
|||||||
|
|
||||||
func newGunConn(reader io.Reader, writer io.Writer, flusher http.Flusher) *GunConn {
|
func newGunConn(reader io.Reader, writer io.Writer, flusher http.Flusher) *GunConn {
|
||||||
return &GunConn{
|
return &GunConn{
|
||||||
reader: std_bufio.NewReader(reader),
|
rawReader: reader,
|
||||||
writer: writer,
|
reader: std_bufio.NewReader(reader),
|
||||||
flusher: flusher,
|
writer: writer,
|
||||||
|
flusher: flusher,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ func newLateGunConn(writer io.Writer) *GunConn {
|
|||||||
|
|
||||||
func (c *GunConn) setup(reader io.Reader, err error) {
|
func (c *GunConn) setup(reader io.Reader, err error) {
|
||||||
if reader != nil {
|
if reader != nil {
|
||||||
|
c.rawReader = reader
|
||||||
c.reader = std_bufio.NewReader(reader)
|
c.reader = std_bufio.NewReader(reader)
|
||||||
}
|
}
|
||||||
c.err = err
|
c.err = err
|
||||||
@ -138,7 +141,7 @@ func (c *GunConn) FrontHeadroom() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GunConn) Close() error {
|
func (c *GunConn) Close() error {
|
||||||
return common.Close(c.reader, c.writer)
|
return common.Close(c.rawReader, c.writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GunConn) LocalAddr() net.Addr {
|
func (c *GunConn) LocalAddr() net.Addr {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user