Roughed in transwarp implementation for 'transwarp:'. We'll see how the listener side of this plays out. (#44)

This commit is contained in:
Michael Quigley
2020-03-17 14:48:14 -04:00
parent b85f1fc4c7
commit 7b13c92e93
4 changed files with 229 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
/*
(c) Copyright NetFoundry, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transwarp
import (
"fmt"
"github.com/netfoundry/ziti-foundation/identity/identity"
"github.com/netfoundry/ziti-foundation/transport"
"io"
"strconv"
"strings"
)
func (self address) Dial(name string, _ *identity.TokenId) (transport.Connection, error) {
return Dial(self.bindableAddress(), name)
}
func (self address) Listen(_ string, _ *identity.TokenId, _ chan transport.Connection) (io.Closer, error) {
return Listen(self.bindableAddress())
}
func (self address) MustListen(name string, _ *identity.TokenId, _ chan transport.Connection) io.Closer {
closer, err := self.Listen(name, nil, nil)
if err != nil {
panic(fmt.Errorf("cannot listen (%w)", err))
}
return closer
}
func (self address) String() string {
return fmt.Sprintf("transwarp:%s", self.bindableAddress())
}
func (self address) bindableAddress() string {
return fmt.Sprintf("%s:%d", self.hostname, self.port)
}
type address struct {
hostname string
port uint16
}
type AddressParser struct{}
func (_ AddressParser) Parse(s string) (transport.Address, error) {
tokens := strings.Split(s, ":")
if len(tokens) != 3 {
return nil, fmt.Errorf("invalid format")
}
if tokens[0] == "transwarp" {
port, err := strconv.ParseUint(tokens[2], 10, 16)
if err != nil {
return nil, err
}
return &address{hostname: tokens[1], port: uint16(port)}, nil
}
return nil, fmt.Errorf("invalid format")
}
+72
View File
@@ -0,0 +1,72 @@
/*
(c) Copyright NetFoundry, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transwarp
import (
"crypto/x509"
"github.com/netfoundry/ziti-foundation/transport"
"io"
"net"
"time"
)
func (self *connection) Detail() *transport.ConnectionDetail {
return self.detail
}
func (_ *connection) PeerCertificates() []*x509.Certificate {
return nil
}
func (self *connection) Reader() io.Reader {
return self.socket
}
func (self *connection) Writer() io.Writer {
return self.socket
}
func (self *connection) Conn() net.Conn {
return self.socket
}
func (self *connection) SetReadTimeout(t time.Duration) error {
return self.socket.SetReadDeadline(time.Now().Add(t))
}
func (self *connection) SetWriteTimeout(t time.Duration) error {
return self.socket.SetWriteDeadline(time.Now().Add(t))
}
func (self *connection) Close() error {
return self.socket.Close()
}
func newConnection(detail *transport.ConnectionDetail, socket net.Conn) *connection {
return &connection{
detail: detail,
socket: socket,
buffer: make([]byte, 4096),
}
}
type connection struct {
detail *transport.ConnectionDetail
socket net.Conn
buffer []byte
copy []byte
}
+46
View File
@@ -0,0 +1,46 @@
/*
(c) Copyright NetFoundry, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transwarp
import (
"fmt"
"github.com/netfoundry/ziti-foundation/transport"
"net"
)
func Dial(destination, name string) (transport.Connection, error) {
destinationAddress, err := net.ResolveUDPAddr("udp", destination)
if err != nil {
return nil, fmt.Errorf("error resolving destination address (%w)", err)
}
localAddress, err := net.ResolveUDPAddr("udp", ":0")
if err != nil {
return nil, fmt.Errorf("error resolving local address (%w)", err)
}
conn, err := net.DialUDP("udp", localAddress, destinationAddress)
if err != nil {
return nil, fmt.Errorf("error dialing (%w)", err)
}
return newConnection(&transport.ConnectionDetail{
Address: "transwarp" + destination,
InBound: false,
Name: name,
}, conn), nil
}
+37
View File
@@ -0,0 +1,37 @@
/*
(c) Copyright NetFoundry, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transwarp
import (
"fmt"
"io"
"net"
)
func Listen(bindAddress string) (io.Closer, error) {
listenAddress, err := net.ResolveUDPAddr("udp", bindAddress)
if err != nil {
return nil, fmt.Errorf("error resolving bind address (%w)", err)
}
socket, err := net.ListenUDP("udp", listenAddress)
if err != nil {
return nil, fmt.Errorf("error listening (%w)", err)
}
return socket, nil
}