matrix.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "time"
  10. )
  11. //ByControlPlane contains all the channels we need.
  12. type ByControlPlane struct {
  13. BadTokens chan string
  14. GoodTokens chan string
  15. StatsTokens chan string
  16. }
  17. //ControPlane is the variabile
  18. var ControPlane ByControlPlane
  19. //ByClassifier is the structure containing our Pseudo-Bayes classifier.
  20. type ByClassifier struct {
  21. GOOD sync.Map
  22. BAD sync.Map
  23. MEH sync.Map
  24. STATS sync.Map
  25. }
  26. //AddStats adds the statistics after proper blocking.
  27. func (c *ByClassifier) AddStats(action string) {
  28. var one int64 = 1
  29. if v, ok := c.STATS.Load(action); ok {
  30. c.STATS.Store(action, v.(int64)+1)
  31. } else {
  32. c.STATS.Store(action, one)
  33. }
  34. }
  35. //IsBAD inserts a bad key in the right place.
  36. func (c *ByClassifier) IsBAD(key string) {
  37. if _, ok := c.MEH.Load(key); ok {
  38. c.MEH.Store(key, time.Now().UnixNano())
  39. return
  40. }
  41. if _, ok := c.GOOD.Load(key); ok {
  42. c.MEH.Store(key, time.Now().UnixNano())
  43. c.GOOD.Delete(key)
  44. return
  45. }
  46. if _, ok := c.BAD.Load(key); ok {
  47. c.BAD.Store(key, time.Now().UnixNano())
  48. return
  49. }
  50. c.BAD.Store(key, time.Now().UnixNano())
  51. }
  52. //IsGOOD inserts the key in the right place.
  53. func (c *ByClassifier) IsGOOD(key string) {
  54. if _, ok := c.MEH.Load(key); ok {
  55. c.MEH.Store(key, time.Now().UnixNano())
  56. return
  57. }
  58. if _, ok := c.BAD.Load(key); ok {
  59. c.MEH.Store(key, time.Now().UnixNano())
  60. c.BAD.Delete(key)
  61. return
  62. }
  63. if _, ok := c.GOOD.Load(key); ok {
  64. c.GOOD.Store(key, time.Now().UnixNano())
  65. return
  66. }
  67. c.GOOD.Store(key, time.Now().UnixNano())
  68. }
  69. //Posterior calculates the posterior probabilities in pseudo-bayes.
  70. func (c *ByClassifier) Posterior(hdr string) map[string]float64 {
  71. headers := strings.Fields(sanitizeHeaders(hdr))
  72. var result = make(map[string]float64)
  73. result["BAD"] = 0
  74. result["GOOD"] = 0
  75. var tmpResGood, tmpResBad, tmpTotal float64
  76. for _, token := range headers {
  77. if _, ok := c.BAD.Load(token); ok {
  78. tmpResBad++
  79. tmpTotal++
  80. }
  81. if _, ok := c.GOOD.Load(token); ok {
  82. tmpResGood++
  83. tmpTotal++
  84. }
  85. }
  86. if tmpTotal == 0 {
  87. tmpTotal = 1
  88. }
  89. log.Printf("Bad Tokens: %f, Good Tokens %f , Total %f\n", tmpResBad, tmpResGood, tmpTotal)
  90. result["BAD"] = tmpResBad / tmpTotal
  91. result["GOOD"] = tmpResGood / tmpTotal
  92. return result
  93. }
  94. //Janitor keeps the maps under a certain size, keeping the biggest values.
  95. func (c *ByClassifier) Janitor(size int) {
  96. log.Println("Janitor Running")
  97. sortMap(&c.BAD, size)
  98. sortMap(&c.GOOD, size)
  99. sortMap(&c.MEH, size)
  100. log.Println("Janitor Finished.")
  101. }
  102. //CleanThread is the Janitor thread
  103. func (c *ByClassifier) CleanThread() {
  104. for {
  105. MaxSize, err := strconv.Atoi(fmt.Sprintf("%d", Maturity))
  106. if err != nil {
  107. MaxSize = 1000
  108. log.Println("Maxsize converted to: ", MaxSize)
  109. }
  110. log.Println("Janitor Maxsize is now:", MaxSize)
  111. time.Sleep(10 * time.Second)
  112. c.Janitor(MaxSize)
  113. }
  114. }
  115. func (c *ByClassifier) enroll() {
  116. ControPlane.BadTokens = make(chan string, 2048)
  117. ControPlane.GoodTokens = make(chan string, 2048)
  118. ControPlane.StatsTokens = make(chan string, 2048)
  119. c.IsBAD("Penis")
  120. c.IsGOOD("Gun")
  121. c.MEH.Store("Dildo", time.Now().UnixNano())
  122. go c.readBadTokens()
  123. go c.readGoodTokens()
  124. go c.readStatsTokens()
  125. log.Println("Classifier populated...")
  126. go c.CleanThread()
  127. go c.CleanMEH()
  128. log.Println("Janitor Started")
  129. }
  130. func sortMap(unsorted *sync.Map, size int) {
  131. type Myt struct {
  132. Name string
  133. Num int64
  134. }
  135. var tempCont []Myt
  136. var tc Myt
  137. unsorted.Range(func(key interface{}, value interface{}) bool {
  138. tc.Name = key.(string)
  139. tc.Num = value.(int64)
  140. tempCont = append(tempCont, tc)
  141. return true
  142. })
  143. sort.Slice(tempCont, func(i, j int) bool { return tempCont[i].Num > tempCont[j].Num })
  144. if size > 0 && len(tempCont) > size {
  145. tempCont = tempCont[:size]
  146. }
  147. unsorted.Range(func(key interface{}, value interface{}) bool {
  148. unsorted.Delete(key)
  149. return true
  150. })
  151. for _, val := range tempCont {
  152. unsorted.Store(val.Name, val.Num)
  153. }
  154. }
  155. func (c *ByClassifier) readBadTokens() {
  156. log.Println("Start reading BAD tokens")
  157. for token := range ControPlane.BadTokens {
  158. c.IsBAD(token)
  159. }
  160. }
  161. func (c *ByClassifier) readGoodTokens() {
  162. log.Println("Start reading GOOD tokens")
  163. for token := range ControPlane.GoodTokens {
  164. c.IsGOOD(token)
  165. }
  166. }
  167. func (c *ByClassifier) readStatsTokens() {
  168. log.Println("Start reading STATS tokens")
  169. for token := range ControPlane.StatsTokens {
  170. c.AddStats(token)
  171. }
  172. }
  173. //CleanMEH cleans periodically the spurious tokens.
  174. func (c *ByClassifier) CleanMEH() {
  175. log.Println("Clean MEH Thread running...")
  176. for a := range time.Tick(24 * time.Hour) {
  177. c.MEH.Range(func(key interface{}, value interface{}) bool {
  178. c.MEH.Delete(key)
  179. return true
  180. })
  181. log.Println("MEH Cleaned at:", a)
  182. }
  183. }