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  }