Skip to content

Commit

Permalink
fix(smtp_server): refactor mx lookups to randomly order mx records wi…
Browse files Browse the repository at this point in the history
…th the same priority

closes #1408
closes #1405
  • Loading branch information
adamcooke committed Jul 27, 2021
1 parent fcb6361 commit bc22394
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
1 change: 1 addition & 0 deletions config/initializers/inflections.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
inflect.acronym 'UUID'
inflect.acronym 'HTTP'
inflect.acronym 'DB'
inflect.acronym 'MX'
inflect.acronym 'DKIM'
end
3 changes: 2 additions & 1 deletion lib/postal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ module Postal
autoload :MessageInspection
autoload :MessageParser
autoload :MessageRequeuer
autoload :MXLookup
autoload :QueryString
autoload :RabbitMQ
autoload :ReplySeparator
autoload :RspecHelpers
autoload :SendResult
autoload :Sender
autoload :SendResult
autoload :SMTPSender
autoload :SMTPServer
autoload :SpamCheck
Expand Down
34 changes: 34 additions & 0 deletions lib/postal/mx_lookup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Postal
class MXLookup

class << self

def lookup(domain)
records = resolve(domain)
records = sort(records)
records.map { |m| m[1] }
end

private

def sort(records)
records.sort do |a, b|
if a[0] == b[0]
[-1, 1].sample
else
a[0] <=> b[0]
end
end
end

def resolve(domain)
Resolv::DNS.open do |dns|
dns.timeouts = [10,5]
dns.getresources(domain, Resolv::DNS::Resource::IN::MX).map { |m| [m.preference.to_i, m.exchange.to_s] }
end
end

end

end
end
10 changes: 3 additions & 7 deletions lib/postal/smtp_sender.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,9 @@ def finish

def servers
@options[:servers] || self.class.relay_hosts || @servers ||= begin
mx_servers = []
Resolv::DNS.open do |dns|
dns.timeouts = [10,5]
mx_servers = dns.getresources(@domain, Resolv::DNS::Resource::IN::MX).map { |m| [m.preference.to_i, m.exchange.to_s] }.sort.map{ |m| m[1] }
if mx_servers.empty?
mx_servers = [@domain] # This will be resolved to an A or AAAA record later
end
mx_servers = MXLookup.lookup(@domain)
if mx_servers.empty?
mx_servers = [@domain] # This will be resolved to an A or AAAA record later
end
mx_servers
end
Expand Down

0 comments on commit bc22394

Please sign in to comment.