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-06 02:12:46 +00:00
|
|
|
// String returns a string suitable to dial; prefer returning IP-based
|
2020-08-05 05:54:05 +00:00
|
|
|
// address, fallback to FQDN
|
2020-08-07 00:38:36 +00:00
|
|
|
func (sf *AddrSpec) String() string {
|
2020-08-30 03:15:05 +00:00
|
|
|
if len(sf.IP) != 0 {
|
2020-08-07 00:38:36 +00:00
|
|
|
return net.JoinHostPort(sf.IP.String(), strconv.Itoa(sf.Port))
|
2020-08-05 05:54:05 +00:00
|
|
|
}
|
2020-08-07 00:38:36 +00:00
|
|
|
return net.JoinHostPort(sf.FQDN, strconv.Itoa(sf.Port))
|
2020-08-05 05:54:05 +00:00
|
|
|
}
|
|
|
|
|
2020-08-06 02:12:46 +00:00
|
|
|
// Address 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
|
2020-08-07 00:38:36 +00:00
|
|
|
func (sf AddrSpec) Address() string {
|
|
|
|
if sf.FQDN != "" {
|
|
|
|
return fmt.Sprintf("%s (%s):%d", sf.FQDN, sf.IP, sf.Port)
|
2020-08-05 05:54:05 +00:00
|
|
|
}
|
2020-08-07 00:38:36 +00:00
|
|
|
return fmt.Sprintf("%s:%d", sf.IP, sf.Port)
|
2020-08-05 05:54:05 +00:00
|
|
|
}
|
|
|
|
|
2020-08-30 03:15:05 +00:00
|
|
|
// ParseAddrSpec parse addr(host:port) to the AddrSpec address
|
|
|
|
func ParseAddrSpec(addr string) (as AddrSpec, err error) {
|
2020-08-05 05:54:05 +00:00
|
|
|
var host, port string
|
|
|
|
|
2020-08-30 03:15:05 +00:00
|
|
|
host, port, err = net.SplitHostPort(addr)
|
2020-08-05 05:54:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2020-08-10 00:34:34 +00:00
|
|
|
as.Port, err = strconv.Atoi(port)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-08-05 05:54:05 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|