2020-06-30 20:48:58 +02:00
|
|
|
// +build !linux android
|
2019-11-19 18:00:20 +01:00
|
|
|
|
|
|
|
// udp_generic implements the nebula UDP interface in pure Go stdlib. This
|
|
|
|
// means it can be used on platforms like Darwin and Windows.
|
|
|
|
|
|
|
|
package nebula
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
|
|
|
type udpConn struct {
|
|
|
|
*net.UDPConn
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewListener(ip string, port int, multi bool) (*udpConn, error) {
|
|
|
|
lc := NewListenConfig(multi)
|
2021-03-19 02:37:24 +01:00
|
|
|
pc, err := lc.ListenPacket(context.TODO(), "udp", fmt.Sprintf("%s:%d", ip, port))
|
2019-11-19 18:00:20 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if uc, ok := pc.(*net.UDPConn); ok {
|
|
|
|
return &udpConn{UDPConn: uc}, nil
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("Unexpected PacketConn: %T %#v", pc, pc)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (uc *udpConn) WriteTo(b []byte, addr *udpAddr) error {
|
2021-03-19 02:37:24 +01:00
|
|
|
_, err := uc.UDPConn.WriteToUDP(b, &net.UDPAddr{IP: addr.IP, Port: int(addr.Port)})
|
2019-11-19 18:00:20 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (uc *udpConn) LocalAddr() (*udpAddr, error) {
|
|
|
|
a := uc.UDPConn.LocalAddr()
|
|
|
|
|
|
|
|
switch v := a.(type) {
|
|
|
|
case *net.UDPAddr:
|
2021-03-19 02:37:24 +01:00
|
|
|
addr := &udpAddr{IP: make([]byte, len(v.IP))}
|
|
|
|
copy(addr.IP, v.IP)
|
|
|
|
addr.Port = uint16(v.Port)
|
|
|
|
return addr, nil
|
|
|
|
|
2019-11-19 18:00:20 +01:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("LocalAddr returned: %#v", a)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *udpConn) reloadConfig(c *Config) {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
2021-03-02 01:51:33 +01:00
|
|
|
func NewUDPStatsEmitter(udpConns []*udpConn) func() {
|
|
|
|
// No UDP stats for non-linux
|
|
|
|
return func() {}
|
|
|
|
}
|
|
|
|
|
2019-11-19 18:00:20 +01:00
|
|
|
type rawMessage struct {
|
|
|
|
Len uint32
|
|
|
|
}
|
|
|
|
|
2021-02-25 21:01:14 +01:00
|
|
|
func (u *udpConn) ListenOut(f *Interface, q int) {
|
2019-11-19 18:00:20 +01:00
|
|
|
plaintext := make([]byte, mtu)
|
|
|
|
buffer := make([]byte, mtu)
|
|
|
|
header := &Header{}
|
|
|
|
fwPacket := &FirewallPacket{}
|
2021-03-19 02:37:24 +01:00
|
|
|
udpAddr := &udpAddr{IP: make([]byte, 16)}
|
2019-11-19 18:00:20 +01:00
|
|
|
nb := make([]byte, 12, 12)
|
|
|
|
|
2020-11-23 20:50:01 +01:00
|
|
|
lhh := f.lightHouse.NewRequestHandler()
|
|
|
|
|
2021-03-02 01:52:17 +01:00
|
|
|
conntrackCache := NewConntrackCacheTicker(f.conntrackCacheTimeout)
|
|
|
|
|
2019-11-19 18:00:20 +01:00
|
|
|
for {
|
|
|
|
// Just read one packet at a time
|
|
|
|
n, rua, err := u.ReadFromUDP(buffer)
|
|
|
|
if err != nil {
|
|
|
|
l.WithError(err).Error("Failed to read packets")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-03-19 02:37:24 +01:00
|
|
|
udpAddr.IP = rua.IP
|
|
|
|
udpAddr.Port = uint16(rua.Port)
|
2021-03-02 01:52:17 +01:00
|
|
|
f.readOutsidePackets(udpAddr, plaintext[:0], buffer[:n], header, fwPacket, lhh, nb, q, conntrackCache.Get())
|
2019-11-19 18:00:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func hostDidRoam(addr *udpAddr, newaddr *udpAddr) bool {
|
|
|
|
return !addr.Equals(newaddr)
|
|
|
|
}
|