1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-02 15:36:41 -05:00

fix reader/writer for packet conn

This commit is contained in:
Darien Raymond 2018-12-03 14:20:57 +01:00
parent e392f8ed3d
commit 3340f81d03
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
2 changed files with 56 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package buf
import ( import (
"io" "io"
"net"
"syscall" "syscall"
"time" "time"
) )
@ -38,6 +39,11 @@ func WriteAllBytes(writer io.Writer, payload []byte) error {
return nil return nil
} }
func isPacketReader(reader io.Reader) bool {
_, ok := reader.(net.PacketConn)
return ok
}
// NewReader creates a new Reader. // NewReader creates a new Reader.
// The Reader instance doesn't take the ownership of reader. // The Reader instance doesn't take the ownership of reader.
func NewReader(reader io.Reader) Reader { func NewReader(reader io.Reader) Reader {
@ -45,6 +51,12 @@ func NewReader(reader io.Reader) Reader {
return mr return mr
} }
if isPacketReader(reader) {
return &PacketReader{
Reader: reader,
}
}
if useReadv { if useReadv {
if sc, ok := reader.(syscall.Conn); ok { if sc, ok := reader.(syscall.Conn); ok {
rawConn, err := sc.SyscallConn() rawConn, err := sc.SyscallConn()
@ -61,14 +73,25 @@ func NewReader(reader io.Reader) Reader {
} }
} }
func isPacketWriter(writer io.Writer) bool {
if _, ok := writer.(net.PacketConn); ok {
return true
}
// If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.
if _, ok := writer.(syscall.Conn); !ok {
return true
}
return false
}
// NewWriter creates a new Writer. // NewWriter creates a new Writer.
func NewWriter(writer io.Writer) Writer { func NewWriter(writer io.Writer) Writer {
if mw, ok := writer.(Writer); ok { if mw, ok := writer.(Writer); ok {
return mw return mw
} }
if _, ok := writer.(syscall.Conn); !ok { if isPacketWriter(writer) {
// If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.
return &SequentialWriter{ return &SequentialWriter{
Writer: writer, Writer: writer,
} }

View File

@ -7,6 +7,23 @@ import (
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
) )
func readOneUDP(r io.Reader) (*Buffer, error) {
b := New()
for i := 0; i < 64; i++ {
_, err := b.ReadFrom(r)
if !b.IsEmpty() {
return b, nil
}
if err != nil {
b.Release()
return nil, err
}
}
b.Release()
return nil, newError("Reader returns too many empty payloads.")
}
func readOne(r io.Reader) (*Buffer, error) { func readOne(r io.Reader) (*Buffer, error) {
// Use an one-byte buffer to wait for incoming payload. // Use an one-byte buffer to wait for incoming payload.
var firstByte [1]byte var firstByte [1]byte
@ -152,3 +169,17 @@ func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
} }
return MultiBuffer{b}, nil return MultiBuffer{b}, nil
} }
// PacketReader is a Reader that read one Buffer every time.
type PacketReader struct {
io.Reader
}
// ReadMultiBuffer implements Reader.
func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {
b, err := readOneUDP(r.Reader)
if err != nil {
return nil, err
}
return MultiBuffer{b}, nil
}