github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/dnsproxy/dns_report.go (about) 1 // +build linux windows 2 3 package dnsproxy 4 5 import ( 6 "context" 7 "fmt" 8 "net" 9 "time" 10 11 "go.aporeto.io/enforcerd/trireme-lib/collector" 12 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pucontext" 13 ) 14 15 var ( 16 waitTimeBeforeReport = 5 * time.Minute 17 ) 18 19 type dnsReport struct { 20 key string 21 contextID string 22 nameLookup string 23 error string 24 source collector.EndPoint 25 dest collector.EndPoint 26 namespace string 27 ips []string 28 } 29 30 func (p *Proxy) sendToCollector(report dnsReport, count int) { 31 r := &collector.DNSRequestReport{ 32 ContextID: report.contextID, 33 NameLookup: report.nameLookup, 34 Source: &report.source, 35 Destination: &report.dest, 36 Namespace: report.namespace, 37 Error: report.error, 38 Count: count, 39 Ts: time.Now(), 40 IPs: report.ips, 41 } 42 p.collector.CollectDNSRequests(r) 43 } 44 45 func (p *Proxy) reportDNSRequests(ctx context.Context, chreport chan dnsReport) { 46 dnsReports := map[string]int{} 47 sendReport := make(chan dnsReport) 48 deleteReport := make(chan dnsReport) 49 50 for { 51 select { 52 case r := <-chreport: 53 dnsReports[r.key]++ 54 switch dnsReports[r.key] { 55 case 1: 56 // dispatch immediately 57 p.sendToCollector(r, 1) 58 go func(r dnsReport) { 59 <-time.After(waitTimeBeforeReport) 60 deleteReport <- r 61 }(r) 62 case 2: 63 go func(r dnsReport) { 64 <-time.After(waitTimeBeforeReport) 65 sendReport <- r 66 }(r) 67 } 68 case r := <-sendReport: 69 p.sendToCollector(r, dnsReports[r.key]-1) 70 delete(dnsReports, r.key) 71 case r := <-deleteReport: 72 if dnsReports[r.key] == 1 { 73 delete(dnsReports, r.key) 74 } 75 case <-ctx.Done(): 76 return 77 } 78 } 79 } 80 81 func (p *Proxy) reportDNSLookup(name string, pucontext *pucontext.PUContext, srcIP net.IP, srcPort uint16, dnsIP net.IP, dnsPort uint16, ips []string, err string) { 82 p.chreports <- dnsReport{ 83 contextID: pucontext.ID(), 84 nameLookup: name, 85 error: err, 86 namespace: pucontext.ManagementNamespace(), 87 source: collector.EndPoint{ 88 IP: srcIP.String(), 89 Port: srcPort, 90 ID: pucontext.ManagementID(), 91 Type: collector.EndPointTypePU, 92 }, 93 dest: collector.EndPoint{ 94 IP: dnsIP.String(), 95 Port: dnsPort, 96 ID: pucontext.ManagementID(), 97 Type: collector.EndPointTypePU, 98 }, 99 ips: ips, 100 key: fmt.Sprintf("%s:%s:%s:%s:%s:%s", pucontext.ID(), name, err, pucontext.ManagementNamespace(), srcIP.String(), pucontext.ManagementID()), 101 } 102 }