neighbour.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package neighbour
  2. import (
  3. "encoding/json"
  4. "log"
  5. "time"
  6. "imuslab.com/arozos/mod/database"
  7. "imuslab.com/arozos/mod/network/mdns"
  8. )
  9. /*
  10. This is a module for discovering nearby arozos systems.
  11. Require MDNS Service
  12. */
  13. const (
  14. AutoDeleteRecordTime = int64(2592000) //30 days = 2592000 seconds
  15. )
  16. type Discoverer struct {
  17. Host *mdns.MDNSHost
  18. Database *database.Database
  19. LastScanningTime int64
  20. NearbyHosts []*mdns.NetworkHost
  21. d chan bool
  22. t *time.Ticker
  23. }
  24. type HostRecord struct {
  25. Name string
  26. Model string
  27. Version string
  28. UUID string
  29. LastSeenIP []string
  30. MacAddr []string
  31. LastOnline int64
  32. }
  33. //New Discoverer return a nearby Aroz Discover agent
  34. func NewDiscoverer(MDNS *mdns.MDNSHost, Database *database.Database) Discoverer {
  35. //Create a new table for neighbour records
  36. Database.NewTable("neighbour")
  37. return Discoverer{
  38. Host: MDNS,
  39. Database: Database,
  40. LastScanningTime: -1,
  41. NearbyHosts: []*mdns.NetworkHost{},
  42. }
  43. }
  44. //Return a list of NetworkHost with the same domain
  45. func (d *Discoverer) GetNearbyHosts() []*mdns.NetworkHost {
  46. nearbyHosts := []*mdns.NetworkHost{}
  47. for _, host := range d.NearbyHosts {
  48. nearbyHosts = append(nearbyHosts, host)
  49. }
  50. return nearbyHosts
  51. }
  52. //Start Scanning, interval and scna Duration in seconds
  53. func (d *Discoverer) StartScanning(interval int, scanDuration int) {
  54. log.Println("ArozOS Neighbour Scanning Started")
  55. if d.ScannerRunning() {
  56. //Another scanner already running. Terminate it
  57. d.StopScanning()
  58. }
  59. //Create a new ticker with the given interval and duration
  60. ticker := time.NewTicker(time.Duration(interval) * time.Second)
  61. done := make(chan bool)
  62. //Start scanner routine
  63. go func() {
  64. for {
  65. select {
  66. case <-done:
  67. return
  68. case <-ticker.C:
  69. d.UpdateScan(scanDuration)
  70. }
  71. }
  72. }()
  73. //Update the Discoverer settings
  74. d.d = done
  75. d.t = ticker
  76. }
  77. func (d *Discoverer) UpdateScan(scanDuration int) {
  78. d.LastScanningTime = time.Now().Unix()
  79. results := d.Host.Scan(scanDuration, d.Host.Host.Domain)
  80. d.NearbyHosts = results
  81. //Record all scanned host into database
  82. for _, thisHost := range results {
  83. thisHostIpString := []string{}
  84. for _, ipaddr := range thisHost.IPv4 {
  85. thisHostIpString = append(thisHostIpString, ipaddr.String())
  86. }
  87. thisHostRecord := HostRecord{
  88. Name: thisHost.HostName,
  89. Model: thisHost.Model,
  90. Version: thisHost.MinorVersion,
  91. UUID: thisHost.UUID,
  92. LastSeenIP: thisHostIpString,
  93. MacAddr: thisHost.MacAddr,
  94. LastOnline: time.Now().Unix(),
  95. }
  96. d.Database.Write("neighbour", thisHost.UUID, thisHostRecord)
  97. }
  98. }
  99. func (d *Discoverer) GetOfflineHosts() ([]*HostRecord, error) {
  100. results := []*HostRecord{}
  101. entries, err := d.Database.ListTable("neighbour")
  102. if err != nil {
  103. return results, err
  104. }
  105. for _, keypairs := range entries {
  106. //Get the host record and UUI from the database
  107. thisHostUUID := string(keypairs[0])
  108. thisHostRecord := HostRecord{}
  109. json.Unmarshal(keypairs[1], &thisHostRecord)
  110. if time.Now().Unix()-thisHostRecord.LastOnline > AutoDeleteRecordTime {
  111. //Remove this record
  112. log.Println("[Neighbour] Removing network host record due to long period offline: " + thisHostUUID + " (" + thisHostRecord.Name + ")")
  113. d.Database.Delete("neighbour", thisHostUUID)
  114. continue
  115. }
  116. //Check this host is online
  117. nodeIsOnline := false
  118. for _, thisOnlineHost := range d.NearbyHosts {
  119. if thisOnlineHost.UUID == thisHostUUID {
  120. //This is online node. skip this
  121. nodeIsOnline = true
  122. break
  123. }
  124. }
  125. if !nodeIsOnline {
  126. results = append(results, &thisHostRecord)
  127. }
  128. }
  129. return results, nil
  130. }
  131. func (d *Discoverer) ScannerRunning() bool {
  132. if d.d != nil {
  133. return true
  134. } else {
  135. return false
  136. }
  137. }
  138. func (d *Discoverer) StopScanning() {
  139. if d.d != nil {
  140. //Another ticker already running. Terminate it
  141. d.d <- true
  142. //Clear the old ticker
  143. d.t.Stop()
  144. d.d = nil
  145. d.t = nil
  146. }
  147. log.Println("ArozOS Neighbour Scanning Stopped")
  148. }