mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
fix: v2ray-plugin mux maybe not close underlay connection
This commit is contained in:
parent
93ca18517c
commit
ebf5918e94
@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SessionStatus = byte
|
type SessionStatus = byte
|
||||||
@ -37,7 +38,6 @@ type Mux struct {
|
|||||||
id [2]byte
|
id [2]byte
|
||||||
length [2]byte
|
length [2]byte
|
||||||
status [2]byte
|
status [2]byte
|
||||||
otb []byte
|
|
||||||
remain int
|
remain int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,14 +104,8 @@ func (m *Mux) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mux) Write(b []byte) (int, error) {
|
func (m *Mux) Write(b []byte) (int, error) {
|
||||||
if m.otb != nil {
|
defer m.buf.Reset() // reset must after write (keep the data fill in NewMux can be sent)
|
||||||
// create a sub connection
|
|
||||||
if _, err := m.Conn.Write(m.otb); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
m.otb = nil
|
|
||||||
}
|
|
||||||
m.buf.Reset()
|
|
||||||
binary.Write(&m.buf, binary.BigEndian, uint16(4))
|
binary.Write(&m.buf, binary.BigEndian, uint16(4))
|
||||||
m.buf.Write(m.id[:])
|
m.buf.Write(m.id[:])
|
||||||
m.buf.WriteByte(SessionStatusKeep)
|
m.buf.WriteByte(SessionStatusKeep)
|
||||||
@ -123,15 +117,26 @@ func (m *Mux) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mux) Close() error {
|
func (m *Mux) Close() error {
|
||||||
_, err := m.Conn.Write([]byte{0x0, 0x4, m.id[0], m.id[1], SessionStatusEnd, OptionNone})
|
errChan := make(chan error, 1)
|
||||||
if err != nil {
|
t := time.AfterFunc(time.Second, func() { // maybe conn write too slowly, force close underlay conn after one second
|
||||||
return err
|
errChan <- m.Conn.Close()
|
||||||
|
})
|
||||||
|
_, _ = m.Conn.Write([]byte{0x0, 0x4, m.id[0], m.id[1], SessionStatusEnd, OptionNone}) // ignore session end frame write error
|
||||||
|
if !t.Stop() {
|
||||||
|
// Stop does not wait for f to complete before returning, so we used a chan to know whether f is completed
|
||||||
|
return <-errChan
|
||||||
}
|
}
|
||||||
return m.Conn.Close()
|
return m.Conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMux(conn net.Conn, option MuxOption) *Mux {
|
func NewMux(conn net.Conn, option MuxOption) *Mux {
|
||||||
buf := &bytes.Buffer{}
|
mux := &Mux{
|
||||||
|
Conn: conn,
|
||||||
|
id: option.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a sub connection (in buf)
|
||||||
|
buf := &mux.buf
|
||||||
|
|
||||||
// fill empty length
|
// fill empty length
|
||||||
buf.Write([]byte{0x0, 0x0})
|
buf.Write([]byte{0x0, 0x0})
|
||||||
@ -165,9 +170,5 @@ func NewMux(conn net.Conn, option MuxOption) *Mux {
|
|||||||
metadata := buf.Bytes()
|
metadata := buf.Bytes()
|
||||||
binary.BigEndian.PutUint16(metadata[:2], uint16(len(metadata)-2))
|
binary.BigEndian.PutUint16(metadata[:2], uint16(len(metadata)-2))
|
||||||
|
|
||||||
return &Mux{
|
return mux
|
||||||
Conn: conn,
|
|
||||||
id: option.ID,
|
|
||||||
otb: metadata,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user