Compare commits

...
5 Commits
Author SHA1 Message Date
xtaci f7d957fc35 fixed a bug that smux.OpenStream /smux.Close will hang forever in rare
case
2023-02-14 22:25:52 +08:00
xtaci bd274abccc upd deps to smux 2023-02-14 22:21:40 +08:00
xtaci 0603885bb6 upd vendor 2023-02-14 20:47:58 +08:00
xtaci eed5f5ff0e upd deps to smux@v1.5.22 2023-02-14 20:47:34 +08:00
xtaci ec099786cb upd deps to smux 2023-02-12 20:10:15 +08:00
6 changed files with 49 additions and 22 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.12
github.com/xtaci/kcp-go/v5 v5.6.2
github.com/xtaci/smux v1.5.19
github.com/xtaci/smux v1.5.24
github.com/xtaci/tcpraw v1.2.25
golang.org/x/crypto v0.5.0
)
+2 -4
View File
@@ -70,10 +70,8 @@ github.com/xtaci/kcp-go/v5 v5.6.2 h1:pSXMa5MOsb+EIZKe4sDBqlTExu2A/2Z+DFhoX2qtt2A
github.com/xtaci/kcp-go/v5 v5.6.2/go.mod h1:LsinWoru+lWWJHb+EM9HeuqYxV6bb9rNcK12v67jYzQ=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/xtaci/smux v1.5.18 h1:NRH2dIxcO1w5dsNpQxSrxfhxjk4YNg6TrS/Nj0FuUPc=
github.com/xtaci/smux v1.5.18/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/smux v1.5.19 h1:QFoVBZPuJnoTs8QQ52TO2469nz8KxGHDpiEb+s3QzCQ=
github.com/xtaci/smux v1.5.19/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=
github.com/xtaci/smux v1.5.24/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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+34 -11
View File
@@ -13,6 +13,16 @@ import (
const (
defaultAcceptBacklog = 1024
maxShaperSize = 1024
openCloseTimeout = 30 * time.Second // stream open/close timeout
)
// define frame class
type CLASSID int
const (
CLSCTRL CLASSID = iota
CLSDATA
)
var (
@@ -24,7 +34,7 @@ var (
)
type writeRequest struct {
prio uint32
class CLASSID
frame Frame
seq uint32
result chan writeResult
@@ -35,10 +45,6 @@ type writeResult struct {
err error
}
type buffersWriter interface {
WriteBuffers(v [][]byte) (n int, err error)
}
// Session defines a multiplexed connection for streams
type Session struct {
conn io.ReadWriteCloser
@@ -398,7 +404,7 @@ func (s *Session) keepalive() {
for {
select {
case <-tickerPing.C:
s.writeFrameInternal(newFrame(byte(s.config.Version), cmdNOP, 0), tickerPing.C, 0)
s.writeFrameInternal(newFrame(byte(s.config.Version), cmdNOP, 0), tickerPing.C, CLSCTRL)
s.notifyBucket() // force a signal to the recvLoop
case <-tickerTimeout.C:
if !atomic.CompareAndSwapInt32(&s.dataReady, 1, 0) {
@@ -420,8 +426,10 @@ func (s *Session) shaperLoop() {
var reqs shaperHeap
var next writeRequest
var chWrite chan writeRequest
var chShaper chan writeRequest
for {
// chWrite is not available until it has packet to send
if len(reqs) > 0 {
chWrite = s.writes
next = heap.Pop(&reqs).(writeRequest)
@@ -429,10 +437,22 @@ func (s *Session) shaperLoop() {
chWrite = nil
}
// control heap size, chShaper is not available until packets are less than maximum allowed
if len(reqs) >= maxShaperSize {
chShaper = nil
} else {
chShaper = s.shaper
}
// assertion on non nil
if chShaper == nil && chWrite == nil {
panic("both channel are nil")
}
select {
case <-s.die:
return
case r := <-s.shaper:
case r := <-chShaper:
if chWrite != nil { // next is valid, reshape
heap.Push(&reqs, next)
}
@@ -448,7 +468,10 @@ func (s *Session) sendLoop() {
var err error
var vec [][]byte // vector for writeBuffers
bw, ok := s.conn.(buffersWriter)
bw, ok := s.conn.(interface {
WriteBuffers(v [][]byte) (n int, err error)
})
if ok {
buf = make([]byte, headerSize)
vec = make([][]byte, 2)
@@ -500,13 +523,13 @@ func (s *Session) sendLoop() {
// writeFrame writes the frame to the underlying connection
// and returns the number of bytes written if successful
func (s *Session) writeFrame(f Frame) (n int, err error) {
return s.writeFrameInternal(f, nil, 0)
return s.writeFrameInternal(f, time.After(openCloseTimeout), CLSCTRL)
}
// internal writeFrame version to support deadline used in keepalive
func (s *Session) writeFrameInternal(f Frame, deadline <-chan time.Time, prio uint32) (int, error) {
func (s *Session) writeFrameInternal(f Frame, deadline <-chan time.Time, class CLASSID) (int, error) {
req := writeRequest{
prio: prio,
class: class,
frame: f,
seq: atomic.AddUint32(&s.requestID, 1),
result: make(chan writeResult, 1),
+8 -2
View File
@@ -6,8 +6,14 @@ func _itimediff(later, earlier uint32) int32 {
type shaperHeap []writeRequest
func (h shaperHeap) Len() int { return len(h) }
func (h shaperHeap) Less(i, j int) bool { return _itimediff(h[j].seq, h[i].seq) > 0 }
func (h shaperHeap) Len() int { return len(h) }
func (h shaperHeap) Less(i, j int) bool {
if h[i].class != h[j].class {
return h[i].class < h[j].class
}
return _itimediff(h[j].seq, h[i].seq) > 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)) }
+3 -3
View File
@@ -255,7 +255,7 @@ func (s *Stream) sendWindowUpdate(consumed uint32) error {
binary.LittleEndian.PutUint32(hdr[:], consumed)
binary.LittleEndian.PutUint32(hdr[4:], uint32(s.sess.config.MaxStreamBuffer))
frame.data = hdr[:]
_, err := s.sess.writeFrameInternal(frame, deadline, 0)
_, err := s.sess.writeFrameInternal(frame, deadline, CLSDATA)
return err
}
@@ -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, s.numWritten)
n, err := s.sess.writeFrameInternal(frame, deadline, CLSDATA)
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, atomic.LoadUint32(&s.numWritten))
n, err := s.sess.writeFrameInternal(frame, deadline, CLSDATA)
atomic.AddUint32(&s.numWritten, uint32(sz))
sent += n
if err != nil {
+1 -1
View File
@@ -38,7 +38,7 @@ github.com/urfave/cli
# github.com/xtaci/kcp-go/v5 v5.6.2
## explicit; go 1.13
github.com/xtaci/kcp-go/v5
# github.com/xtaci/smux v1.5.19
# github.com/xtaci/smux v1.5.24
## explicit; go 1.13
github.com/xtaci/smux
# github.com/xtaci/tcpraw v1.2.25