1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
package socks5
import (
"bytes"
"encoding/binary"
"errors"
"net"
"strconv"
)
// ParseAddress format address x.x.x.x:xx to raw address.
// addr contains domain length
func ParseAddress(address string) (a byte, addr []byte, port []byte, err error) {
var h, p string
h, p, err = net.SplitHostPort(address)
if err != nil {
return
}
ip := net.ParseIP(h)
if ip4 := ip.To4(); ip4 != nil {
a = ATYPIPv4
addr = []byte(ip4)
} else if ip6 := ip.To16(); ip6 != nil {
a = ATYPIPv6
addr = []byte(ip6)
} else {
a = ATYPDomain
addr = []byte{byte(len(h))}
addr = append(addr, []byte(h)...)
}
i, _ := strconv.Atoi(p)
port = make([]byte, 2)
binary.BigEndian.PutUint16(port, uint16(i))
return
}
// bytes to address
// addr contains domain length
func ParseBytesAddress(b []byte) (a byte, addr []byte, port []byte, err error) {
if len(b) < 1 {
err = errors.New("Invalid address")
return
}
a = b[0]
if a == ATYPIPv4 {
if len(b) < 1+4+2 {
err = errors.New("Invalid address")
return
}
addr = b[1 : 1+4]
port = b[1+4 : 1+4+2]
return
}
if a == ATYPIPv6 {
if len(b) < 1+16+2 {
err = errors.New("Invalid address")
return
}
addr = b[1 : 1+16]
port = b[1+16 : 1+16+2]
return
}
if a == ATYPDomain {
if len(b) < 1+1 {
err = errors.New("Invalid address")
return
}
l := int(b[1])
if len(b) < 1+1+l+2 {
err = errors.New("Invalid address")
return
}
addr = b[1 : 1+1+l]
port = b[1+1+l : 1+1+l+2]
return
}
err = errors.New("Invalid address")
return
}
// ToAddress format raw address to x.x.x.x:xx
// addr contains domain length
func ToAddress(a byte, addr []byte, port []byte) string {
var h, p string
if a == ATYPIPv4 || a == ATYPIPv6 {
h = net.IP(addr).String()
}
if a == ATYPDomain {
if len(addr) < 1 {
return ""
}
if len(addr) < int(addr[0])+1 {
return ""
}
h = string(addr[1:])
}
p = strconv.Itoa(int(binary.BigEndian.Uint16(port)))
return net.JoinHostPort(h, p)
}
// Address return request address like ip:xx
func (r *Request) Address() string {
var s string
if r.Atyp == ATYPDomain {
s = bytes.NewBuffer(r.DstAddr[1:]).String()
} else {
s = net.IP(r.DstAddr).String()
}
p := strconv.Itoa(int(binary.BigEndian.Uint16(r.DstPort)))
return net.JoinHostPort(s, p)
}
// Address return request address like ip:xx
func (r *Reply) Address() string {
var s string
if r.Atyp == ATYPDomain {
s = bytes.NewBuffer(r.BndAddr[1:]).String()
} else {
s = net.IP(r.BndAddr).String()
}
p := strconv.Itoa(int(binary.BigEndian.Uint16(r.BndPort)))
return net.JoinHostPort(s, p)
}
// Address return datagram address like ip:xx
func (d *Datagram) Address() string {
var s string
if d.Atyp == ATYPDomain {
s = bytes.NewBuffer(d.DstAddr[1:]).String()
} else {
s = net.IP(d.DstAddr).String()
}
p := strconv.Itoa(int(binary.BigEndian.Uint16(d.DstPort)))
return net.JoinHostPort(s, p)
}
|