mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-10-06 17:27:05 +08:00

现在整个程序均通过了go test, main 也可以正常运行了。 Relay_UDP 函数添加流量计数; 发现之前 Relay函数的流量计数 在main.go里参数传反了,导致实际上计数的是上传而不是下载,已修复 对fullcone的情况做了特别考量。MsgConn的 Close函数在fullcone时不能随便被调用。 因此我添加了一个 CloseConnWithRaddr(raddr Addr) error 方法,以及 Fullcone() bool 方法 在utils包的init部分使用 rand 随机种子
137 lines
2.4 KiB
Go
137 lines
2.4 KiB
Go
package vless
|
||
|
||
import (
|
||
"bufio"
|
||
"io"
|
||
"net"
|
||
|
||
"github.com/hahahrfool/v2ray_simple/netLayer"
|
||
"github.com/hahahrfool/v2ray_simple/utils"
|
||
)
|
||
|
||
type UDPConn struct {
|
||
net.Conn
|
||
optionalReader io.Reader
|
||
|
||
remainFirstBufLen int
|
||
|
||
version int
|
||
isClientEnd bool
|
||
|
||
bufr *bufio.Reader
|
||
|
||
notFirst bool //for v0
|
||
raddr netLayer.Addr
|
||
}
|
||
|
||
func (u *UDPConn) CloseConnWithRaddr(raddr netLayer.Addr) error {
|
||
return u.Close()
|
||
}
|
||
func (u *UDPConn) Fullcone() bool {
|
||
return u.version != 0
|
||
}
|
||
|
||
func (u *UDPConn) WriteTo(p []byte, raddr netLayer.Addr) error {
|
||
|
||
//v0很垃圾,不支持fullcone,无视raddr,始终向最开始的raddr发送。
|
||
if u.version == 0 {
|
||
writeBuf := utils.GetBuf()
|
||
|
||
if !u.isClientEnd && !u.notFirst {
|
||
u.notFirst = true
|
||
|
||
//v0 中,服务端的回复的第一个包也是要有数据头的(和客户端的handshake类似,只是第一个包有),第一字节版本,第二字节addon长度(都是0)
|
||
|
||
writeBuf.WriteByte(0)
|
||
writeBuf.WriteByte(0)
|
||
|
||
}
|
||
|
||
l := int16(len(p))
|
||
|
||
writeBuf.WriteByte(byte(l >> 8))
|
||
writeBuf.WriteByte(byte(l << 8 >> 8))
|
||
|
||
writeBuf.Write(p)
|
||
|
||
_, err := u.Conn.Write(writeBuf.Bytes()) //“直接return这个的长度” 是错的,因为写入长度只能小于等于len(p)
|
||
|
||
utils.PutBuf(writeBuf)
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
|
||
} else {
|
||
|
||
}
|
||
return nil
|
||
|
||
}
|
||
|
||
//从 客户端读取 udp请求
|
||
func (u *UDPConn) ReadFrom() ([]byte, netLayer.Addr, error) {
|
||
|
||
var from io.Reader = u.Conn
|
||
if u.optionalReader != nil {
|
||
from = u.optionalReader
|
||
}
|
||
|
||
if u.version == 0 {
|
||
|
||
if u.isClientEnd {
|
||
if !u.notFirst {
|
||
u.notFirst = true
|
||
u.bufr = bufio.NewReader(from)
|
||
|
||
_, err := u.bufr.ReadByte() //version byte
|
||
if err != nil {
|
||
return nil, netLayer.Addr{}, err
|
||
}
|
||
|
||
_, err = u.bufr.ReadByte() //addon len byte
|
||
if err != nil {
|
||
return nil, netLayer.Addr{}, err
|
||
}
|
||
|
||
}
|
||
|
||
} else {
|
||
if u.bufr == nil {
|
||
u.bufr = bufio.NewReader(from)
|
||
|
||
}
|
||
}
|
||
bs, err := u.read_with_v0_Head()
|
||
return bs, u.raddr, err
|
||
} else {
|
||
|
||
}
|
||
return nil, netLayer.Addr{}, nil
|
||
}
|
||
|
||
func (uc *UDPConn) read_with_v0_Head() ([]byte, error) {
|
||
|
||
b1, err := uc.bufr.ReadByte()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
b2, err := uc.bufr.ReadByte()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
l := int(int16(b1)<<8 + int16(b2))
|
||
|
||
bs := utils.GetBytes(l)
|
||
n, err := io.ReadFull(uc.bufr, bs)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return bs[:n], nil
|
||
|
||
}
|