go-socks5/statute/util.go

61 lines
1.5 KiB
Go
Raw Normal View History

2020-08-05 05:54:05 +00:00
package statute
import (
"fmt"
"net"
"strconv"
)
// AddrSpec is used to return the target AddrSpec
// which may be specified as IPv4, IPv6, or a FQDN
type AddrSpec struct {
FQDN string
IP net.IP
Port int
2020-08-05 10:10:50 +00:00
// private stuff set when Request parsed
2020-08-06 01:20:43 +00:00
AddrType byte
2020-08-05 05:54:05 +00:00
}
2020-08-05 10:10:50 +00:00
// DstAddress returns a string suitable to dial; prefer returning IP-based
2020-08-05 05:54:05 +00:00
// address, fallback to FQDN
func (a *AddrSpec) String() string {
if 0 != len(a.IP) {
return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
}
return net.JoinHostPort(a.FQDN, strconv.Itoa(a.Port))
}
2020-08-05 10:10:50 +00:00
// DstAddress returns a string which may be specified
2020-08-05 05:54:05 +00:00
// if IPv4/IPv6 will return < ip:port >
// if FQDN will return < domain ip:port >
// Note: do not used to dial, Please use String
func (a AddrSpec) Address() string {
if a.FQDN != "" {
return fmt.Sprintf("%s (%s):%d", a.FQDN, a.IP, a.Port)
}
return fmt.Sprintf("%s:%d", a.IP, a.Port)
}
// ParseAddrSpec parse address to the AddrSpec address
2020-08-06 01:20:43 +00:00
func ParseAddrSpec(address string) (as AddrSpec, err error) {
2020-08-05 05:54:05 +00:00
var host, port string
host, port, err = net.SplitHostPort(address)
if err != nil {
return
}
ip := net.ParseIP(host)
if ip4 := ip.To4(); ip4 != nil {
2020-08-06 01:20:43 +00:00
as.AddrType, as.IP = ATYPIPv4, ip
2020-08-05 05:54:05 +00:00
} else if ip6 := ip.To16(); ip6 != nil {
2020-08-06 01:20:43 +00:00
as.AddrType, as.IP = ATYPIPv6, ip
2020-08-05 05:54:05 +00:00
} else {
2020-08-06 01:20:43 +00:00
as.AddrType, as.FQDN = ATYPDomain, host
2020-08-05 05:54:05 +00:00
}
2020-08-06 01:20:43 +00:00
as.Port, err = strconv.Atoi(port)
2020-08-05 05:54:05 +00:00
return
}
2020-08-06 01:20:43 +00:00
func buildPort(hi, lo byte) int { return (int(hi) << 8) | int(lo) }
func breakPort(port int) (hi, lo byte) { return byte(port >> 8), byte(port) }