Files
v2ray_simple/proxy/socks5/udp_test.go
hahahrfool ce735dbb99 修订udp代码; dial配置 添加 fullcone 选项;默认为非fullcone
现在整个程序均通过了go test, main 也可以正常运行了。

Relay_UDP 函数添加流量计数;

发现之前 Relay函数的流量计数 在main.go里参数传反了,导致实际上计数的是上传而不是下载,已修复

对fullcone的情况做了特别考量。MsgConn的 Close函数在fullcone时不能随便被调用。

因此我添加了一个 CloseConnWithRaddr(raddr Addr) error  方法,以及 Fullcone() bool     方法

在utils包的init部分使用 rand 随机种子
2022-04-08 20:31:59 +08:00

167 lines
3.8 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 socks5_test
import (
"net"
"strconv"
"strings"
"testing"
"github.com/hahahrfool/v2ray_simple/netLayer"
"github.com/hahahrfool/v2ray_simple/proxy/direct"
"github.com/hahahrfool/v2ray_simple/proxy/socks5"
)
//tcp就不测了我们实践直接测试完全好使这里重点测试UDP
// 因为chrome也是无法通过 socks5去申请udp链接的所以没法自己用浏览器测试
//下面的部分代码在 main.go 中也有用到.
func TestUDP(t *testing.T) {
s := &socks5.Server{}
//建立socks5服务并监听这里仅用于 udp associate 握手
sAddrStr := netLayer.GetRandLocalAddr()
listener, err := net.Listen("tcp", sAddrStr)
if err != nil {
t.Log("can not listen on", sAddrStr, err)
t.FailNow()
}
direct := &direct.Client{}
go func() {
for {
lc, err := listener.Accept()
if err != nil {
t.Logf("failed in accept: %v", err)
t.Fail()
}
t.Log("socks5 server got new conn")
_, wlc, targetAddr, err := s.Handshake(lc)
if targetAddr.IsUDP() {
t.Log("socks5 server got udp associate")
}
//此时wlc返回的是socks5新监听的 conn
go func() {
for {
t.Log("socks5 server start read udp channel")
bs, addr, err := wlc.ReadFrom()
if err != nil {
t.Log("socks5 server read udp channel err,", err)
break
}
t.Log("socks5 server got udp msg")
msgConn, err := direct.EstablishUDPChannel(nil, addr)
if err != nil {
t.Fail()
return
}
err = msgConn.WriteTo(bs, addr)
if err != nil {
t.Log("socks5 server Write To direct failed,", len(bs), err)
}
go func() {
for {
rbs, raddr, err := msgConn.ReadFrom()
if err != nil {
break
}
wlc.WriteTo(rbs, raddr)
}
}()
}
}()
}
}()
//建立虚拟目标udp服务器并监听
fakeUDP_ServerPort := netLayer.RandPort()
fakeRealUDPServerListener, err := net.ListenUDP("udp4", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: fakeUDP_ServerPort,
})
if err != nil {
t.Log("监听失败 udp ", err)
t.FailNow()
}
defer fakeRealUDPServerListener.Close()
go func() {
readbuf := make([]byte, 10*1024)
for {
t.Log(" udp for! ")
// 读取数据, 无视任何信息,直接返回 "reply"
n, remoteAddr, err := fakeRealUDPServerListener.ReadFromUDP(readbuf)
if err != nil {
if strings.Contains(err.Error(), "use of closed network connection") {
t.Log("udp server read connection closed")
return
} else {
t.Log("udp server 读取数据失败!", err)
}
//continue
break
}
t.Log("fake udp server got", remoteAddr, string(readbuf[:n]))
_, err = fakeRealUDPServerListener.WriteToUDP([]byte("reply"), remoteAddr)
if err != nil {
t.Log("udp write back err:", err)
t.Fail()
return
}
t.Log("fake udp server written")
}
}()
//尝试客户端 UDPAssociate 发起请求
rc, _ := net.Dial("tcp", sAddrStr)
defer rc.Close()
socks5_ServerPort, err := socks5.Client_EstablishUDPAssociate(rc)
if err != nil {
t.Log("Client_EstablishUDPAssociate failed", err)
t.FailNow()
}
t.Log("Server Port", socks5_ServerPort)
//获知 服务器udp端口后再向该端口发起请求
raSocks5, _ := netLayer.NewAddr("127.0.0.1:" + strconv.Itoa(socks5_ServerPort))
raSocks5UDPAddr := raSocks5.ToUDPAddr()
urc, err := net.DialUDP("udp", nil, raSocks5UDPAddr)
if err != nil {
t.Log("DialUDP failed", raSocks5UDPAddr)
t.FailNow()
}
defer urc.Close()
raFake, _ := netLayer.NewAddr("127.0.0.1:" + strconv.Itoa(fakeUDP_ServerPort))
t.Log("call Client_RequestUDP")
socks5.Client_RequestUDP(urc, &raFake, []byte("hello"))
t.Log("call Client_ReadUDPResponse")
ta, data, err := socks5.Client_ReadUDPResponse(urc, raSocks5UDPAddr)
if err != nil {
t.Log("Client_ReadUDPResponse failed", err)
t.FailNow()
}
t.Log(ta, string(data))
}