On Thu, Mar 27, 2014 at 03:24:14PM +0200, Bogdan Enache wrote:

> A user is trying to send email to a domain, "tn.odessa.ua" which has 3 MX
> servers. One of them is clearly not working,
> "notes.uptel.net[195.138.170.139]", which has a priority of 30. Checking the
> logs I see that Postfix always tries to deliver to "notes.uptel.net", and
> only that one, for the past 9 hours.

You are misinterpreting your logs, which you have not posted.
Postfix is actually trying all the MX hosts, you're only looking
at the results with the *final* MX which is where delivery error
is reported after trying all the others.

You don't need to change any of the session or address limits, they
are just fine.

Try the attached "collate" script to look at complete transaction
logs with all related connection attempts, ...

    # perl collate your.mail.log.file |
        perl -ne '
            BEGIN {$/ = "\n\n"; $domain = shift(@ARGV);}
            print if m{\@\Q$domain\E>}o;' tn.odessa.ua |
        less

-- 
        Viktor.
#! /usr/pkg/bin/perl

use strict;
use warnings;

# Postfix delivery agents
my @agents = qw(discard error lmtp local pipe smtp virtual);

my $instre = qr{(?x)
        \A                      # Absolute line start
        (?:\S+ \s+){3}          # Timestamp, adjust for other time formats
        \S+ \s+                 # Hostname
        (postfix(?:-\S+)?)/     # postfix instance
        };

my $cmdpidre = qr{(?x)
        \G                      # Continue from previous match
        (\S+)\[(\d+)\]:\s+      # command[pid]:
};

my %smtpd;
my %smtp;
my %transaction;
my $i = 0;
my %seqno;

my %isagent = map { ($_, 1) } @agents;

while (<>) {
        next unless m{$instre}ogc; my $inst = $1;
        next unless m{$cmdpidre}ogc; my $command = $1; my $pid = $2;

        if ($command eq "smtpd") {
                if (m{\Gconnect from }gc) {
                        # Start new log
                        $smtpd{$pid}->{"log"} = $_; next;
                }

                $smtpd{$pid}->{"log"} .= $_;

                if (m{\G(\w+): client=}gc) {
                        # Fresh transaction 
                        my $qid = "$inst/$1";
                        $smtpd{$pid}->{"qid"} = $qid;
                        $transaction{$qid} = $smtpd{$pid}->{"log"};
                        $seqno{$qid} = ++$i;
                        next;
                }

                my $qid = $smtpd{$pid}->{"qid"};
                $transaction{$qid} .= $_
                        if (defined($qid) && exists $transaction{$qid});
                delete $smtpd{$pid} if (m{\Gdisconnect from}gc);
                next;
        }

        if ($command eq "pickup") {
                if (m{\G(\w+): uid=}gc) {
                        my $qid = "$inst/$1";
                        $transaction{$qid} = $_;
                        $seqno{$qid} = ++$i;
                }
                next;
        }

        # bounce(8) logs transaction start after cleanup(8) already logged
        # the message-id, so the cleanup log entry may be first
        #
        if ($command eq "cleanup") {
                next unless (m{\G(\w+): }gc);
                my $qid = "$inst/$1";
                $transaction{$qid} .= $_;
                next;
        }

        if ($command eq "qmgr") {
                next unless (m{\G(\w+): }gc);
                my $qid = "$inst/$1";
                if (defined($transaction{$qid})) {
                        $transaction{$qid} .= $_;
                        if (m{\Gremoved$}gc) {
                                print delete $transaction{$qid}, "\n";
                        }
                }
                next;
        }

        # Save pre-delivery messages for smtp(8) and lmtp(8)
        #
        if ($command eq "smtp" || $command eq "lmtp") {
                $smtp{$pid} .= $_;

                if (m{\G(\w+): to=}gc) {
                        my $qid = "$inst/$1";
                        if (defined($transaction{$qid})) {
                                $transaction{$qid} .= $smtp{$pid};
                        }
                        delete $smtp{$pid};
                }
                next;
        }

        if ($command eq "bounce") {
                if (m{\G(\w+): .*? notification: (\w+)$}gc) {
                        my $qid = "$inst/$1";
                        my $newid = "$inst/$2";
                        if (defined($transaction{$qid})) {
                                $transaction{$qid} .= $_;
                        }
                        $transaction{$newid} =
                                $_ . $transaction{$newid};
                }
                next;
        }

        if ($isagent{$command}) {
                if (m{\G(\w+): to=}gc) {
                        my $qid = "$inst/$1";
                        if (defined($transaction{$qid})) {
                                $transaction{$qid} .= $_;
                        }
                }
                next;
        }
}

# Dump logs of incomplete transactions.
foreach my $qid (sort {$seqno{$a} <=> $seqno{$b}} keys %transaction) {
    print $transaction{$qid}, "\n";
}

Reply via email to