udp_generic.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // +build !linux android
  2. // udp_generic implements the nebula UDP interface in pure Go stdlib. This
  3. // means it can be used on platforms like Darwin and Windows.
  4. package nebula
  5. import (
  6. "context"
  7. "fmt"
  8. "net"
  9. )
  10. type udpConn struct {
  11. *net.UDPConn
  12. }
  13. func NewListener(ip string, port int, multi bool) (*udpConn, error) {
  14. lc := NewListenConfig(multi)
  15. pc, err := lc.ListenPacket(context.TODO(), "udp", fmt.Sprintf("%s:%d", ip, port))
  16. if err != nil {
  17. return nil, err
  18. }
  19. if uc, ok := pc.(*net.UDPConn); ok {
  20. return &udpConn{UDPConn: uc}, nil
  21. }
  22. return nil, fmt.Errorf("Unexpected PacketConn: %T %#v", pc, pc)
  23. }
  24. func (uc *udpConn) WriteTo(b []byte, addr *udpAddr) error {
  25. _, err := uc.UDPConn.WriteToUDP(b, &net.UDPAddr{IP: addr.IP, Port: int(addr.Port)})
  26. return err
  27. }
  28. func (uc *udpConn) LocalAddr() (*udpAddr, error) {
  29. a := uc.UDPConn.LocalAddr()
  30. switch v := a.(type) {
  31. case *net.UDPAddr:
  32. addr := &udpAddr{IP: make([]byte, len(v.IP))}
  33. copy(addr.IP, v.IP)
  34. addr.Port = uint16(v.Port)
  35. return addr, nil
  36. default:
  37. return nil, fmt.Errorf("LocalAddr returned: %#v", a)
  38. }
  39. }
  40. func (u *udpConn) reloadConfig(c *Config) {
  41. // TODO
  42. }
  43. func NewUDPStatsEmitter(udpConns []*udpConn) func() {
  44. // No UDP stats for non-linux
  45. return func() {}
  46. }
  47. type rawMessage struct {
  48. Len uint32
  49. }
  50. func (u *udpConn) ListenOut(f *Interface, q int) {
  51. plaintext := make([]byte, mtu)
  52. buffer := make([]byte, mtu)
  53. header := &Header{}
  54. fwPacket := &FirewallPacket{}
  55. udpAddr := &udpAddr{IP: make([]byte, 16)}
  56. nb := make([]byte, 12, 12)
  57. lhh := f.lightHouse.NewRequestHandler()
  58. conntrackCache := NewConntrackCacheTicker(f.conntrackCacheTimeout)
  59. for {
  60. // Just read one packet at a time
  61. n, rua, err := u.ReadFromUDP(buffer)
  62. if err != nil {
  63. l.WithError(err).Error("Failed to read packets")
  64. continue
  65. }
  66. udpAddr.IP = rua.IP
  67. udpAddr.Port = uint16(rua.Port)
  68. f.readOutsidePackets(udpAddr, plaintext[:0], buffer[:n], header, fwPacket, lhh, nb, q, conntrackCache.Get())
  69. }
  70. }
  71. func hostDidRoam(addr *udpAddr, newaddr *udpAddr) bool {
  72. return !addr.Equals(newaddr)
  73. }