discovery.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package discovery
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "quickip/internal/config"
  8. "quickip/internal/deviceinfo"
  9. "quickip/internal/logger"
  10. "quickip/internal/model"
  11. )
  12. type Server struct {
  13. cfg config.Config
  14. log *logger.Logger
  15. deviceSvc *deviceinfo.Service
  16. }
  17. func New(cfg config.Config, log *logger.Logger, deviceSvc *deviceinfo.Service) *Server {
  18. return &Server{cfg: cfg, log: log, deviceSvc: deviceSvc}
  19. }
  20. func (s *Server) Run(ctx context.Context) error {
  21. addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", s.cfg.UDPHost, s.cfg.UDPPort))
  22. if err != nil {
  23. return err
  24. }
  25. conn, err := net.ListenUDP("udp4", addr)
  26. if err != nil {
  27. return err
  28. }
  29. defer conn.Close()
  30. go func() {
  31. <-ctx.Done()
  32. _ = conn.Close()
  33. }()
  34. s.log.Info("udp discovery listening", "addr", conn.LocalAddr().String())
  35. buf := make([]byte, 2048)
  36. for {
  37. n, remote, err := conn.ReadFromUDP(buf)
  38. if err != nil {
  39. if ctx.Err() != nil {
  40. return nil
  41. }
  42. return err
  43. }
  44. var req model.DiscoverRequest
  45. if err := json.Unmarshal(buf[:n], &req); err != nil || req.MessageType != "discover" {
  46. continue
  47. }
  48. device := s.deviceSvc.Get()
  49. resp := model.DiscoverResponse{
  50. ProtocolVersion: 1,
  51. MessageType: "discover_response",
  52. RequestID: req.RequestID,
  53. DeviceID: device.DeviceID,
  54. Hostname: device.Hostname,
  55. AgentVersion: device.AgentVersion,
  56. LAN2IP: s.cfg.MaintenanceIP,
  57. AuthRequired: true,
  58. }
  59. payload, _ := json.Marshal(resp)
  60. _, _ = conn.WriteToUDP(payload, remote)
  61. }
  62. }