github.com/openziti/transport@v0.1.5/transwarptls/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 transwarptls
    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, id *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, id, subc)
    52  }
    53  
    54  func (self address) DialWithLocalBinding(name string, localBinding string, id *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  	return DialWithLocalBinding(endpoint, name, localBinding, id, subc)
    68  }
    69  
    70  func (self address) Listen(name string, id *identity.TokenId, incoming chan transport.Connection, tcfg transport.Configuration) (io.Closer, error) {
    71  	bind, err := net.ResolveUDPAddr("udp", self.bindableAddress())
    72  	if err != nil {
    73  		return nil, errors.Wrap(err, "resolve udp")
    74  	}
    75  	var subc map[interface{}]interface{}
    76  	if tcfg != nil {
    77  		if v, found := tcfg["westworld3"]; found {
    78  			if subv, ok := v.(map[interface{}]interface{}); ok {
    79  				subc = subv
    80  			}
    81  		}
    82  	}
    83  	return Listen(bind, name, id, incoming, subc)
    84  }
    85  
    86  func (self address) MustListen(name string, id *identity.TokenId, incoming chan transport.Connection, tcfg transport.Configuration) io.Closer {
    87  	closer, err := self.Listen(name, id, incoming, tcfg)
    88  	if err != nil {
    89  		panic(err)
    90  	}
    91  	return closer
    92  }
    93  
    94  func (self address) String() string {
    95  	return fmt.Sprintf("transwarptls:%s", self.bindableAddress())
    96  }
    97  
    98  func (self address) bindableAddress() string {
    99  	return fmt.Sprintf("%s:%d", self.hostname, self.port)
   100  }
   101  
   102  func (a address) Type() string {
   103  	return "transwarptls"
   104  }
   105  
   106  type AddressParser struct{}
   107  
   108  func (self AddressParser) Parse(s string) (transport.Address, error) {
   109  	tokens := strings.Split(s, ":")
   110  	if len(tokens) < 2 {
   111  		return nil, errors.New("invalid format")
   112  	}
   113  
   114  	if tokens[0] == "transwarptls" {
   115  		if len(tokens) != 3 {
   116  			return nil, errors.New("invalid format")
   117  		}
   118  
   119  		port, err := strconv.ParseUint(tokens[2], 10, 16)
   120  		if err != nil {
   121  			return nil, err
   122  		}
   123  
   124  		return &address{hostname: tokens[1], port: uint16(port)}, nil
   125  	}
   126  
   127  	return nil, errors.New("invalid format")
   128  }