github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/agentconfig/portandproto.go (about) 1 package agentconfig 2 3 import ( 4 "errors" 5 "fmt" 6 "math" 7 "net" 8 "strconv" 9 "strings" 10 11 core "k8s.io/api/core/v1" 12 ) 13 14 var ErrNotInteger = errors.New("not an integer") 15 16 const ProtoSeparator = byte('/') 17 18 // ParseNumericPort parses the given string into a positive unsigned 16-bit integer. 19 // ErrNotInteger is returned if the string doesn't represent an integer. 20 // A range error is return unless the integer is between 1 and 65535. 21 func ParseNumericPort(portStr string) (uint16, error) { 22 port, err := strconv.Atoi(portStr) 23 if err != nil { 24 return 0, ErrNotInteger 25 } 26 if port < 1 || port > math.MaxUint16 { 27 return 0, fmt.Errorf("%s is not between 1 and 65535", portStr) 28 } 29 return uint16(port), nil 30 } 31 32 func ParseProtocol(protocol string) (core.Protocol, error) { 33 pr := core.Protocol(strings.ToUpper(protocol)) 34 switch pr { 35 case "": 36 return core.ProtocolTCP, nil 37 case core.ProtocolUDP, core.ProtocolTCP: 38 return pr, nil 39 default: 40 return "", fmt.Errorf("unsupported protocol: %s", pr) 41 } 42 } 43 44 type PortAndProto struct { 45 Port uint16 46 Proto core.Protocol 47 } 48 49 func NewPortAndProto(s string) (PortAndProto, error) { 50 pp := PortAndProto{Proto: core.ProtocolTCP} 51 var err error 52 if ix := strings.IndexByte(s, ProtoSeparator); ix > 0 { 53 if pp.Proto, err = ParseProtocol(s[ix+1:]); err != nil { 54 return pp, err 55 } 56 s = s[0:ix] 57 } 58 pp.Port, err = ParseNumericPort(s) 59 return pp, err 60 } 61 62 func (pp *PortAndProto) Addr() (addr net.Addr, err error) { 63 as := fmt.Sprintf(":%d", pp.Port) 64 if pp.Proto == core.ProtocolTCP { 65 addr, err = net.ResolveTCPAddr("tcp", as) 66 } else { 67 addr, err = net.ResolveUDPAddr("udp", as) 68 } 69 return 70 } 71 72 func (pp *PortAndProto) String() string { 73 if pp.Proto == core.ProtocolTCP { 74 return strconv.Itoa(int(pp.Port)) 75 } 76 return fmt.Sprintf("%d/%s", pp.Port, pp.Proto) 77 }