Files
v2ray_simple/proxy/vless/udpConn.go

198 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package vless
import (
"bufio"
"bytes"
"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
udp_multi bool
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) WriteMsgTo(p []byte, raddr netLayer.Addr) error {
writeBuf := utils.GetBuf()
defer utils.PutBuf(writeBuf)
//v0很垃圾不支持fullcone而是无视raddr始终向最开始的raddr发送。
if u.version == 0 {
if !u.isClientEnd && !u.notFirst {
u.notFirst = true
//v0 中,服务端的回复的第一个包也是要有数据头的(和客户端的handshake类似只是第一个包有)第一字节版本第二字节addon长度都是0
writeBuf.WriteByte(0)
writeBuf.WriteByte(0)
}
return u.writeDataTo(writeBuf, p)
} else { // v1
if u.udp_multi {
if u.isClientEnd {
//如果是客户端则不存在raddr与初始地址不同的情况因为这种情况已经在 netLayer.RelayUDP_separate 里过滤掉了
return u.writeDataTo(writeBuf, p)
} else {
//判断raddr是否与 u.raddr相同, 如果不相同, 则要传输umfurs信息
// umfurs信息将会提示客户端 下一次发送到此地址时,拨号一个新的 udp信道.
if u.raddr.GetHashable() == raddr.GetHashable() {
writeBuf.WriteByte(0)
return u.writeDataTo(writeBuf, p)
} else {
writeBuf.WriteByte(1)
WriteAddrTo(writeBuf, raddr)
return u.writeDataTo(writeBuf, p)
}
}
} else {
WriteAddrTo(writeBuf, raddr)
return u.writeDataTo(writeBuf, p)
}
}
//return nil
}
func (uc *UDPConn) readData_with_len() ([]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
}
func (u *UDPConn) writeDataTo(writeBuf *bytes.Buffer, p []byte) error {
writeBuf.WriteByte(byte(len(p) >> 8))
writeBuf.WriteByte(byte(len(p) << 8 >> 8))
_, err := u.Conn.Write(writeBuf.Bytes())
if err != nil {
return err
} else {
_, err := u.Conn.Write(p)
return err
}
}
func (u *UDPConn) ReadMsgFrom() ([]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.readData_with_len()
return bs, u.raddr, err
} else {
if u.bufr == nil {
u.bufr = bufio.NewReader(from)
}
if u.udp_multi {
if u.isClientEnd {
//判断是否是 umfurs信息
// umfurs信息将会提示客户端 下一次发送到此地址时,拨号一个新的 udp信道.
b1, err := u.bufr.ReadByte()
if err != nil {
return nil, netLayer.Addr{}, err
}
switch b1 {
default:
return nil, netLayer.Addr{}, utils.ErrInErr{ErrDesc: "udp_multi client read first byte unexpected", ErrDetail: utils.ErrInvalidData, Data: b1}
case 0:
bs, err := u.readData_with_len()
return bs, u.raddr, err
case 1:
raddr, err := GetAddrFrom(u.bufr)
bs, err := u.readData_with_len()
return bs, raddr, err
}
} else {
bs, err := u.readData_with_len()
return bs, u.raddr, err
}
} else {
raddr, err := GetAddrFrom(u.bufr)
bs, err := u.readData_with_len()
return bs, raddr, err
}
}
//return nil, netLayer.Addr{}, nil
}