mirror of https://github.com/v2ray/v2ray-core
handle transport errors in mux session
parent
a3f47f4fa2
commit
90c6113dfc
|
@ -15,6 +15,7 @@ const (
|
||||||
SessionStatusKeep SessionStatus = 0x02
|
SessionStatusKeep SessionStatus = 0x02
|
||||||
SessionStatusEnd SessionStatus = 0x03
|
SessionStatusEnd SessionStatus = 0x03
|
||||||
SessionStatusKeepAlive SessionStatus = 0x04
|
SessionStatusKeepAlive SessionStatus = 0x04
|
||||||
|
SessionStatusError SessionStatus = 0x05
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -146,12 +146,14 @@ func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
|
||||||
}
|
}
|
||||||
s.transferType = transferType
|
s.transferType = transferType
|
||||||
writer := NewWriter(s.ID, dest, output, transferType)
|
writer := NewWriter(s.ID, dest, output, transferType)
|
||||||
defer writer.Close()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
newError("dispatching request to ", dest).WithContext(ctx).WriteToLog()
|
newError("dispatching request to ", dest).WithContext(ctx).WriteToLog()
|
||||||
if err := buf.Copy(s.input, writer); err != nil {
|
if err := buf.Copy(s.input, writer); err != nil {
|
||||||
newError("failed to fetch all input").Base(err).WithContext(ctx).WriteToLog()
|
newError("failed to fetch all input").Base(err).WithContext(ctx).WriteToLog()
|
||||||
|
writer.Error()
|
||||||
|
} else {
|
||||||
|
writer.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +216,18 @@ func (m *Client) handleStatusEnd(meta *FrameMetadata, reader *buf.BufferedReader
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Client) handleStatusError(meta *FrameMetadata, reader *buf.BufferedReader) error {
|
||||||
|
if s, found := m.sessionManager.Get(meta.SessionID); found {
|
||||||
|
s.output.CloseError()
|
||||||
|
s.input.CloseError()
|
||||||
|
s.Close()
|
||||||
|
}
|
||||||
|
if meta.Option.Has(OptionData) {
|
||||||
|
return drain(reader)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Client) fetchOutput() {
|
func (m *Client) fetchOutput() {
|
||||||
defer m.done.Close()
|
defer m.done.Close()
|
||||||
|
|
||||||
|
@ -237,6 +251,8 @@ func (m *Client) fetchOutput() {
|
||||||
err = m.handleStatusNew(meta, reader)
|
err = m.handleStatusNew(meta, reader)
|
||||||
case SessionStatusKeep:
|
case SessionStatusKeep:
|
||||||
err = m.handleStatusKeep(meta, reader)
|
err = m.handleStatusKeep(meta, reader)
|
||||||
|
case SessionStatusError:
|
||||||
|
err = m.handleStatusError(meta, reader)
|
||||||
default:
|
default:
|
||||||
newError("unknown status: ", meta.SessionStatus).AtError().WriteToLog()
|
newError("unknown status: ", meta.SessionStatus).AtError().WriteToLog()
|
||||||
return
|
return
|
||||||
|
@ -294,8 +310,10 @@ func handle(ctx context.Context, s *Session, output buf.Writer) {
|
||||||
writer := NewResponseWriter(s.ID, output, s.transferType)
|
writer := NewResponseWriter(s.ID, output, s.transferType)
|
||||||
if err := buf.Copy(s.input, writer); err != nil {
|
if err := buf.Copy(s.input, writer); err != nil {
|
||||||
newError("session ", s.ID, " ends.").Base(err).WithContext(ctx).WriteToLog()
|
newError("session ", s.ID, " ends.").Base(err).WithContext(ctx).WriteToLog()
|
||||||
}
|
writer.Error()
|
||||||
|
} else {
|
||||||
writer.Close()
|
writer.Close()
|
||||||
|
}
|
||||||
s.Close()
|
s.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,6 +371,18 @@ func (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *ServerWorker) handleStatusError(meta *FrameMetadata, reader *buf.BufferedReader) error {
|
||||||
|
if s, found := w.sessionManager.Get(meta.SessionID); found {
|
||||||
|
s.input.CloseError()
|
||||||
|
s.output.CloseError()
|
||||||
|
s.Close()
|
||||||
|
}
|
||||||
|
if meta.Option.Has(OptionData) {
|
||||||
|
return drain(reader)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedReader) error {
|
func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedReader) error {
|
||||||
meta, err := ReadMetadata(reader)
|
meta, err := ReadMetadata(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -368,6 +398,8 @@ func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedRead
|
||||||
err = w.handleStatusNew(ctx, meta, reader)
|
err = w.handleStatusNew(ctx, meta, reader)
|
||||||
case SessionStatusKeep:
|
case SessionStatusKeep:
|
||||||
err = w.handleStatusKeep(meta, reader)
|
err = w.handleStatusKeep(meta, reader)
|
||||||
|
case SessionStatusError:
|
||||||
|
err = w.handleStatusError(meta, reader)
|
||||||
default:
|
default:
|
||||||
return newError("unknown status: ", meta.SessionStatus).AtError()
|
return newError("unknown status: ", meta.SessionStatus).AtError()
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,3 +112,16 @@ func (w *Writer) Close() error {
|
||||||
w.writer.WriteMultiBuffer(buf.NewMultiBufferValue(frame))
|
w.writer.WriteMultiBuffer(buf.NewMultiBufferValue(frame))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Writer) Error() error {
|
||||||
|
meta := FrameMetadata{
|
||||||
|
SessionID: w.id,
|
||||||
|
SessionStatus: SessionStatusError,
|
||||||
|
}
|
||||||
|
|
||||||
|
frame := buf.New()
|
||||||
|
common.Must(meta.WriteTo(frame))
|
||||||
|
|
||||||
|
w.writer.WriteMultiBuffer(buf.NewMultiBufferValue(frame))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue