Skip to content

Commit ebf5918

Browse files
committed
fix: v2ray-plugin mux maybe not close underlay connection
1 parent 93ca185 commit ebf5918

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

transport/v2ray-plugin/mux.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"errors"
77
"io"
88
"net"
9+
"time"
910
)
1011

1112
type SessionStatus = byte
@@ -37,7 +38,6 @@ type Mux struct {
3738
id [2]byte
3839
length [2]byte
3940
status [2]byte
40-
otb []byte
4141
remain int
4242
}
4343

@@ -104,14 +104,8 @@ func (m *Mux) Read(b []byte) (int, error) {
104104
}
105105

106106
func (m *Mux) Write(b []byte) (int, error) {
107-
if m.otb != nil {
108-
// create a sub connection
109-
if _, err := m.Conn.Write(m.otb); err != nil {
110-
return 0, err
111-
}
112-
m.otb = nil
113-
}
114-
m.buf.Reset()
107+
defer m.buf.Reset() // reset must after write (keep the data fill in NewMux can be sent)
108+
115109
binary.Write(&m.buf, binary.BigEndian, uint16(4))
116110
m.buf.Write(m.id[:])
117111
m.buf.WriteByte(SessionStatusKeep)
@@ -123,15 +117,26 @@ func (m *Mux) Write(b []byte) (int, error) {
123117
}
124118

125119
func (m *Mux) Close() error {
126-
_, err := m.Conn.Write([]byte{0x0, 0x4, m.id[0], m.id[1], SessionStatusEnd, OptionNone})
127-
if err != nil {
128-
return err
120+
errChan := make(chan error, 1)
121+
t := time.AfterFunc(time.Second, func() { // maybe conn write too slowly, force close underlay conn after one second
122+
errChan <- m.Conn.Close()
123+
})
124+
_, _ = m.Conn.Write([]byte{0x0, 0x4, m.id[0], m.id[1], SessionStatusEnd, OptionNone}) // ignore session end frame write error
125+
if !t.Stop() {
126+
// Stop does not wait for f to complete before returning, so we used a chan to know whether f is completed
127+
return <-errChan
129128
}
130129
return m.Conn.Close()
131130
}
132131

133132
func NewMux(conn net.Conn, option MuxOption) *Mux {
134-
buf := &bytes.Buffer{}
133+
mux := &Mux{
134+
Conn: conn,
135+
id: option.ID,
136+
}
137+
138+
// create a sub connection (in buf)
139+
buf := &mux.buf
135140

136141
// fill empty length
137142
buf.Write([]byte{0x0, 0x0})
@@ -165,9 +170,5 @@ func NewMux(conn net.Conn, option MuxOption) *Mux {
165170
metadata := buf.Bytes()
166171
binary.BigEndian.PutUint16(metadata[:2], uint16(len(metadata)-2))
167172

168-
return &Mux{
169-
Conn: conn,
170-
id: option.ID,
171-
otb: metadata,
172-
}
173+
return mux
173174
}

0 commit comments

Comments
 (0)