Skip to content

Commit

Permalink
optimize: switch fixed length LRU to fixed timeout LRU (#14)
Browse files Browse the repository at this point in the history
* optimize: switch fixed length LRU to fixed timeout LRU

* fix(linklist): refine Back() and Front()
  • Loading branch information
mzz2017 authored Jan 27, 2021
1 parent 38b32c9 commit cf2e7c1
Show file tree
Hide file tree
Showing 20 changed files with 209 additions and 188 deletions.
2 changes: 1 addition & 1 deletion cipher/cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"crypto/cipher"
"crypto/md5"
"crypto/sha1"
"github.com/Qv2ray/mmp-go/common/pool"
"github.com/Qv2ray/mmp-go/infra/pool"
"github.com/qv2ray/smaead"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/hkdf"
Expand Down
70 changes: 0 additions & 70 deletions common/lru/lru.go

This file was deleted.

25 changes: 8 additions & 17 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import (
"flag"
"fmt"
"github.com/Qv2ray/mmp-go/cipher"
"github.com/Qv2ray/mmp-go/common/lru"
"github.com/Qv2ray/mmp-go/infra/lru"
"io/ioutil"
"log"
"os"
"sync"
"time"
)

type Config struct {
ConfPath string `json:"-"`
Groups []Group `json:"groups"`
ClientCapacity int `json:"clientCapacity"`
ConfPath string `json:"-"`
Groups []Group `json:"groups"`
}
type Server struct {
Target string `json:"target"`
Expand All @@ -32,8 +32,7 @@ type Group struct {
}

const (
// around 30kB per client if there are 300 servers to forward
DefaultClientCapacity = 100
LRUTimeout = 30 * time.Minute
)

var (
Expand All @@ -49,12 +48,8 @@ func (g *Group) BuildMasterKeys() {
s.MasterKey = cipher.EVPBytesToKey(s.Password, cipher.CiphersConf[s.Method].KeyLen)
}
}
func (g *Group) BuildUserContextPool(globalLRUSize int) {
lruSize := g.LRUSize
if lruSize == 0 {
lruSize = globalLRUSize
}
g.UserContextPool = (*UserContextPool)(lru.New(lruSize))
func (g *Group) BuildUserContextPool(timeout time.Duration) {
g.UserContextPool = (*UserContextPool)(lru.New(lru.FixedTimeout, int64(timeout)))
}

func (config *Config) CheckMethodSupported() error {
Expand Down Expand Up @@ -128,13 +123,9 @@ func check(config *Config) (err error) {
return
}
func build(config *Config) {
globalClientCapacity := config.ClientCapacity
if globalClientCapacity == 0 {
globalClientCapacity = DefaultClientCapacity
}
for i := range config.Groups {
g := &config.Groups[i]
g.BuildUserContextPool(globalClientCapacity)
g.BuildUserContextPool(LRUTimeout)
g.BuildMasterKeys()
}
}
Expand Down
12 changes: 6 additions & 6 deletions config/userContext.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package config

import (
"github.com/Qv2ray/mmp-go/common/lru"
"github.com/Qv2ray/mmp-go/common/lrulist"
"github.com/Qv2ray/mmp-go/infra/lru"
"github.com/Qv2ray/mmp-go/infra/lrulist"
"math/rand"
"net"
"time"
Expand Down Expand Up @@ -53,11 +53,11 @@ func (pool *UserContextPool) Infra() *lru.LRU {

func (pool *UserContextPool) GetOrInsert(addr net.Addr, servers []Server) *UserContext {
userIdent, _, _ := net.SplitHostPort(addr.String())
node, removed := pool.Infra().GetOrInsert(userIdent, func() (val interface{}) {
value, removed := pool.Infra().GetOrInsert(userIdent, func() (val interface{}) {
return NewUserContext(servers)
})
if removed != nil {
removed.Val.(*UserContext).Close()
for _, ev := range removed {
ev.Value.(*UserContext).Close()
}
return node.Val.(*UserContext)
return value.(*UserContext)
}
34 changes: 33 additions & 1 deletion dispatcher/tcp/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package tcp
import (
"fmt"
"github.com/Qv2ray/mmp-go/cipher"
"github.com/Qv2ray/mmp-go/common/pool"
"github.com/Qv2ray/mmp-go/infra/pool"
"github.com/Qv2ray/mmp-go/config"
"github.com/Qv2ray/mmp-go/dispatcher"
"github.com/Qv2ray/mmp-go/dispatcher/infra"
"io"
"log"
"net"
"strings"
"sync"
"time"
)
Expand All @@ -33,6 +35,36 @@ func New(g *config.Group) (d dispatcher.Dispatcher) {
return &TCP{group: g}
}

func (d *TCP) Listen() (err error) {
d.l, err = net.Listen("tcp", fmt.Sprintf(":%d", d.group.Port))
if err != nil {
return
}
defer d.l.Close()
log.Printf("[tcp] listen on :%v\n", d.group.Port)
for {
conn, err := d.l.Accept()
if err != nil {
switch err := err.(type) {
case *net.OpError:
// FIXME:
// use `if errors.Is(err.Unwrap(), net.ErrClosed) {` with go1.16 instead.
if strings.HasSuffix(err.Error(), infra.ErrNetClosing.Error()) {
return nil
}
}
log.Printf("[error] ReadFrom: %v", err)
continue
}
go func() {
err := d.handleConn(conn)
if err != nil {
log.Println(err)
}
}()
}
}

func (d *TCP) UpdateGroup(group *config.Group) {
d.gMutex.Lock()
defer d.gMutex.Unlock()
Expand Down
39 changes: 0 additions & 39 deletions dispatcher/tcp/tcp_listen.go

This file was deleted.

2 changes: 1 addition & 1 deletion dispatcher/udp/ipMTUTrie.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package udp

import (
"github.com/Qv2ray/mmp-go/common/trie"
"github.com/Qv2ray/mmp-go/infra/trie"
"net"
"strconv"
"strings"
Expand Down
37 changes: 36 additions & 1 deletion dispatcher/udp/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package udp
import (
"fmt"
"github.com/Qv2ray/mmp-go/cipher"
"github.com/Qv2ray/mmp-go/common/pool"
"github.com/Qv2ray/mmp-go/infra/pool"
"github.com/Qv2ray/mmp-go/config"
"github.com/Qv2ray/mmp-go/dispatcher"
"github.com/Qv2ray/mmp-go/dispatcher/infra"
"golang.org/x/net/dns/dnsmessage"
"log"
"net"
"strings"
"sync"
"time"
)
Expand Down Expand Up @@ -38,6 +39,40 @@ func New(g *config.Group) (d dispatcher.Dispatcher) {
return &UDP{group: g, nm: NewUDPConnMapping()}
}

func (d *UDP) Listen() (err error) {
d.c, err = net.ListenUDP("udp", &net.UDPAddr{Port: d.group.Port})
if err != nil {
return
}
defer d.c.Close()
log.Printf("[udp] listen on :%v\n", d.group.Port)
var buf [MTU]byte
for {
n, laddr, err := d.c.ReadFrom(buf[:])
if err != nil {
switch err := err.(type) {
case *net.OpError:
// FIXME:
// use `if errors.Is(err.Unwrap(), net.ErrClosed) {` with go1.16 instead.
if strings.HasSuffix(err.Error(), infra.ErrNetClosing.Error()) {
return nil
}
}
log.Printf("[error] ReadFrom: %v", err)
continue
}
data := pool.Get(n)
copy(data, buf[:n])
go func() {
err := d.handleConn(laddr, data, n)
if err != nil {
log.Println(err)
}
pool.Put(data)
}()
}
}

func (d *UDP) UpdateGroup(group *config.Group) {
d.gMutex.Lock()
defer d.gMutex.Unlock()
Expand Down
44 changes: 0 additions & 44 deletions dispatcher/udp/udp_listen.go

This file was deleted.

2 changes: 0 additions & 2 deletions example_fullview.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"clientCapacity": 30,
"groups": [
{
"port": 1090,
"clientCapacity": 500,
"upstreams": [
{
"type": "outline",
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/Qv2ray/mmp-go
go 1.15

require (
github.com/pkg/errors v0.9.1
github.com/qv2ray/smaead v0.0.0-20210102113335-316eca415c84
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/qv2ray/smaead v0.0.0-20210102113335-316eca415c84 h1:6mrHkm7XiH40WgL0jCj3p7wjjEO2B6W0cHaeqdEcWCc=
github.com/qv2ray/smaead v0.0.0-20210102113335-316eca415c84/go.mod h1:5WfQIZ5n1h1QK0IRRI7HE5HQh1/I++F2ftQMDyJC8kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down
Loading

0 comments on commit cf2e7c1

Please sign in to comment.