summaryrefslogtreecommitdiffstats
path: root/usr.sbin/portsnap
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2006-05-03 21:19:43 +0000
committercperciva <cperciva@FreeBSD.org>2006-05-03 21:19:43 +0000
commit160fd830bec208508bbe390448c63626f240920c (patch)
tree087e8433248319e764acab30b8db39ee346adaa0 /usr.sbin/portsnap
parent1f2eeff0a4673cd2b5921553c09fae8c12c7304c (diff)
downloadFreeBSD-src-160fd830bec208508bbe390448c63626f240920c.zip
FreeBSD-src-160fd830bec208508bbe390448c63626f240920c.tar.gz
Instead of selecting a mirror and failing if it is inaccessible, keep
track of which mirrors we have tried and try a different mirror if we fail when trying to download the SSL public key or the snapshot signature. Failures later in the download process will not result in switching to a different mirror, for two reasons: 1. If is very unlikely that a mirror will fail partway through the process of downloading updates. 2. If we switched from a more recently updated mirror to a less recently updated mirror partway through the download process, we would end up failing anyway because we would be trying to fetch files which the second mirror didn't have yet. PR: bin/96288 Requested by: lots of people Sponsored by: FreeBSD security development fundraiser
Diffstat (limited to 'usr.sbin/portsnap')
-rw-r--r--usr.sbin/portsnap/portsnap/portsnap.sh75
1 files changed, 50 insertions, 25 deletions
diff --git a/usr.sbin/portsnap/portsnap/portsnap.sh b/usr.sbin/portsnap/portsnap/portsnap.sh
index bcf2efc..9c16b1c 100644
--- a/usr.sbin/portsnap/portsnap/portsnap.sh
+++ b/usr.sbin/portsnap/portsnap/portsnap.sh
@@ -309,21 +309,21 @@ update_check_params() {
# (in which case portsnap will use that particular server, since there
# won't be an SRV entry for that name).
#
-# We don't implement the recommendations from RFC 2782 completely, since
-# we are only looking to pick a single server -- the recommendations are
-# targetted at applications which obtain a list of servers and then try
-# each in turn, but we are instead just going to pick one server and let
-# the user re-run portsnap if a broken server was selected.
-#
-# We also ignore the Port field, since we are always going to use port 80.
-fetch_pick_server() {
+# We ignore the Port field, since we are always going to use port 80.
+
+# Fetch the mirror list, but do not pick a mirror yet. Returns 1 if
+# no mirrors are available for any reason.
+fetch_pick_server_init() {
+ : > serverlist_tried
+
# Check that host(1) exists (i.e., that the system wasn't built with the
# WITHOUT_BIND set) and don't try to find a mirror if it doesn't exist.
if ! which -s host; then
- return
+ : > serverlist_full
+ return 1
fi
- echo -n "Looking up ${SERVERNAME} mirrors..."
+ echo -n "Looking up ${SERVERNAME} mirrors... "
# Issue the SRV query and pull out the Priority, Weight, and Target fields.
# BIND 9 prints "$name has SRV record ..." while BIND 8 prints
@@ -332,12 +332,29 @@ fetch_pick_server() {
host -t srv "${MLIST}" |
sed -nE "s/${MLIST} (has SRV record|server selection) //p" |
cut -f 1,2,4 -d ' ' |
- sed -e 's/\.$//' > serverlist
+ sed -e 's/\.$//' |
+ sort > serverlist_full
# If no records, give up -- we'll just use the server name we were given.
+ if [ `wc -l < serverlist_full` -eq 0 ]; then
+ echo "none found."
+ return 1
+ fi
+
+# Report how many mirrors we found.
+ echo `wc -l < serverlist_full` "mirrors found."
+}
+
+# Pick a mirror. Returns 1 if we have run out of mirrors to try.
+fetch_pick_server() {
+# Generate a list of not-yet-tried mirrors
+ sort serverlist_tried |
+ comm -23 serverlist_full - > serverlist
+
+# Have we run out of mirrors?
if [ `wc -l < serverlist` -eq 0 ]; then
- echo " none found."
- return
+ echo "No mirrors remaining, giving up."
+ return 1
fi
# Find the highest priority level (lowest numeric value).
@@ -365,7 +382,9 @@ fetch_pick_server() {
# Pick a random value between 1 and the sum of the weights
SRV_RND=`jot -r 1 1 ${SRV_WSUM}`
-# Read through the list of mirrors and set SERVERNAME
+# Read through the list of mirrors and set SERVERNAME. Write the line
+# corresponding to the mirror we selected into serverlist_tried so that
+# we won't try it again.
while read X; do
case "$X" in
${SRV_PRIORITY}\ *)
@@ -373,6 +392,7 @@ fetch_pick_server() {
SRV_W=$(($SRV_W + $SRV_W_ADD))
if [ $SRV_RND -le $SRV_W ]; then
SERVERNAME=`echo $X | cut -f 3 -d ' '`
+ echo "$X" >> serverlist_tried
break
else
SRV_RND=$(($SRV_RND - $SRV_W))
@@ -380,18 +400,17 @@ fetch_pick_server() {
;;
esac
done < serverlist
-
- echo " using ${SERVERNAME}"
}
# Check that we have a public key with an appropriate hash, or
-# fetch the key if it doesn't exist.
+# fetch the key if it doesn't exist. Returns 1 if the key has
+# not yet been fetched.
fetch_key() {
if [ -r pub.ssl ] && [ `${SHA256} -q pub.ssl` = ${KEYPRINT} ]; then
- return
+ return 0
fi
- echo -n "Fetching public key... "
+ echo -n "Fetching public key from ${SERVERNAME}... "
rm -f pub.ssl
fetch ${QUIETFLAG} http://${SERVERNAME}/pub.ssl \
2>${QUIETREDIR} || true
@@ -411,8 +430,8 @@ fetch_key() {
fetch_tag() {
rm -f snapshot.ssl tag.new
- echo ${NDEBUG} "Fetching snapshot tag... "
- fetch ${QUIETFLAG} http://${SERVERNAME}/$1.ssl
+ echo ${NDEBUG} "Fetching snapshot tag from ${SERVERNAME}... "
+ fetch ${QUIETFLAG} http://${SERVERNAME}/$1.ssl \
2>${QUIETREDIR} || true
if ! [ -r $1.ssl ]; then
echo "failed."
@@ -571,7 +590,9 @@ fetch_snapshot_verify() {
# Fetch a snapshot tarball, extract, and verify.
fetch_snapshot() {
- fetch_tag snapshot || return 1
+ while ! fetch_tag snapshot; do
+ fetch_pick_server || return 1
+ done
fetch_snapshot_tagsanity || return 1
fetch_metadata || return 1
fetch_metadata_sanity || return 1
@@ -619,7 +640,9 @@ fetch_update() {
OLDSNAPSHOTDATE=`cut -f 2 -d '|' < tag`
OLDSNAPSHOTHASH=`cut -f 3 -d '|' < tag`
- fetch_tag latest || return 1
+ while ! fetch_tag latest; do
+ fetch_pick_server || return 1
+ done
fetch_update_tagsanity || return 1
fetch_update_neededp || return 0
fetch_metadata || return 1
@@ -772,9 +795,11 @@ fetch_update() {
# Do the actual work involved in "fetch" / "cron".
fetch_run() {
- fetch_pick_server
+ fetch_pick_server_init && fetch_pick_server
- fetch_key || return 1
+ while ! fetch_key; do
+ fetch_pick_server || return 1
+ done
if ! [ -d files -a -r tag -a -r INDEX -a -r tINDEX ]; then
fetch_snapshot || return 1
OpenPOWER on IntegriCloud