github.com/openziti/transport@v0.1.5/transwarp/address.go (about) 1 /* 2 Copyright NetFoundry, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 https://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package transwarp 18 19 import ( 20 "fmt" 21 "github.com/openziti/foundation/identity/identity" 22 "github.com/openziti/transport" 23 "github.com/pkg/errors" 24 "io" 25 "net" 26 "strconv" 27 "strings" 28 "time" 29 ) 30 31 var _ transport.Address = (*address)(nil) // enforce that address implements transport.Address 32 33 type address struct { 34 hostname string 35 port uint16 36 } 37 38 func (self address) Dial(name string, _ *identity.TokenId, _ time.Duration, tcfg transport.Configuration) (transport.Connection, error) { 39 endpoint, err := net.ResolveUDPAddr("udp", self.bindableAddress()) 40 if err != nil { 41 return nil, errors.Wrap(err, "resolve udp") 42 } 43 var subc map[interface{}]interface{} 44 if tcfg != nil { 45 if v, found := tcfg["westworld3"]; found { 46 if subv, ok := v.(map[interface{}]interface{}); ok { 47 subc = subv 48 } 49 } 50 } 51 return Dial(endpoint, name, subc) 52 } 53 54 func (self address) DialWithLocalBinding(name string, localBinding string, _ *identity.TokenId, _ time.Duration, tcfg transport.Configuration) (transport.Connection, error) { 55 endpoint, err := net.ResolveUDPAddr("udp", self.bindableAddress()) 56 if err != nil { 57 return nil, errors.Wrap(err, "resolve udp") 58 } 59 var subc map[interface{}]interface{} 60 if tcfg != nil { 61 if v, found := tcfg["westworld3"]; found { 62 if subv, ok := v.(map[interface{}]interface{}); ok { 63 subc = subv 64 } 65 } 66 } 67 68 return DialWithLocalBinding(endpoint, name, localBinding, subc) 69 } 70 71 func (self address) Listen(name string, _ *identity.TokenId, incoming chan transport.Connection, tcfg transport.Configuration) (io.Closer, error) { 72 bind, err := net.ResolveUDPAddr("udp", self.bindableAddress()) 73 if err != nil { 74 return nil, errors.Wrap(err, "resolve udp") 75 } 76 var subc map[interface{}]interface{} 77 if tcfg != nil { 78 if v, found := tcfg["westworld3"]; found { 79 if subv, ok := v.(map[interface{}]interface{}); ok { 80 subc = subv 81 } 82 } 83 } 84 return Listen(bind, name, incoming, subc) 85 } 86 87 func (self address) MustListen(name string, i *identity.TokenId, incoming chan transport.Connection, tcfg transport.Configuration) io.Closer { 88 closer, err := self.Listen(name, i, incoming, tcfg) 89 if err != nil { 90 panic(err) 91 } 92 return closer 93 } 94 95 func (self address) String() string { 96 return fmt.Sprintf("transwarp:%s", self.bindableAddress()) 97 } 98 99 func (self address) bindableAddress() string { 100 return fmt.Sprintf("%s:%d", self.hostname, self.port) 101 } 102 103 func (a address) Type() string { 104 return "transwarp" 105 } 106 107 type AddressParser struct{} 108 109 func (self AddressParser) Parse(s string) (transport.Address, error) { 110 tokens := strings.Split(s, ":") 111 if len(tokens) < 2 { 112 return nil, errors.New("invalid format") 113 } 114 115 if tokens[0] == "transwarp" { 116 if len(tokens) != 3 { 117 return nil, errors.New("invalid format") 118 } 119 120 port, err := strconv.ParseUint(tokens[2], 10, 16) 121 if err != nil { 122 return nil, err 123 } 124 125 return &address{hostname: tokens[1], port: uint16(port)}, nil 126 } 127 128 return nil, errors.New("invalid format") 129 }