From c6f3ab48ee12a1fb2071c70179a2de8e7fa169ee Mon Sep 17 00:00:00 2001 From: Kslr Date: Sat, 18 May 2019 15:09:58 +0800 Subject: [PATCH] fixed ReadV issue for windows sync https://github.com/v2fly/v2ray-core/commit/847b289798eca6ec90b3733288a27887c7427522 --- common/buf/io.go | 7 ++++- common/buf/readv_constraint_other.go | 9 +++++++ common/buf/readv_constraint_windows.go | 37 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 common/buf/readv_constraint_other.go create mode 100644 common/buf/readv_constraint_windows.go diff --git a/common/buf/io.go b/common/buf/io.go index 938e347b..c13a35aa 100644 --- a/common/buf/io.go +++ b/common/buf/io.go @@ -63,7 +63,12 @@ func NewReader(reader io.Reader) Reader { if err != nil { newError("failed to get sysconn").Base(err).WriteToLog() } else { - return NewReadVReader(reader, rawConn) + /* Check if ReadVReader Can be used on this reader first + Fix https://github.com/v2ray/v2ray-core/issues/1666 + */ + if ok, _ := checkReadVConstraint(rawConn); ok { + return NewReadVReader(reader, rawConn) + } } } } diff --git a/common/buf/readv_constraint_other.go b/common/buf/readv_constraint_other.go new file mode 100644 index 00000000..315ce61f --- /dev/null +++ b/common/buf/readv_constraint_other.go @@ -0,0 +1,9 @@ +// +build !windows + +package buf + +import "syscall" + +func checkReadVConstraint(conn syscall.RawConn) (bool, error) { + return true, nil +} diff --git a/common/buf/readv_constraint_windows.go b/common/buf/readv_constraint_windows.go new file mode 100644 index 00000000..d78cbaa8 --- /dev/null +++ b/common/buf/readv_constraint_windows.go @@ -0,0 +1,37 @@ +// +build windows +package buf + +import ( + "syscall" +) + +func checkReadVConstraint(conn syscall.RawConn) (bool, error) { + var isSocketReady = false + var reason error + /* + In Windows, WSARecv system call only support socket connection. + + It it required to check if the given fd is of a socket type + + Fix https://github.com/v2ray/v2ray-core/issues/1666 + + Additional Information: + https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsarecv + https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-getsockopt + https://docs.microsoft.com/en-us/windows/desktop/WinSock/sol-socket-socket-options + + */ + err := conn.Control(func(fd uintptr) { + var val [4]byte + var le = int32(len(val)) + err := syscall.Getsockopt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, &val[0], &le) + if err != nil { + isSocketReady = false + } else { + isSocketReady = true + } + reason = err + }) + + return isSocketReady, err +}