mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 04:27:39 +03:00
86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
package udphop
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var ErrInvalidPort = errors.New("invalid port")
|
|
|
|
// UDPHopAddr contains an IP address and a list of ports.
|
|
type UDPHopAddr struct {
|
|
IP net.IP
|
|
Ports []uint16
|
|
PortStr string
|
|
}
|
|
|
|
func (a *UDPHopAddr) Network() string {
|
|
return "udphop"
|
|
}
|
|
|
|
func (a *UDPHopAddr) String() string {
|
|
return net.JoinHostPort(a.IP.String(), a.PortStr)
|
|
}
|
|
|
|
// addrs returns a list of net.Addr's, one for each port.
|
|
func (a *UDPHopAddr) addrs() ([]net.Addr, error) {
|
|
var addrs []net.Addr
|
|
for _, port := range a.Ports {
|
|
addr := &net.UDPAddr{
|
|
IP: a.IP,
|
|
Port: int(port),
|
|
}
|
|
addrs = append(addrs, addr)
|
|
}
|
|
return addrs, nil
|
|
}
|
|
|
|
func ResolveUDPHopAddr(addr string) (*UDPHopAddr, error) {
|
|
host, portStr, err := net.SplitHostPort(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ip, err := net.ResolveIPAddr("ip", host)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := &UDPHopAddr{
|
|
IP: ip.IP,
|
|
PortStr: portStr,
|
|
}
|
|
|
|
portStrs := strings.Split(portStr, ",")
|
|
for _, portStr := range portStrs {
|
|
if strings.Contains(portStr, "-") {
|
|
// Port range
|
|
portRange := strings.Split(portStr, "-")
|
|
if len(portRange) != 2 {
|
|
return nil, ErrInvalidPort
|
|
}
|
|
start, err := strconv.ParseUint(portRange[0], 10, 16)
|
|
if err != nil {
|
|
return nil, ErrInvalidPort
|
|
}
|
|
end, err := strconv.ParseUint(portRange[1], 10, 16)
|
|
if err != nil {
|
|
return nil, ErrInvalidPort
|
|
}
|
|
if start > end {
|
|
start, end = end, start
|
|
}
|
|
for i := start; i <= end; i++ {
|
|
result.Ports = append(result.Ports, uint16(i))
|
|
}
|
|
} else {
|
|
// Single port
|
|
port, err := strconv.ParseUint(portStr, 10, 16)
|
|
if err != nil {
|
|
return nil, ErrInvalidPort
|
|
}
|
|
result.Ports = append(result.Ports, uint16(port))
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|