3 set -e$MODRELAYS_PROBE_SET_X
5 MODRELAYS=moderators.isc.org
6 PROBE_TIMEOUT=$(( 20 * 60 ))
7 PROBE_EXPIRE=$(( 32 * 86400 ))
15 shift; shift; set "$mode" "$@"
23 statedir=probes/probes
25 lockfile=$statedir/.lock
28 printf >&2 "%s\n" "modrelays-probe: error: $1"
33 # implicitly uses GROUP, id, domain
34 # caller must "local td", which will be set
37 probeid="$domain,${probeid//[^-=:.,_0-9A-Za-z]/%},$id"
39 .*|*/*) fail "yikes, sanitisation bug ($probeid) !" ;;
42 td="$statedir/$probeid"
50 record-probing-start () {
52 if ! [ -e "$td/started" ]; then
53 date -R >"$td/started"
62 record-probing "$probeid"
63 printf "%s\n" >"$td"/"$outcome" "$message"
66 record-success () { record-outcome "$1" ok ''; }
67 record-tempfail () { record-outcome "$1" tempfail "$2"; }
68 record-permfail () { record-outcome "$1" permfail "$2"; }
75 record-probing-start "mx=$mx,addr=$addr"
78 swaks --to "${GROUP//./-}@$domain" \
80 --tls-optional-strict \
81 --header 'Subject: test modrelays probe test' \
83 "X-WebSTUMP-Relay-Probe: $GROUP $id $domain $mx $addr" \
84 -n >$td/swaks.log 2>$td/swaks.err
89 0) return ;; # record-success done by receiver
95 local expect_no_5xx='initial connection'
97 while read <&4 prefix rhs; do
102 if [ "x$expect_no_5xx" != x ] && \
103 [ "x$permfail" = x ]; then
104 permfail="$rhs ($expect_no_5xx)"
111 EHLO*|STARTTLS*) expect_no_5xx='' ;;
112 *) expect_no_5xx="after $rhs" ;;
119 if [ "x$permfail" = x ]; then
120 record-tempfail "mx=$mx,addr=$addr" "see swaks.log / swaks.err"
122 record-permfail "mx=$mx,addr=$addr" "$permfail"
129 record-probing-start dns
132 adnshost -Fi -Tn +Do +Dt -t mx $domain >$td/dns
138 # have a list of MX's
144 while read <&3 pref mx statustype statustypenum rhs; do
145 case $statustypenum in
147 # have a list of relays
151 record-permfail "mx=$mx" \
161 INET|INET6) continue ;;
168 record-tempfail "mx=$mx" \
169 "dns $rc $statustype $rhs"
173 record-permfail "mx=$mx" \
174 "dns $rc $statustype $rhs"
184 adnshost -Fi -Tn +Do +Dt -t a $domain >$td/dns
192 # have a list of A's (dealt with MXs above)
195 while read <&3 addr; do
196 probe-addr 'NONE' $addr
204 record-tempfail dns "dns <no-mx> $emsg"
209 record-permfail dns "dns <no-mx> $emsg"
217 *) fail "no arguments to $mode allowed" ;;
223 if [ x"$WEBSTUMP_PROBE_LOCK" = x"$lockfile" ]; then return; fi
224 WEBSTUMP_PROBE_LOCK=$lockfile \
225 exec with-lock-ex $lock_mode "$lockfile" "$0" "$mode" "$@"
229 # implicitly uses $outcome, $reported etc. - see maybe-report
231 printf >>$logdir/log "%s: %s%s %s (%s)\n" \
232 "$(date --iso-8601=seconds | sed 's/T/ /')" \
233 "$outcome" "${reported:+ previously=}$reported" "$info" "$message"
234 echo "$outcome" >"$attempt"/reported
240 if $found_to_report; then return; fi
241 if ! [ -e "$attempt/$outcome" ]; then return; fi
244 message=$(cat "$attempt/$outcome")
247 if [ -e "$attempt/reported" ]; then
248 read <"$attempt/reported" reported
250 if [ "x$outcome" = "x$reported" ]; then return; fi
252 local info=${attempt##*/}
255 if [ x"$outcome" = x"ok" ] && [ x"$reported" = x ]; then
260 delim=`od -N 50 -An -x -w50 </dev/urandom`
263 local email="$attempt/.report.$outcome"
266 Subject: mod relay probe $outcome $info
267 Content-Type: multipart/mixed; boundary="$delim"
271 Content-Type: text/plain; charset="utf-8"
272 Content-Transfer-Encoding: 7bit
274 The moderation relay probe
278 if [ -e "$attempt/started" ]; then
280 read started <"$attempt/started"
288 resulted in the outcome
291 if [ "x$message" != x ]; then
298 if [ "x$reported" != x ]; then
300 This is even though previously the outcome seemed to be
302 and this was reported previously.
310 and concatenated to this email.
315 for log in "$attempt"/*; do
318 Content-Type: text/plain; charset="utf-8"
319 Content-Disposition: inline; filename="${log##*/}"
320 Content-Description: "${log##*/}"
321 Content-Transfer-Encoding: 8bit
324 cat >>"$email" <"$log"
332 /usr/sbin/sendmail -odb -oem -oee -t <"$email"
340 for attempt in $statedir/*; do
342 local now=$(date +%s)
343 local age=$(stat -c %Y "$attempt")
344 age=$(( $now - $age ))
346 local found_to_report=false
348 maybe-report permfail
349 maybe-report tempfail
351 if ! [ -e $attempt/reported ] && \
352 [ $age -gt $PROBE_TIMEOUT ]; then
353 echo >"$attempt"/timeout \
354 "Message did not arrive after ${PROBE_TIMEOUT}s"
359 if [ -e $attempt/reported ] && \
360 [ $age -gt $PROBE_EXPIRE ]; then
369 local hn group id domain mx addr
370 while read hn group id domain mx addr; do
371 if [ x"$hn" != x"X-WebSTUMP-Relay-Probe:" ]; then continue; fi
372 if [ x"$group" != x"$GROUP" ]; then continue; fi
373 case " $id $domain $mx $addr" in
374 */*|' '.*) fail "bad syntax" ;;
377 compute-td "mx=$mx,addr=$addr"
385 for domain in $MODRELAYS; do
391 for domain in "$@"; do