By default, only check the first IP against RBL, not all chain

This commit is contained in:
nemunaire 2025-10-27 16:00:20 +07:00
commit 86ec7a6100
7 changed files with 34 additions and 22 deletions

View file

@ -44,6 +44,7 @@ func NewEmailAnalyzer(cfg *config.Config) *EmailAnalyzer {
cfg.Analysis.DNSTimeout,
cfg.Analysis.HTTPTimeout,
cfg.Analysis.RBLs,
cfg.Analysis.CheckAllIPs,
)
return &EmailAnalyzer{

View file

@ -34,9 +34,10 @@ import (
// RBLChecker checks IP addresses against DNS-based blacklists
type RBLChecker struct {
Timeout time.Duration
RBLs []string
resolver *net.Resolver
Timeout time.Duration
RBLs []string
CheckAllIPs bool // Check all IPs found in headers, not just the first one
resolver *net.Resolver
}
// DefaultRBLs is a list of commonly used RBL providers
@ -50,7 +51,7 @@ var DefaultRBLs = []string{
}
// NewRBLChecker creates a new RBL checker with configurable timeout and RBL list
func NewRBLChecker(timeout time.Duration, rbls []string) *RBLChecker {
func NewRBLChecker(timeout time.Duration, rbls []string, checkAllIPs bool) *RBLChecker {
if timeout == 0 {
timeout = 5 * time.Second // Default timeout
}
@ -58,8 +59,9 @@ func NewRBLChecker(timeout time.Duration, rbls []string) *RBLChecker {
rbls = DefaultRBLs
}
return &RBLChecker{
Timeout: timeout,
RBLs: rbls,
Timeout: timeout,
RBLs: rbls,
CheckAllIPs: checkAllIPs,
resolver: &net.Resolver{
PreferGo: true,
},
@ -96,6 +98,11 @@ func (r *RBLChecker) CheckEmail(email *EmailMessage) *RBLResults {
results.ListedCount++
}
}
// Only check the first IP unless CheckAllIPs is enabled
if !r.CheckAllIPs {
break
}
}
return results

View file

@ -55,7 +55,7 @@ func TestNewRBLChecker(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checker := NewRBLChecker(tt.timeout, tt.rbls)
checker := NewRBLChecker(tt.timeout, tt.rbls, false)
if checker.Timeout != tt.expectedTimeout {
t.Errorf("Timeout = %v, want %v", checker.Timeout, tt.expectedTimeout)
}
@ -97,7 +97,7 @@ func TestReverseIP(t *testing.T) {
},
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -157,7 +157,7 @@ func TestIsPublicIP(t *testing.T) {
},
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -237,7 +237,7 @@ func TestExtractIPs(t *testing.T) {
},*/
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -322,7 +322,7 @@ func TestGetBlacklistScore(t *testing.T) {
},
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -351,7 +351,7 @@ func TestGetUniqueListedIPs(t *testing.T) {
},
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
listedIPs := checker.GetUniqueListedIPs(results)
expectedIPs := []string{"198.51.100.1", "198.51.100.2"}
@ -376,7 +376,7 @@ func TestGetRBLsForIP(t *testing.T) {
},
}
checker := NewRBLChecker(5*time.Second, nil)
checker := NewRBLChecker(5*time.Second, nil, false)
tests := []struct {
name string

View file

@ -44,12 +44,13 @@ func NewReportGenerator(
dnsTimeout time.Duration,
httpTimeout time.Duration,
rbls []string,
checkAllIPs bool,
) *ReportGenerator {
return &ReportGenerator{
authAnalyzer: NewAuthenticationAnalyzer(),
spamAnalyzer: NewSpamAssassinAnalyzer(),
dnsAnalyzer: NewDNSAnalyzer(dnsTimeout),
rblChecker: NewRBLChecker(dnsTimeout, rbls),
rblChecker: NewRBLChecker(dnsTimeout, rbls, checkAllIPs),
contentAnalyzer: NewContentAnalyzer(httpTimeout),
headerAnalyzer: NewHeaderAnalyzer(),
}

View file

@ -32,7 +32,7 @@ import (
)
func TestNewReportGenerator(t *testing.T) {
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs)
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false)
if gen == nil {
t.Fatal("Expected report generator, got nil")
}
@ -55,7 +55,7 @@ func TestNewReportGenerator(t *testing.T) {
}
func TestAnalyzeEmail(t *testing.T) {
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs)
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false)
email := createTestEmail()
@ -75,7 +75,7 @@ func TestAnalyzeEmail(t *testing.T) {
}
func TestGenerateReport(t *testing.T) {
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs)
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false)
testID := uuid.New()
email := createTestEmail()
@ -130,7 +130,7 @@ func TestGenerateReport(t *testing.T) {
}
func TestGenerateReportWithSpamAssassin(t *testing.T) {
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs)
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false)
testID := uuid.New()
email := createTestEmailWithSpamAssassin()
@ -150,7 +150,7 @@ func TestGenerateReportWithSpamAssassin(t *testing.T) {
}
func TestGenerateRawEmail(t *testing.T) {
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs)
gen := NewReportGenerator(10*time.Second, 10*time.Second, DefaultRBLs, false)
tests := []struct {
name string