Files
v2ray_simple/proxy/addr.go
hahahrfool 009162cf40 first
2022-03-09 21:27:13 +08:00

155 lines
2.7 KiB
Go

package proxy
import (
"net"
"strconv"
)
// Addr represents a address that you want to access by proxy. Either Name or IP is used exclusively.
type Addr struct {
Name string // domain name
IP net.IP
Port int
IsUDP bool
}
func NewAddrFromUDPAddr(addr *net.UDPAddr) *Addr {
return &Addr{
IP: addr.IP,
Port: addr.Port,
IsUDP: true,
}
}
func NewAddr(addrStr string) (*Addr, error) {
host, portStr, err := net.SplitHostPort(addrStr)
if err != nil {
return nil, err
}
if host == "" {
host = "127.0.0.1"
}
port, err := strconv.Atoi(portStr)
a := &Addr{Port: port}
if ip := net.ParseIP(host); ip != nil {
a.IP = ip
} else {
a.Name = host
}
return a, nil
}
// Return host:port string
func (a *Addr) String() string {
port := strconv.Itoa(a.Port)
if a.IP == nil {
return net.JoinHostPort(a.Name, port)
}
return net.JoinHostPort(a.IP.String(), port)
}
func (a *Addr) UrlString() string {
str := a.String()
if a.IsUDP {
return "udp://" + str
}
return "tcp://" + str
}
func (a *Addr) ToUDPAddr() *net.UDPAddr {
if !a.IsUDP {
return nil
}
ua, err := net.ResolveUDPAddr("udp", a.String())
if err != nil {
return nil
}
return ua
}
// Returned host string
func (a *Addr) HostStr() string {
if a.IP == nil {
return a.Name
}
return a.IP.String()
}
func (addr *Addr) Dial() (net.Conn, error) {
if addr.IsUDP {
return net.Dial("udp", addr.String())
}
return net.Dial("tcp", addr.String())
}
// Returned address bytes and type
func (a *Addr) AddressBytes() ([]byte, byte) {
var addr []byte
var atyp byte
if a.IP != nil {
if ip4 := a.IP.To4(); ip4 != nil {
addr = make([]byte, net.IPv4len)
atyp = AtypIP4
copy(addr[:], ip4)
} else {
addr = make([]byte, net.IPv6len)
atyp = AtypIP6
copy(addr[:], a.IP)
}
} else {
if len(a.Name) > 255 {
return nil, 0
}
addr = make([]byte, 1+len(a.Name))
atyp = AtypDomain
addr[0] = byte(len(a.Name))
copy(addr[1:], a.Name)
}
return addr, atyp
}
// ParseAddr parses the address in string s
func ParseStrToAddr(s string) (atyp byte, addr []byte, port_uint16 uint16, err error) {
var host string
var portStr string
host, portStr, err = net.SplitHostPort(s)
if err != nil {
return
}
if ip := net.ParseIP(host); ip != nil {
if ip4 := ip.To4(); ip4 != nil {
addr = make([]byte, net.IPv4len)
atyp = AtypIP4
copy(addr[:], ip4)
} else {
addr = make([]byte, net.IPv6len)
atyp = AtypIP6
copy(addr[:], ip)
}
} else {
if len(host) > 255 {
return
}
addr = make([]byte, 1+len(host))
atyp = AtypDomain
addr[0] = byte(len(host))
copy(addr[1:], host)
}
var portUint64 uint64
portUint64, err = strconv.ParseUint(portStr, 10, 16)
if err != nil {
return
}
port_uint16 = uint16(portUint64)
return
}