diff --git a/src/mapper/pkg/dnscache/dns_cache.go b/src/mapper/pkg/dnscache/dns_cache.go index c2f01487..2a545e30 100644 --- a/src/mapper/pkg/dnscache/dns_cache.go +++ b/src/mapper/pkg/dnscache/dns_cache.go @@ -10,15 +10,19 @@ import ( ) type DNSCache struct { - cache *ttlcache.Cache[string, string] + cache *ttlcache.Cache[string, string] + ipToNameCache *ttlcache.Cache[string, string] } func NewDNSCache() *DNSCache { capacity := viper.GetInt(config.DNSCacheItemsMaxCapacityKey) dnsRecordCache := ttlcache.New[string, string](ttlcache.WithCapacity[string, string](uint64(capacity))) go dnsRecordCache.Start() + ipToNameCache := ttlcache.New[string, string](ttlcache.WithCapacity[string, string](uint64(capacity))) + go ipToNameCache.Start() lastCapacityReachedErrorPrint := time.Time{} + ipToNameLastCapacityReachedErrorPrint := time.Time{} dnsRecordCache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { if reason == ttlcache.EvictionReasonCapacityReached && time.Since(lastCapacityReachedErrorPrint) > time.Minute { logrus.Warningf("DNS cache capacity reached entries are being dropped, consider increasing config '%s'", @@ -27,14 +31,24 @@ func NewDNSCache() *DNSCache { } }) + ipToNameCache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { + if reason == ttlcache.EvictionReasonCapacityReached && time.Since(ipToNameLastCapacityReachedErrorPrint) > time.Minute { + logrus.Warningf("DNS cache capacity reached entries are being dropped, consider increasing config '%s'", + config.DNSCacheItemsMaxCapacityKey) + ipToNameLastCapacityReachedErrorPrint = time.Now() + } + }) + return &DNSCache{ - cache: dnsRecordCache, + cache: dnsRecordCache, + ipToNameCache: ipToNameCache, } } func (d *DNSCache) AddOrUpdateDNSData(dnsName string, ip string, ttlSeconds int) { ttl := time.Duration(ttlSeconds) * time.Second d.cache.Set(dnsName, ip, ttl) + d.ipToNameCache.Set(ip, dnsName, ttl) } func (d *DNSCache) GetResolvedIP(dnsName string) (string, bool) { @@ -44,3 +58,11 @@ func (d *DNSCache) GetResolvedIP(dnsName string) (string, bool) { } return entry.Value(), true } + +func (d *DNSCache) GetResolvedDNSName(ip string) (string, bool) { + entry := d.ipToNameCache.Get(ip) + if entry == nil { + return "", false + } + return entry.Value(), true +} diff --git a/src/mapper/pkg/resolvers/resolver.go b/src/mapper/pkg/resolvers/resolver.go index 143d7aba..70ffc75c 100644 --- a/src/mapper/pkg/resolvers/resolver.go +++ b/src/mapper/pkg/resolvers/resolver.go @@ -3,10 +3,10 @@ package resolvers import ( "context" "github.com/99designs/gqlgen/graphql/handler" - "github.com/bugsnag/bugsnag-go/v2" "github.com/labstack/echo/v4" "github.com/otterize/intents-operator/src/shared/errors" "github.com/otterize/intents-operator/src/shared/serviceidresolver" + "github.com/otterize/intents-operator/src/shared/telemetries/errorreporter" "github.com/otterize/network-mapper/src/mapper/pkg/awsintentsholder" "github.com/otterize/network-mapper/src/mapper/pkg/dnscache" "github.com/otterize/network-mapper/src/mapper/pkg/externaltrafficholder" @@ -84,27 +84,27 @@ func (r *Resolver) Register(e *echo.Echo) { func (r *Resolver) RunForever(ctx context.Context) error { errgrp, errGrpCtx := errgroup.WithContext(ctx) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.dnsCaptureResults, r.handleReportCaptureResults) }) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.tcpCaptureResults, r.handleReportTCPCaptureResults) }) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.socketScanResults, r.handleReportSocketScanResults) }) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.kafkaMapperResults, r.handleReportKafkaMapperResults) }) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.istioConnectionResults, r.handleReportIstioConnectionResults) }) errgrp.Go(func() error { - defer bugsnag.AutoNotify(errGrpCtx) + defer errorreporter.AutoNotify() return runHandleLoop(errGrpCtx, r.awsOperations, r.handleAWSOperationReport) }) err := errgrp.Wait() diff --git a/src/mapper/pkg/resolvers/schema.helpers.resolvers.go b/src/mapper/pkg/resolvers/schema.helpers.resolvers.go index 667930f6..7ba3590c 100644 --- a/src/mapper/pkg/resolvers/schema.helpers.resolvers.go +++ b/src/mapper/pkg/resolvers/schema.helpers.resolvers.go @@ -393,7 +393,7 @@ func (r *Resolver) handleReportTCPCaptureResults(ctx context.Context, results mo } for _, dest := range captureItem.Destinations { - r.handleExternalIncomingTrafficTCPResult(ctx, srcSvcIdentity, dest) + r.handleIncomingTCPResult(ctx, srcSvcIdentity, dest) } } telemetrysender.SendNetworkMapper(telemetriesgql.EventTypeIntentsDiscoveredCapture, len(results.Results)) @@ -423,7 +423,7 @@ func (r *Resolver) reportIncomingInternetTraffic(ctx context.Context, srcIP stri return nil } -func (r *Resolver) handleExternalIncomingTrafficTCPResult(ctx context.Context, srcIdentity model.OtterizeServiceIdentity, dest model.Destination) { +func (r *Resolver) handleIncomingTCPResult(ctx context.Context, srcIdentity model.OtterizeServiceIdentity, dest model.Destination) { lastSeen := dest.LastSeen destIdentity, ok, err := r.resolveDestIdentity(ctx, dest, lastSeen) if err != nil { @@ -431,7 +431,17 @@ func (r *Resolver) handleExternalIncomingTrafficTCPResult(ctx context.Context, s return } if !ok { - return + // If the destination is not in cluster, check if it's traffic that goes to an IP address that we previously resolved by DNS. + dnsName, found := r.dnsCache.GetResolvedDNSName(dest.Destination) + if found && dest.DestinationIP != nil { + intent := externaltrafficholder.ExternalTrafficIntent{ + Client: srcIdentity, + LastSeen: dest.LastSeen, + DNSName: dnsName, + IPs: map[externaltrafficholder.IP]struct{}{externaltrafficholder.IP(*dest.DestinationIP): {}}, + } + r.externalTrafficIntentsHolder.AddIntent(intent) + } } intent := model.Intent{