メーリングリストサーバとして代表的なものは、Mailmanやfml、sympa等があります。
その中のfmlで動作がおかしい部分を発見したので、忘れないようにメモメモ〆(.. )
正直、クリティカルなものかそうでないかと言えば、微妙なところなのですがf(^^;)
所謂、”仕様”なのかもしれませんが( ̄Д ̄;)
おかしい気がするので。。。
fmlは、一度送信したメールのmessage-IDを記録しておき、以前送ったことがあるメールかどうかをmessage-IDを比較してチェックします。message-IDが同じメールを送ろうとすると、以前送ったメールであると判断してエラーとなり、「Loop Alert:」というログが出力されます。
message-IDはメール1通1通の識別子であり、同じになることはまずありえないのです。ですが、やたらと「Loop Alert:」となったので、何かがおかしい。で、メールログと、fmlのキャッシュを比べると似たようなmessage-IDがありました。
キャッシュファイル内: JA8AAAAABIH8CgABYQABNARwAfxU@example.com
メールログ内 : JA8AAAAABIH8cgABYQABNARwAfxU@example.com
^
|
ん?Cの大文字と小文字が違うだけ?怪しい・・・分からないので、実際にmessage-IDを比較しているところをfmlのソースから確認してみました。perlなので普通に分かりました。
◇ /usr/local/fml/fml.pl
~
local($status, $mid);
# no check -> "return not looped"
$CHECK_MESSAGE_ID || return 0;
local($mid) = $Envelope{'h:Message-Id:'};
$mid =~ s/[\<\>]//g;
$mid =~ s/^\s+//;
&Debug("DupMessageIdP::($mid, $LOG_MESSAGE_ID)") if $debug;
$status = &SearchDupKey($mid, $LOG_MESSAGE_ID);
^^^^^^^^^^^^^
if ($status) {
&Debug("\tDupMessageIdP::(DUPLICATED == LOOPED)") if $debug;
local($s) = "Duplicated Message-ID";
&Log("Loop Alert: $s");
&WarnE("Loop Alert: $s $ML_FN", "$s in <$MAIL_LIST>.\n\n");
1;
}
~
|
SearchDupKeyの関数を見ればいいんだね!
~
sub SearchDupKey
{
local($key, $file) = @_;
local($status, $i);
# 1. scan current and
if (-f $file) {
$status = &Lookup($key, $file);
^^^^^^^
}
return $status if $status;
# 2. scan all available caches
for $i (0 .. $NEWSYSLOG_MAX) {
if ($status) {
last; # end if non null $status is returned.
}
elsif (-f "$file.$i") {
$status = &Lookup($key, "$file.$i");
^^^^^^^
}
}
$status;
}
~
|
Lookupの関数を見ればいいんだね!
~
sub Lookup
{
local($address, $file) = @_;
local($addr, $has_special_char, $auto_registrable);
~
# for high performance(Firstly special character check)
if (! $has_special_char) { next getline unless /^$addr/i;}
# This searching algorithm must require about N/2, not tuned,
if (1 == &AddressMatch($_, $address)) {
^^^^^^^^^^^^^
close(LOOKUP_TABLE);
return 1;
}
}# end of while loop;
close(LOOKUP_TABLE);
return 0;
}
~
|
AddressMatchの関数を見ればいいんだね!
~
sub AddressMatch
{
local($addr1, $addr2) = @_;
&Debug(" AddressMatch($addr1, $addr2)".
" [\$ADDR_CHECK_MAX=$ADDR_CHECK_MAX]\n") if $debug_addrmatch;
# canonicalize to lower case
$addr1 =~ y/A-Z/a-z/; ☆ビンゴ
$addr2 =~ y/A-Z/a-z/;
~
}
~
|
ビンゴ!!大文字を小文字に変えてるΣ( ̄Д ̄;)
つまり、大文字小文字区別なしでメールのIDを比較をしているジャマイカ。
RFCでは「メールのIDは大文字小文字の区別を行う」事が規定ですので、fmlがRFCに準拠していない。。。すごく似たmessage-IDを付けるメーラーもメーラーですが、これはいけないですよね・・・。