Skip to content

Commit

Permalink
optimize: use raw udp conn to solve quic in quic problem (juicity#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
mzz2017 authored Aug 27, 2023
1 parent 7b603cc commit 9d653f7
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 65 deletions.
7 changes: 5 additions & 2 deletions cmd/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Mini configuration:
"certificate": "/path/to/fullchain.cer",
"private_key": "/path/to/private.key",
"congestion_control": "bbr",
"disable_outbound_udp443": true,
"log_level": "info"
}
```
Expand All @@ -53,14 +54,16 @@ Full configuration:
"log_level": "info",
"fwmark": "0x1000",
"send_through": "113.25.132.3",
"dialer_link": "socks5://127.0.0.1:1080"
"dialer_link": "socks5://127.0.0.1:1080",
"disable_outbound_udp443": true
}
```

- Optional values of `congestion_control`: cubic, bbr, new_reno.
- `congestion_control`: one of cubic, bbr, new_reno.
- `fwmark` is useful for iptables/nft.
- `send_through` is the interface IP to specify to use.
- `dialer_link` can be extreme flexible. Juicity support many protocols, even proxy chains. See [proxy-protocols](https://github.com/daeuniverse/dae/blob/main/docs/en/proxy-protocols.md) [中文](https://github.com/daeuniverse/dae/blob/main/docs/zh/proxy-protocols.md).
- `disable_outbound_udp443`: usually quic traffic. Suggest to disable it because quic usually consumes too much cpu/mem resources.

## Arguments

Expand Down
17 changes: 9 additions & 8 deletions cmd/server/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,15 @@ func Serve(conf *config.Config) (err error) {
}
}
s, err := server.New(&server.Options{
Logger: logger,
Users: conf.Users,
Certificate: conf.Certificate,
PrivateKey: conf.PrivateKey,
CongestionControl: conf.CongestionControl,
Fwmark: int(fwmark),
SendThrough: conf.SendThrough,
DialerLink: conf.DialerLink,
Logger: logger,
Users: conf.Users,
Certificate: conf.Certificate,
PrivateKey: conf.PrivateKey,
CongestionControl: conf.CongestionControl,
Fwmark: int(fwmark),
SendThrough: conf.SendThrough,
DialerLink: conf.DialerLink,
DisableOutboundUdp443: conf.DisableOutboundUdp443,
})
if err != nil {
return err
Expand Down
13 changes: 7 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ type Config struct {
Forward map[string]string `json:"forward"`

// Server
Users map[string]string `json:"users"`
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
Fwmark string `json:"fwmark"`
SendThrough string `json:"send_through"`
DialerLink string `json:"dialer_link"`
Users map[string]string `json:"users"`
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
Fwmark string `json:"fwmark"`
SendThrough string `json:"send_through"`
DialerLink string `json:"dialer_link"`
DisableOutboundUdp443 bool `json:"disable_outbound_udp443"`

// Common
Listen string `json:"listen"`
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ go 1.21.0

require (
github.com/daeuniverse/outbound v0.0.0-20230814161100-5d9b25e38843
github.com/daeuniverse/softwind v0.0.0-20230821142121-f4d871b5a8c9
github.com/daeuniverse/softwind v0.0.0-20230827075246-db555b38f9f7
github.com/google/uuid v1.3.0
github.com/miekg/dns v1.1.55
github.com/mzz2017/quic-go v0.0.0-20230821141654-3dd2575ee6bc
github.com/mzz2017/quic-go v0.0.0-20230826094347-f6ce422906f4
github.com/nadoo/glider v0.16.3
github.com/rs/zerolog v1.30.0
github.com/sourcegraph/conc v0.3.0
Expand Down Expand Up @@ -37,7 +37,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mzz2017/disk-bloom v1.0.1 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.2 // indirect
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
github.com/quic-go/quic-go v0.37.4 // indirect
github.com/refraction-networking/utls v1.4.3 // indirect
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect
Expand All @@ -62,3 +62,4 @@ replace github.com/nadoo/glider => github.com/juicity/glider v0.0.0-202308051437
// replace github.com/daeuniverse/softwind => ../softwind

// replace github.com/mzz2017/quic-go => ../quic-go
// replace github.com/mzz2017/quic-go => github.com/mzz2017/quic-go v0.0.0-20230821141654-3dd2575ee6bc
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/daeuniverse/outbound v0.0.0-20230814161100-5d9b25e38843 h1:DQCB9XdxWmI9ySh7lh1Yyer+1RM+d+1oXG586NBPJ5U=
github.com/daeuniverse/outbound v0.0.0-20230814161100-5d9b25e38843/go.mod h1:0MOSc+twby808YzJjBA2VOSd928vLQFhUzHLSdL7aKM=
github.com/daeuniverse/softwind v0.0.0-20230821142121-f4d871b5a8c9 h1:88k/mjYFuA5294C50M3rXMqRYaqSNAnuk9hnjY/xGMM=
github.com/daeuniverse/softwind v0.0.0-20230821142121-f4d871b5a8c9/go.mod h1:K9Au9LY2ttqfAhZXxPPnyqt4Bue1dd/Xi8WPsZEgxOk=
github.com/daeuniverse/softwind v0.0.0-20230827075246-db555b38f9f7 h1:3gbOD+bVTILxwwfsDufnPjGDXZgoNjcbls0INqr1/j4=
github.com/daeuniverse/softwind v0.0.0-20230827075246-db555b38f9f7/go.mod h1:Didl+N+gp/UIZ6+n9lwHQjdQEBNWYbdFXvRlmlVcth8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -68,17 +68,17 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mzz2017/disk-bloom v1.0.1 h1:rEF9MiXd9qMW3ibRpqcerLXULoTgRlM21yqqJl1B90M=
github.com/mzz2017/disk-bloom v1.0.1/go.mod h1:JLHETtUu44Z6iBmsqzkOtFlRvXSlKnxjwiBRDapizDI=
github.com/mzz2017/quic-go v0.0.0-20230821141654-3dd2575ee6bc h1:2gjLlS2yBxXUGICgHSWGLS5LyRa0Lr6+w5GFiqOco/o=
github.com/mzz2017/quic-go v0.0.0-20230821141654-3dd2575ee6bc/go.mod h1:j4yzgjc6nLseaxzQT/As8D7VRQMKASjVWXBunJGTF8Y=
github.com/mzz2017/quic-go v0.0.0-20230826094347-f6ce422906f4 h1:GlGWHALzJpMsdbJMKIRg0XNjkjkWjL7x0x7JfiGQaBI=
github.com/mzz2017/quic-go v0.0.0-20230826094347-f6ce422906f4/go.mod h1:tWtXPktBZvMi0SzXP4QFO8SKDNsAkGEijAeiNe8QmyM=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
github.com/refraction-networking/utls v1.4.3 h1:BdWS3BSzCwWCFfMIXP3mjLAyQkdmog7diaD/OqFbAzM=
Expand Down
2 changes: 1 addition & 1 deletion server/forwarder.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (s *Forwarder) Serve() (err error) {
go func(buf pool.PB, lAddr netip.AddrPort) {
defer buf.Put()
endpoint, isNew, err := s.udpEndpointPool.GetOrCreate(lAddr, &UdpEndpointOptions{
Handler: func(data []byte, from netip.AddrPort) error {
Handler: func(data []byte, from netip.AddrPort, metadata any) error {
_, err := s.udpListener.WriteToUDPAddrPort(data, lAddr)
return err
},
Expand Down
91 changes: 91 additions & 0 deletions server/inflight.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package server

import (
"context"
"sync"
"time"

"github.com/daeuniverse/softwind/protocol/juicity"
)

type inFlightKey = [juicity.UnderlaySaltLen]byte

type ContextCancel struct {
Ctx context.Context
Cancel func()
}
type InFlightUnderlayKey struct {
ttl time.Duration
mu sync.Mutex
m map[inFlightKey]*juicity.UnderlayAuth
notify map[inFlightKey]*ContextCancel
}

func NewInFlightUnderlayKey(ttl time.Duration) *InFlightUnderlayKey {
return &InFlightUnderlayKey{
ttl: ttl,
mu: sync.Mutex{},
m: make(map[inFlightKey]*juicity.UnderlayAuth, 64),
notify: make(map[inFlightKey]*ContextCancel, 64),
}
}

func (i *InFlightUnderlayKey) Evict(k [juicity.UnderlaySaltLen]byte) *juicity.UnderlayAuth {
i.mu.Lock()
cc, ok := i.notify[k]
if !ok {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(i.ttl))
cc = &ContextCancel{
Ctx: ctx,
Cancel: cancel,
}
i.notify[k] = cc
i.mu.Unlock()
_ = context.AfterFunc(ctx, func() {
i.mu.Lock()
defer i.mu.Unlock()
if i.notify[k] == cc {
delete(i.notify, k)
}
})
<-cc.Ctx.Done()
i.mu.Lock()
defer i.mu.Unlock()
} else {
delete(i.notify, k)
defer cc.Cancel()
defer i.mu.Unlock()
}
auth, ok := i.m[k]
if !ok {
return nil
}
delete(i.m, k)
return auth
}

func (i *InFlightUnderlayKey) Store(k [juicity.UnderlaySaltLen]byte, auth *juicity.UnderlayAuth) {
i.mu.Lock()
defer i.mu.Unlock()
cc, ok := i.notify[k]
if !ok {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(i.ttl))
cc = &ContextCancel{
Ctx: ctx,
Cancel: cancel,
}
i.notify[k] = cc
i.m[k] = auth
_ = context.AfterFunc(ctx, func() {
i.mu.Lock()
defer i.mu.Unlock()
if i.notify[k] == cc {
delete(i.notify, k)
}
})
} else {
i.m[k] = auth
delete(i.notify, k)
cc.Cancel()
}
}
Loading

0 comments on commit 9d653f7

Please sign in to comment.