@@ -36,9 +36,10 @@ import (
3636)
3737
3838var (
39- version = "dev"
40- certGraph = graph .NewCertGraph ()
41- processedCerts = make (map [fingerprint.Fingerprint ]bool ) // Session-wide cache for processed certificates
39+ version = "dev"
40+ certGraph = graph .NewCertGraph ()
41+ processedCerts = make (map [fingerprint.Fingerprint ]bool ) // Session-wide cache for processed certificates
42+ processedCertsMutex sync.Mutex // Protects processedCerts map
4243)
4344
4445// temp flag vars
@@ -408,7 +409,6 @@ func visit(domainNode *graph.DomainNode) {
408409 }
409410 domainNode .AddRelatedDomains (relatedDomains )
410411
411- // TODO parallelize this
412412 // TODO fix printing domains as they are found with new driver
413413 // add cert nodes to graph
414414 fingerprintMap , err := results .GetFingerprints ()
@@ -419,32 +419,88 @@ func visit(domainNode *graph.DomainNode) {
419419
420420 // fingerprints for the domain queried
421421 fingerprints := fingerprintMap [domainNode .Domain ]
422- for _ , fp := range fingerprints {
423- // add certNode to graph
424- certNode , exists := certGraph .GetCert (fp )
425- if ! exists {
426- // Check if we've already attempted to process this certificate
427- if processedCerts [fp ] {
428- v ("Certificate processing already attempted, skipping:" , fp .HexString ())
429- continue
430- }
422+
423+ // Parallelize certificate processing using worker pool
424+ type certWork struct {
425+ fp fingerprint.Fingerprint
426+ result * graph.CertNode
427+ err error
428+ }
429+
430+ certChan := make (chan fingerprint.Fingerprint , len (fingerprints ))
431+ resultChan := make (chan certWork , len (fingerprints ))
432+
433+ // Start worker goroutines
434+ numWorkers := min (config .parallel , uint (len (fingerprints )))
435+ if numWorkers == 0 {
436+ numWorkers = 1
437+ }
438+
439+ for i := uint (0 ); i < numWorkers ; i ++ {
440+ go func () {
441+ for fp := range certChan {
442+ var work certWork
443+ work .fp = fp
444+
445+ // Check if we've already attempted to process this certificate
446+ processedCertsMutex .Lock ()
447+ if processedCerts [fp ] {
448+ processedCertsMutex .Unlock ()
449+ work .err = fmt .Errorf ("already processed" )
450+ resultChan <- work
451+ continue
452+ }
453+ processedCerts [fp ] = true
454+ processedCertsMutex .Unlock ()
431455
432- // Mark as being processed to avoid duplicate attempts
433- processedCerts [fp ] = true
456+ // get cert details
457+ certResult , err := results .QueryCert (ctx , fp )
458+ if err != nil {
459+ work .err = err
460+ resultChan <- work
461+ continue
462+ }
434463
435- // get cert details
436- certResult , err := results .QueryCert (ctx , fp )
437- if err != nil {
438- v ("QueryCert" , err )
439- continue
464+ work .result = certNodeFromCertResult (certResult )
465+ resultChan <- work
440466 }
441-
442- certNode = certNodeFromCertResult (certResult )
443- certGraph .AddCert (certNode )
467+ }()
468+ }
469+
470+ // Send work to workers
471+ workCount := 0
472+ for _ , fp := range fingerprints {
473+ // Check if cert already exists in graph
474+ if _ , exists := certGraph .GetCert (fp ); exists {
475+ continue
476+ }
477+ certChan <- fp
478+ workCount ++
479+ }
480+ close (certChan )
481+
482+ // Collect results
483+ for i := 0 ; i < workCount ; i ++ {
484+ work := <- resultChan
485+ if work .err != nil {
486+ if work .err .Error () != "already processed" {
487+ v ("QueryCert" , work .err )
488+ }
489+ continue
490+ }
491+
492+ if work .result != nil {
493+ certGraph .AddCert (work .result )
494+ }
495+ }
496+
497+ // Add relationships after all certificates are processed
498+ for _ , fp := range fingerprints {
499+ certNode , exists := certGraph .GetCert (fp )
500+ if exists {
501+ certNode .AddFound (certDriver .GetName ())
502+ domainNode .AddCertFingerprint (certNode .Fingerprint , certDriver .GetName ())
444503 }
445-
446- certNode .AddFound (certDriver .GetName ())
447- domainNode .AddCertFingerprint (certNode .Fingerprint , certDriver .GetName ())
448504 }
449505
450506 // we don't process any other certificates returned, they will be collected
@@ -460,10 +516,12 @@ func printNode(domainNode *graph.DomainNode) {
460516 _ , _ = fmt .Fprintln (os .Stdout , domainNode .Domain )
461517 }
462518 if config .checkDNS && ! domainNode .HasDNS {
463- // TODO print this in a better way
464- // TODO for debugging
465519 realDomain , _ := dns .ApexDomain (domainNode .Domain )
466- _ , _ = fmt .Fprintf (os .Stdout , "* Missing DNS for: %s\n " , realDomain )
520+ if config .details {
521+ _ , _ = fmt .Fprintf (os .Stdout , " ⚠ DNS resolution failed for apex domain: %s\n " , realDomain )
522+ } else {
523+ _ , _ = fmt .Fprintf (os .Stdout , " [NO DNS] %s\n " , realDomain )
524+ }
467525
468526 }
469527}
0 commit comments