Compare commits

...
6 Commits
Author SHA1 Message Date
xtaci 94c9cacf4f upd deps to smux to v1.5.16 2021-09-22 21:45:09 +08:00
xtaci 9a5b31b470 enable support for Apple M1 2021-04-01 22:23:46 +08:00
xtaci 07ad03fecf remove a duplicated logging 2020-12-20 19:09:43 +08:00
Hugo WangandGitHub 2225d258cb create UDP connection only when needed (#825)
* create udp connection only when needed

* misc

* some more minor changes

* update option description

* sync the doc

* lets keep original

* respect config.Quiet

* misc

* removed the useless muxes init
2020-12-20 16:23:32 +08:00
xtaci e9316f7be4 remove a condition in scavenger 2020-12-19 11:42:24 +08:00
xtaci 9ac04cd24d a smarter scavenger 2020-12-17 17:37:36 +08:00
10 changed files with 64 additions and 51 deletions
+1 -1
View File
@@ -152,7 +152,7 @@ GLOBAL OPTIONS:
--mode value profiles: fast3, fast2, fast, normal, manual (default: "fast")
--conn value set num of UDP connections to server (default: 1)
--autoexpire value set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)
--scavengettl value set how long an expired connection can live(in sec), -1 to disable (default: 600)
--scavengettl value set how long an expired connection can live (in seconds) (default: 600)
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 128)
--rcvwnd value set receive window size(num of packets) (default: 512)
+6 -11
View File
@@ -57,6 +57,12 @@ for os in ${OSES[@]}; do
$sum kcptun-${os}-386-$VERSION.tar.gz
done
#Apple M1 device
env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_darwin_arm64 github.com/xtaci/kcptun/server
env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_darwin_arm64 github.com/xtaci/kcptun/client
tar -zcf kcptun-darwin-arm64-$VERSION.tar.gz client_darwin_arm64 server_darwin_arm64
$sum kcptun-darwin-arm64-$VERSION.tar.gz
# ARM
ARMS=(5 6 7)
for v in ${ARMS[@]}; do
@@ -67,17 +73,6 @@ tar -zcf kcptun-linux-arm$v-$VERSION.tar.gz client_linux_arm$v server_linux_arm$
$sum kcptun-linux-arm$v-$VERSION.tar.gz
done
#Apple M1 device
os=`uname` #Darwin
arch=`arch`
if [ $os == "Darwin" ] && [ $arch == "arm64" ]
then
env CGO_ENABLED=0 GOOS=darwin GOARCH=$arch go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_darwin_$arch github.com/xtaci/kcptun/server
env CGO_ENABLED=0 GOOS=darwin GOARCH=$arch go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_darwin_$arch github.com/xtaci/kcptun/client
tar -zcf kcptun-darwin-arm64-$VERSION.tar.gz client_darwin_arm64 server_darwin_arm64
$sum kcptun-darwin-arm64-$VERSION.tar.gz
fi
# ARM64
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm64 github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -mod=vendor -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm64 github.com/xtaci/kcptun/server
+41 -32
View File
@@ -73,6 +73,11 @@ func checkError(err error) {
}
}
type timedSession struct {
session *smux.Session
expiryDate time.Time
}
func main() {
rand.Seed(int64(time.Now().Nanosecond()))
if VERSION == "SELFBUILD" {
@@ -124,7 +129,7 @@ func main() {
cli.IntFlag{
Name: "scavengettl",
Value: 600,
Usage: "set how long an expired connection can live(in sec), -1 to disable",
Usage: "set how long an expired connection can live (in seconds)",
},
cli.IntFlag{
Name: "mtu",
@@ -421,20 +426,16 @@ func main() {
}
}
numconn := uint16(config.Conn)
muxes := make([]struct {
session *smux.Session
ttl time.Time
}, numconn)
for k := range muxes {
muxes[k].session = waitConn()
muxes[k].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
}
chScavenger := make(chan *smux.Session, 128)
go scavenger(chScavenger, config.ScavengeTTL)
// start snmp logger
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
// start scavenger
chScavenger := make(chan timedSession, 128)
go scavenger(chScavenger, &config)
// start listener
numconn := uint16(config.Conn)
muxes := make([]timedSession, numconn)
rr := uint16(0)
for {
p1, err := listener.AcceptTCP()
@@ -444,10 +445,13 @@ func main() {
idx := rr % numconn
// do auto expiration && reconnection
if muxes[idx].session.IsClosed() || (config.AutoExpire > 0 && time.Now().After(muxes[idx].ttl)) {
chScavenger <- muxes[idx].session
if muxes[idx].session == nil || muxes[idx].session.IsClosed() ||
(config.AutoExpire > 0 && time.Now().After(muxes[idx].expiryDate)) {
muxes[idx].session = waitConn()
muxes[idx].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
muxes[idx].expiryDate = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
if config.AutoExpire > 0 { // only when autoexpire set
chScavenger <- muxes[idx]
}
}
go handleClient(muxes[idx].session, p1, config.Quiet)
@@ -457,30 +461,35 @@ func main() {
myApp.Run(os.Args)
}
type scavengeSession struct {
session *smux.Session
ts time.Time
}
func scavenger(ch chan timedSession, config *Config) {
// When AutoExpire is set to 0 (default), sessionList will keep empty.
// Then this routine won't need to do anything; thus just terminate it.
if config.AutoExpire <= 0 {
return
}
func scavenger(ch chan *smux.Session, ttl int) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
var sessionList []scavengeSession
var sessionList []timedSession
for {
select {
case sess := <-ch:
sessionList = append(sessionList, scavengeSession{sess, time.Now()})
log.Println("session marked as expired", sess.RemoteAddr())
case item := <-ch:
sessionList = append(sessionList, timedSession{
item.session,
item.expiryDate.Add(time.Duration(config.ScavengeTTL) * time.Second)})
case <-ticker.C:
var newList []scavengeSession
if len(sessionList) == 0 {
continue
}
var newList []timedSession
for k := range sessionList {
s := sessionList[k]
if s.session.NumStreams() == 0 || s.session.IsClosed() {
log.Println("session normally closed", s.session.RemoteAddr())
s.session.Close()
} else if ttl >= 0 && time.Since(s.ts) >= time.Duration(ttl)*time.Second {
log.Println("session reached scavenge ttl", s.session.RemoteAddr())
if s.session.IsClosed() {
log.Println("scavenger: session normally closed:", s.session.LocalAddr())
} else if time.Now().After(s.expiryDate) {
s.session.Close()
log.Println("scavenger: session closed due to ttl:", s.session.LocalAddr())
} else {
newList = append(newList, sessionList[k])
}
+1 -1
View File
@@ -7,7 +7,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.21.0
github.com/xtaci/kcp-go/v5 v5.6.1
github.com/xtaci/smux v1.5.15
github.com/xtaci/smux v1.5.16
github.com/xtaci/tcpraw v1.2.25
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
)
+2
View File
@@ -42,6 +42,8 @@ github.com/xtaci/smux v1.5.14 h1:1j+zJYDZRv9FHaWqCJfH5RPizIm0fSzJIFbfVn8zsfg=
github.com/xtaci/smux v1.5.14/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/smux v1.5.15 h1:6hMiXswcleXj5oNfcJc+DXS8Vj36XX2LaX98udog6Kc=
github.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/smux v1.5.16 h1:FBPYOkW8ZTjLKUM4LI4xnnuuDC8CQ/dB04HD519WoEk=
github.com/xtaci/smux v1.5.16/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk=
github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+3
View File
@@ -1,3 +1,6 @@
arch:
- amd64
- ppc64le
language: go
go:
- 1.9.x
+2 -2
View File
@@ -24,7 +24,7 @@ var (
)
type writeRequest struct {
prio uint64
prio uint32
frame Frame
result chan writeResult
}
@@ -496,7 +496,7 @@ func (s *Session) writeFrame(f Frame) (n int, err error) {
}
// internal writeFrame version to support deadline used in keepalive
func (s *Session) writeFrameInternal(f Frame, deadline <-chan time.Time, prio uint64) (int, error) {
func (s *Session) writeFrameInternal(f Frame, deadline <-chan time.Time, prio uint32) (int, error) {
req := writeRequest{
prio: prio,
frame: f,
+5 -1
View File
@@ -1,9 +1,13 @@
package smux
func _itimediff(later, earlier uint32) int32 {
return (int32)(later - earlier)
}
type shaperHeap []writeRequest
func (h shaperHeap) Len() int { return len(h) }
func (h shaperHeap) Less(i, j int) bool { return h[i].prio < h[j].prio }
func (h shaperHeap) Less(i, j int) bool { return _itimediff(h[j].prio, h[i].prio) > 0 }
func (h shaperHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *shaperHeap) Push(x interface{}) { *h = append(*h, x.(writeRequest)) }
+2 -2
View File
@@ -325,7 +325,7 @@ func (s *Stream) Write(b []byte) (n int, err error) {
}
frame.data = bts[:sz]
bts = bts[sz:]
n, err := s.sess.writeFrameInternal(frame, deadline, uint64(s.numWritten))
n, err := s.sess.writeFrameInternal(frame, deadline, s.numWritten)
s.numWritten++
sent += n
if err != nil {
@@ -393,7 +393,7 @@ func (s *Stream) writeV2(b []byte) (n int, err error) {
}
frame.data = bts[:sz]
bts = bts[sz:]
n, err := s.sess.writeFrameInternal(frame, deadline, uint64(atomic.LoadUint32(&s.numWritten)))
n, err := s.sess.writeFrameInternal(frame, deadline, atomic.LoadUint32(&s.numWritten))
atomic.AddUint32(&s.numWritten, uint32(sz))
sent += n
if err != nil {
+1 -1
View File
@@ -41,7 +41,7 @@ github.com/urfave/cli
# github.com/xtaci/kcp-go/v5 v5.6.1
## explicit
github.com/xtaci/kcp-go/v5
# github.com/xtaci/smux v1.5.15
# github.com/xtaci/smux v1.5.16
## explicit
github.com/xtaci/smux
# github.com/xtaci/tcpraw v1.2.25