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:
parent
e392f8ed3d
commit
3340f81d03
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user