[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Processed: destruction of round-robin functionality is fucking up our mirrors and making Debian suck for many people, hence fixing this is a release-critical "wish"



On Sun, Dec 16, 2007 at 06:07:24PM +1000, Anthony Towns wrote:
> Ah, like that. Attached.
> $ ./rule9-prediction.py ftp.us.debian.org

No, really.

Cheers,
aj

#!/usr/bin/env python

import socket, sys

def ip2bits(ip):
    return "".join(
        [ "".join(
		[ ("%d" % (int(x*(2**-y)) % 2)) for y in range(7,-1,-1) ] )
        for x in [ int(x,10) for x in ip.split(".") ] ] )

def bits2ip(bits):
    return ".".join([ "%03d" % (int(bits[x*8:x*8+8],2)) for x in range(4) ])

def iprange(prefix):
    lo = bits2ip( (prefix + "0"*32)[:32] )
    hi = bits2ip( (prefix + "1"*32)[:32] )
    if hi == "255.255.255.255":
      nx = ""
    else:
      nx = bits2ip( (prefix[:prefix.rfind("0")] + "1" + "0" * 31)[:32] )
    return (lo, hi, nx)

ips = []
for arg in sys.argv[1:]:
    ips.extend( [ (x[4][0], ip2bits(x[4][0]))
		 for x in socket.getaddrinfo(arg, "http") ] )
ips.sort( lambda x,y: cmp(x[1], y[1]) )

if ips == []:
    print "Usage: %s host|address host|address..." % sys.argv[0]
    sys.exit(1)

working = [ ("", [b for ip,b in ips]) ]
result = []
while len(working) > 0:
    newworking = []
    for (prefix, ips) in working:
        if len(ips) == 1: 
            result.append( (prefix, ips) )
            continue
        prefixL = prefix + "0"
        prefixR = prefix + "1"
        ipsL = []
        ipsR = []
        for ip in ips:
            if ip.startswith(prefixL): 
               ipsL.append(ip)
            else:
               ipsR.append(ip)

        if ipsL == []:
            result.append( (prefixL, ips) )
        else:
            newworking.append( (prefixL, ipsL) )

        if ipsR == []:
            result.append( (prefixR, ips) )
        else:
            newworking.append( (prefixR, ipsR) )
    working = newworking 

result.sort(lambda x,y: cmp(x[0], y[0]))

prefix, ips = result[0]
lo, hi, nx = iprange(prefix)
for p2, ips2 in result[1:]:
    l2, h2, n2 = iprange(p2)
    if nx != l2:
        print "OUT OF ORDER"
        sys.exit(1)
    if ips != ips2:
        print "%15s-%15s: %s" % (lo, hi, ", ".join([bits2ip(b) for b in ips]))
        lo, hi, nx, ips = l2, h2, n2, ips2
    else:
        hi, nx = h2, n2

print "%15s-%15s: %s" % (lo, hi, ", ".join([bits2ip(b) for b in ips]))

Attachment: signature.asc
Description: Digital signature


Reply to: