mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-05-11 01:56:34 +00:00
91 lines
1.7 KiB
Go
91 lines
1.7 KiB
Go
package connection
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// TODO: TUN-5422 Unregister session
|
|
const (
|
|
sessionIDLen = len(uuid.UUID{})
|
|
)
|
|
|
|
type udpSessions struct {
|
|
lock sync.RWMutex
|
|
sessions map[uuid.UUID]*net.UDPConn
|
|
localIP net.IP
|
|
}
|
|
|
|
func newUDPSessions(localIP net.IP) *udpSessions {
|
|
return &udpSessions{
|
|
sessions: make(map[uuid.UUID]*net.UDPConn),
|
|
localIP: localIP,
|
|
}
|
|
}
|
|
|
|
func (us *udpSessions) register(id uuid.UUID, dstIP net.IP, dstPort uint16) (*net.UDPConn, error) {
|
|
us.lock.Lock()
|
|
defer us.lock.Unlock()
|
|
dstAddr := &net.UDPAddr{
|
|
IP: dstIP,
|
|
Port: int(dstPort),
|
|
}
|
|
conn, err := net.DialUDP("udp", us.localAddr(), dstAddr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
us.sessions[id] = conn
|
|
return conn, nil
|
|
}
|
|
|
|
func (us *udpSessions) unregister(id uuid.UUID) {
|
|
us.lock.Lock()
|
|
defer us.lock.Unlock()
|
|
delete(us.sessions, id)
|
|
}
|
|
|
|
func (us *udpSessions) send(id uuid.UUID, payload []byte) error {
|
|
us.lock.RLock()
|
|
defer us.lock.RUnlock()
|
|
conn, ok := us.sessions[id]
|
|
if !ok {
|
|
return fmt.Errorf("session %s not found", id)
|
|
}
|
|
_, err := conn.Write(payload)
|
|
return err
|
|
}
|
|
|
|
func (ud *udpSessions) localAddr() *net.UDPAddr {
|
|
// TODO: Determine the IP to bind to
|
|
|
|
return &net.UDPAddr{
|
|
IP: ud.localIP,
|
|
Port: 0,
|
|
}
|
|
}
|
|
|
|
// TODO: TUN-5421 allow user to specify which IP to bind to
|
|
func GetLocalIP() (net.IP, error) {
|
|
addrs, err := net.InterfaceAddrs()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, addr := range addrs {
|
|
// Find the IP that is not loop back
|
|
var ip net.IP
|
|
switch v := addr.(type) {
|
|
case *net.IPNet:
|
|
ip = v.IP
|
|
case *net.IPAddr:
|
|
ip = v.IP
|
|
}
|
|
if !ip.IsLoopback() {
|
|
return ip, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("cannot determine IP to bind to")
|
|
}
|