mirror of
https://github.com/xiaoqidun/probe.git
synced 2026-02-11 10:25:30 +08:00
Compare commits
3 Commits
2d44a5d5b8
...
1d6d419f86
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d6d419f86 | |||
| 2be0a4a40b | |||
| 1c2dea15f9 |
@@ -52,7 +52,7 @@ func main() {
|
|||||||
var err error
|
var err error
|
||||||
if s5 != "" {
|
if s5 != "" {
|
||||||
fmt.Printf("通过代理探测: %s\n", s5)
|
fmt.Printf("通过代理探测: %s\n", s5)
|
||||||
conn, err = DialSocks5UDP(s5)
|
conn, err = DialSocks5UDP(s5, network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("连接代理失败: %v\n", err)
|
fmt.Printf("连接代理失败: %v\n", err)
|
||||||
return
|
return
|
||||||
|
|||||||
+15
-2
@@ -103,7 +103,9 @@ func performTest(conn net.PacketConn, serverAddr string, network string, timeout
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
txID := [12]byte{}
|
txID := [12]byte{}
|
||||||
rand.Read(txID[:])
|
if _, err := rand.Read(txID[:]); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
req := encodeSTUNRequest(txID, changeIP, changePort)
|
req := encodeSTUNRequest(txID, changeIP, changePort)
|
||||||
if _, err := conn.WriteTo(req, dst); err != nil {
|
if _, err := conn.WriteTo(req, dst); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -147,6 +149,14 @@ func DetectNAT(conn net.PacketConn, primarySTUN, secondarySTUN, network string,
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
res.MappedIP = mappedAddr1.String()
|
res.MappedIP = mappedAddr1.String()
|
||||||
|
if localAddr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
|
||||||
|
if localAddr.IP.Equal(mappedAddr1.IP) && localAddr.Port == mappedAddr1.Port {
|
||||||
|
res.Type = NATOpen
|
||||||
|
res.Mapping = MappingEndpointIndependent
|
||||||
|
res.Filtering = FilteringEndpointIndependent
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
var targetSTUN2 string
|
var targetSTUN2 string
|
||||||
if secondarySTUN != "" {
|
if secondarySTUN != "" {
|
||||||
targetSTUN2 = secondarySTUN
|
targetSTUN2 = secondarySTUN
|
||||||
@@ -158,7 +168,10 @@ func DetectNAT(conn net.PacketConn, primarySTUN, secondarySTUN, network string,
|
|||||||
host, port, _ := net.SplitHostPort(primarySTUN)
|
host, port, _ := net.SplitHostPort(primarySTUN)
|
||||||
ips, err := net.LookupIP(host)
|
ips, err := net.LookupIP(host)
|
||||||
if err == nil && len(ips) > 1 {
|
if err == nil && len(ips) > 1 {
|
||||||
primaryIP, _ := net.ResolveIPAddr("ip", host)
|
primaryIP, err := net.ResolveIPAddr("ip", host)
|
||||||
|
if err != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
wantIPv4 := network == "udp4"
|
wantIPv4 := network == "udp4"
|
||||||
wantIPv6 := network == "udp6"
|
wantIPv6 := network == "udp6"
|
||||||
if network == "udp" {
|
if network == "udp" {
|
||||||
|
|||||||
+20
-7
@@ -58,7 +58,7 @@ func (c *socks5PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
if n < 10 {
|
if n < 10 {
|
||||||
return 0, nil, nil
|
return 0, nil, errors.New("packet too short")
|
||||||
}
|
}
|
||||||
atyp := buf[3]
|
atyp := buf[3]
|
||||||
var rAddr *net.UDPAddr
|
var rAddr *net.UDPAddr
|
||||||
@@ -93,6 +93,8 @@ func (c *socks5PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||||||
port := binary.BigEndian.Uint16(buf[20:22])
|
port := binary.BigEndian.Uint16(buf[20:22])
|
||||||
rAddr = &net.UDPAddr{IP: ip, Port: int(port)}
|
rAddr = &net.UDPAddr{IP: ip, Port: int(port)}
|
||||||
dataOffset = 22
|
dataOffset = 22
|
||||||
|
default:
|
||||||
|
return 0, nil, fmt.Errorf("unknown address type: 0x%x", atyp)
|
||||||
}
|
}
|
||||||
copy(p, buf[dataOffset:n])
|
copy(p, buf[dataOffset:n])
|
||||||
return n - dataOffset, rAddr, nil
|
return n - dataOffset, rAddr, nil
|
||||||
@@ -142,8 +144,12 @@ func (c *socks5PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
|||||||
// Close 关闭连接
|
// Close 关闭连接
|
||||||
// 返回: err 关闭错误
|
// 返回: err 关闭错误
|
||||||
func (c *socks5PacketConn) Close() error {
|
func (c *socks5PacketConn) Close() error {
|
||||||
c.tcpConn.Close()
|
err1 := c.tcpConn.Close()
|
||||||
return c.udpConn.Close()
|
err2 := c.udpConn.Close()
|
||||||
|
if err1 != nil {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalAddr 获取本地地址
|
// LocalAddr 获取本地地址
|
||||||
@@ -174,9 +180,9 @@ func (c *socks5PacketConn) SetWriteDeadline(t time.Time) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DialSocks5UDP 建立SOCKS5 UDP关联
|
// DialSocks5UDP 建立SOCKS5 UDP关联
|
||||||
// 入参: proxyAddr 代理服务器地址
|
// 入参: proxyAddr 代理服务器地址, network 网络协议(udp/udp4/udp6)
|
||||||
// 返回: conn 数据包连接, err 连接错误
|
// 返回: conn 数据包连接, err 连接错误
|
||||||
func DialSocks5UDP(proxyAddr string) (net.PacketConn, error) {
|
func DialSocks5UDP(proxyAddr, network string) (net.PacketConn, error) {
|
||||||
var host string
|
var host string
|
||||||
if strings.Contains(proxyAddr, "://") {
|
if strings.Contains(proxyAddr, "://") {
|
||||||
u, err := url.Parse(proxyAddr)
|
u, err := url.Parse(proxyAddr)
|
||||||
@@ -187,7 +193,14 @@ func DialSocks5UDP(proxyAddr string) (net.PacketConn, error) {
|
|||||||
} else {
|
} else {
|
||||||
host = proxyAddr
|
host = proxyAddr
|
||||||
}
|
}
|
||||||
conn, err := net.DialTimeout("tcp", host, 5*time.Second)
|
tcpNetwork := "tcp"
|
||||||
|
switch network {
|
||||||
|
case "udp4":
|
||||||
|
tcpNetwork = "tcp4"
|
||||||
|
case "udp6":
|
||||||
|
tcpNetwork = "tcp6"
|
||||||
|
}
|
||||||
|
conn, err := net.DialTimeout(tcpNetwork, host, 5*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -266,7 +279,7 @@ func DialSocks5UDP(proxyAddr string) (net.PacketConn, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
relayAddr := &net.UDPAddr{IP: relayIP, Port: relayPort}
|
relayAddr := &net.UDPAddr{IP: relayIP, Port: relayPort}
|
||||||
lConn, err := net.ListenUDP("udp", nil)
|
lConn, err := net.ListenUDP(network, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
+14
-11
@@ -136,9 +136,9 @@ func decodeSTUNResponse(data []byte, txID [12]byte) (*stunMessage, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseAddress 解析STUN属性中的地址信息
|
// parseAddress 解析STUN属性中的地址信息
|
||||||
// 入参: attrType 属性类型, data 属性值数据
|
// 入参: attrType 属性类型, data 属性值数据, txID 事务ID用于XOR解码
|
||||||
// 返回: addr 解析出的UDP地址, err 解析错误信息
|
// 返回: addr 解析出的UDP地址, err 解析错误信息
|
||||||
func parseAddress(attrType uint16, data []byte) (*net.UDPAddr, error) {
|
func parseAddress(attrType uint16, data []byte, txID [12]byte) (*net.UDPAddr, error) {
|
||||||
if len(data) < 4 {
|
if len(data) < 4 {
|
||||||
return nil, errors.New("attribute too short")
|
return nil, errors.New("attribute too short")
|
||||||
}
|
}
|
||||||
@@ -157,11 +157,14 @@ func parseAddress(attrType uint16, data []byte) (*net.UDPAddr, error) {
|
|||||||
copy(ip, data[4:4+ipLen])
|
copy(ip, data[4:4+ipLen])
|
||||||
if attrType == attrXorMappedAddress {
|
if attrType == attrXorMappedAddress {
|
||||||
port ^= uint16(stunMagicCookie >> 16)
|
port ^= uint16(stunMagicCookie >> 16)
|
||||||
if ipLen == 4 {
|
mc := make([]byte, 4)
|
||||||
mc := make([]byte, 4)
|
binary.BigEndian.PutUint32(mc, stunMagicCookie)
|
||||||
binary.BigEndian.PutUint32(mc, stunMagicCookie)
|
for i := 0; i < 4; i++ {
|
||||||
for i := 0; i < 4; i++ {
|
ip[i] ^= mc[i]
|
||||||
ip[i] ^= mc[i]
|
}
|
||||||
|
if ipLen == 16 {
|
||||||
|
for i := 4; i < 16; i++ {
|
||||||
|
ip[i] ^= txID[i-4]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,14 +176,14 @@ func parseAddress(attrType uint16, data []byte) (*net.UDPAddr, error) {
|
|||||||
func (m *stunMessage) GetMappedAddress() *net.UDPAddr {
|
func (m *stunMessage) GetMappedAddress() *net.UDPAddr {
|
||||||
for _, attr := range m.Attributes {
|
for _, attr := range m.Attributes {
|
||||||
if attr.Type == attrXorMappedAddress {
|
if attr.Type == attrXorMappedAddress {
|
||||||
if addr, err := parseAddress(attr.Type, attr.Value); err == nil {
|
if addr, err := parseAddress(attr.Type, attr.Value, m.Header.ID); err == nil {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, attr := range m.Attributes {
|
for _, attr := range m.Attributes {
|
||||||
if attr.Type == attrMappedAddress {
|
if attr.Type == attrMappedAddress {
|
||||||
if addr, err := parseAddress(attr.Type, attr.Value); err == nil {
|
if addr, err := parseAddress(attr.Type, attr.Value, m.Header.ID); err == nil {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,14 +196,14 @@ func (m *stunMessage) GetMappedAddress() *net.UDPAddr {
|
|||||||
func (m *stunMessage) GetChangedAddress() *net.UDPAddr {
|
func (m *stunMessage) GetChangedAddress() *net.UDPAddr {
|
||||||
for _, attr := range m.Attributes {
|
for _, attr := range m.Attributes {
|
||||||
if attr.Type == attrChangedAddress {
|
if attr.Type == attrChangedAddress {
|
||||||
if addr, err := parseAddress(attr.Type, attr.Value); err == nil {
|
if addr, err := parseAddress(attr.Type, attr.Value, m.Header.ID); err == nil {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, attr := range m.Attributes {
|
for _, attr := range m.Attributes {
|
||||||
if attr.Type == attrOtherAddress {
|
if attr.Type == attrOtherAddress {
|
||||||
if addr, err := parseAddress(attr.Type, attr.Value); err == nil {
|
if addr, err := parseAddress(attr.Type, attr.Value, m.Header.ID); err == nil {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user