mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-12 18:00:49 +01:00
0c039274a4
This update adds new relay integration for NetBird clients. The new relay is based on web sockets and listens on a single port. - Adds new relay implementation with websocket with single port relaying mechanism - refactor peer connection logic, allowing upgrade and downgrade from/to P2P connection - peer connections are faster since it connects first to relay and then upgrades to P2P - maintains compatibility with old clients by not using the new relay - updates infrastructure scripts with new relay service
182 lines
4.3 KiB
Go
182 lines
4.3 KiB
Go
//go:build linux || darwin
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/netbirdio/netbird/relay/testec2/tun"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type TurnReceiver struct {
|
|
conns []*net.UDPConn
|
|
clientAddresses map[string]string
|
|
devices []*tun.Device
|
|
}
|
|
|
|
type TurnSender struct {
|
|
turnConns map[string]*TurnConn
|
|
addresses []string
|
|
devices []*tun.Device
|
|
}
|
|
|
|
func runTurnWriting(tcpConn net.Conn, testData []byte, testDataLen int, wg *sync.WaitGroup) {
|
|
defer wg.Done()
|
|
defer tcpConn.Close()
|
|
|
|
log.Infof("start to sending test data: %s", tcpConn.RemoteAddr())
|
|
|
|
si := NewStartInidication(time.Now(), testDataLen)
|
|
_, err := tcpConn.Write(si)
|
|
if err != nil {
|
|
log.Errorf("failed to write to tcp: %s", err)
|
|
return
|
|
}
|
|
|
|
pieceSize := 1024
|
|
for j := 0; j < testDataLen; j += pieceSize {
|
|
end := j + pieceSize
|
|
if end > testDataLen {
|
|
end = testDataLen
|
|
}
|
|
_, writeErr := tcpConn.Write(testData[j:end])
|
|
if writeErr != nil {
|
|
log.Errorf("failed to write to tcp conn: %s", writeErr)
|
|
return
|
|
}
|
|
}
|
|
|
|
// grant time to flush out packages
|
|
time.Sleep(3 * time.Second)
|
|
}
|
|
|
|
func createSenderDevices(sender *TurnSender, clientAddresses *ClientPeerAddr) {
|
|
var i int
|
|
devices := make([]*tun.Device, 0, len(clientAddresses.Address))
|
|
for k, v := range clientAddresses.Address {
|
|
tc, ok := sender.turnConns[k]
|
|
if !ok {
|
|
log.Fatalf("failed to find turn conn: %s", k)
|
|
}
|
|
|
|
addr, err := net.ResolveUDPAddr("udp", v)
|
|
if err != nil {
|
|
log.Fatalf("failed to resolve udp address: %s", err)
|
|
}
|
|
device := &tun.Device{
|
|
Name: fmt.Sprintf("mtun-sender-%d", i),
|
|
IP: fmt.Sprintf("10.0.%d.1", i),
|
|
PConn: tc.relayConn,
|
|
DstAddr: addr,
|
|
}
|
|
|
|
err = device.Up()
|
|
if err != nil {
|
|
log.Fatalf("failed to bring up device: %s", err)
|
|
}
|
|
|
|
devices = append(devices, device)
|
|
i++
|
|
}
|
|
sender.devices = devices
|
|
}
|
|
|
|
func createTurnConns(p int, sender *TurnSender) {
|
|
turnConns := make(map[string]*TurnConn)
|
|
addresses := make([]string, 0, len(pairs))
|
|
for i := 0; i < p; i++ {
|
|
tc := AllocateTurnClient(turnSrvAddress)
|
|
log.Infof("allocated turn client: %s", tc.Address().String())
|
|
turnConns[tc.Address().String()] = tc
|
|
addresses = append(addresses, tc.Address().String())
|
|
}
|
|
|
|
sender.turnConns = turnConns
|
|
sender.addresses = addresses
|
|
}
|
|
|
|
func runTurnReading(d *tun.Device, durations chan time.Duration) {
|
|
tcpListener, err := net.Listen("tcp", d.IP+":9999")
|
|
if err != nil {
|
|
log.Fatalf("failed to listen on tcp: %s", err)
|
|
}
|
|
log := log.WithField("device", tcpListener.Addr())
|
|
|
|
tcpConn, err := tcpListener.Accept()
|
|
if err != nil {
|
|
_ = tcpListener.Close()
|
|
log.Fatalf("failed to accept connection: %s", err)
|
|
}
|
|
log.Infof("remote peer connected")
|
|
|
|
buf := make([]byte, 103)
|
|
n, err := tcpConn.Read(buf)
|
|
if err != nil {
|
|
_ = tcpListener.Close()
|
|
log.Fatalf(errMsgFailedReadTCP, err)
|
|
}
|
|
|
|
si := DecodeStartIndication(buf[:n])
|
|
log.Infof("received start indication: %v, %d", si, n)
|
|
|
|
buf = make([]byte, 8192)
|
|
i, err := tcpConn.Read(buf)
|
|
if err != nil {
|
|
_ = tcpListener.Close()
|
|
log.Fatalf(errMsgFailedReadTCP, err)
|
|
}
|
|
now := time.Now()
|
|
for i < si.TransferSize {
|
|
n, err := tcpConn.Read(buf)
|
|
if err != nil {
|
|
_ = tcpListener.Close()
|
|
log.Fatalf(errMsgFailedReadTCP, err)
|
|
}
|
|
i += n
|
|
}
|
|
durations <- time.Since(now)
|
|
}
|
|
|
|
func createDevices(addresses []string, receiver *TurnReceiver) error {
|
|
receiver.conns = make([]*net.UDPConn, 0, len(addresses))
|
|
receiver.clientAddresses = make(map[string]string, len(addresses))
|
|
receiver.devices = make([]*tun.Device, 0, len(addresses))
|
|
for i, addr := range addresses {
|
|
localAddr, err := net.ResolveUDPAddr("udp", udpListener)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to resolve UDP address: %s", err)
|
|
}
|
|
|
|
conn, err := net.ListenUDP("udp", localAddr)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create UDP connection: %s", err)
|
|
}
|
|
|
|
receiver.conns = append(receiver.conns, conn)
|
|
receiver.clientAddresses[addr] = conn.LocalAddr().String()
|
|
|
|
dstAddr, err := net.ResolveUDPAddr("udp", addr)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to resolve address: %s", err)
|
|
}
|
|
|
|
device := &tun.Device{
|
|
Name: fmt.Sprintf("mtun-%d", i),
|
|
IP: fmt.Sprintf("10.0.%d.2", i),
|
|
PConn: conn,
|
|
DstAddr: dstAddr,
|
|
}
|
|
|
|
if err = device.Up(); err != nil {
|
|
return fmt.Errorf("failed to bring up device: %s, %s", device.Name, err)
|
|
}
|
|
receiver.devices = append(receiver.devices, device)
|
|
}
|
|
return nil
|
|
}
|