Archive for 2008

The appeal of London

November 22nd, 2008

London, it's a wonderful city. The culture, the entertainment, the architecture. Historical and contemporary at once. Everyone and everything is there.

Oh sure, initial impressions can be disappointing. The drab landmarks of postcard tourism.. the baroque London Bridge, the utterly pointless Tower of London, the entirely forgettable Buckingham Palace, the simplistically named Big Ben, the gaudy Westminster Abbey. Next to Rome or Paris they look almost barbaric, like the Stone Henge next to the Eiffel Tower. But I cannot for a second imagine that someone could come away from London without absorbing the magic and the culture inherent to it. There's something for everyone to love.

The most striking thing about London to outward appearances is the architecture. There is no shortage of classical buildings, but then there is none of modernity either. Soho, Picadilly, Westminster for a bite of classical; St. Paul's, Queen Victoria, Cornhill for the modern. But you don't have to chase it down, architecture is everywhere and the urbanism is top class, it all fits no matter what it is.

Walking around the wide streets there is that feeling of a real metropolis. The streets are buzzing, both motorized traffic and pedestrian. And they do not fall asleep after dark, there are always people. For that warm and cuddly city feeling Oxford Street is a good bet. When you're ready to take a load off, look for a Starbucks (they're everywhere). Then walk across the street to Caffè Nero, a cozy café chain without the fast food atmosphere.

If you're after shopping there is a huge Borders off Oxford Circus, 4 storeys of bookstore. Be there at 9am and you have the whole thing to yourself! And it's well worth it. Books have always been cheaper in England. You can walk out with two shopping bags for the price of a sports jersey or some silly fashion item.

London's subway system is unique and something of a contradiction. When you look at the map you notice that the stations cover the city very laboriously, it's obviously a huge network. But then you enter the underground and everything is so cramp, the passage ways are narrow, there's little space above your head, the platforms are about 4m wide, and the trains themselves are no different, only wide enough for 3 seats and a passage - less than a bus. So why is a network so vast, designed to transport so many people so cramped? And still, the trains run with such regularity that you're never actually obstructed or stalled, it's very efficient. The maximum waiting time in zone 1 is 3 minutes in the daytime.

State instituted paranoia

The one thing that everyone knows about London and Britain nowadays is that it's a surveillance society. I didn't actually take any pictures myself, but I bet I could cover every last site of interest just with the pictures taken for me and of me in every location. I'm not sure whom I have to call to recoup those photos, though. It's no exaggeration, there really is a camera everywhere, and often, several.

All of this for my protection, naturally. The subway is already entirely covered in cameras, but you'll still see signs reading "for your protection we are installing more cameras". Ditto in the commercial realm, the same cameras wrapped in tinted glass (so as to be less obvious) greet you in a café as the ones you see in the street.

London feels like a pretty safe place if it wasn't for the police crawling everywhere. I don't know about you, but seeing a police unit doesn't make me feel particularly safe. Presumably they are on scene to stop, intervene, apprehend, pursue and I don't want to get stuck with a ticket for crossing the street at my own choosing just because the restless cops feel they have to justify their presence somehow.

State instituted paranoia is on show. There's a warning sign on everything to alert you to the magnificent danger. Walking down Horse Guards Road in Westminster I saw an entirely unremarkable statue surrounded by a fence on all sides, with a plaque stating that it would be a criminal act to climb the fence. This kind of thing is systemic, there is so much distrust and hostility in the announcements and signage. A security circus.

The thing is though, I don't think the public is buying it. They are tolerating it, because it hasn't impacted their lives much, but London doesn't strike me as a society in anxiety or panic, far from it. London was the site of a bombing since the era of paranoia ensued, fair enough, but is the solution to that not police work rather than a paranoia epidemic? The public seems to think so. Terrorism is shamelessly used for political currency, as is the current trend. In the same area there's a monument to the Bali bombing victims. Not that Bali was unimportant, but how many other people have died tragically through various other causes in the same period, starting with the civilian casualties caused by the Iraq invasion (concentrate on the territories under British control, say), ending with the armed conflict du jour on the African continent? No political gain from that, so let's not dwell on those shall we.

Left is right, except when it's not

It is so typical of the British to be different. Not different in a useful way, just arbitrarily so. It might be illusions of grandeur over the long lost empire. One of those differences is driving on the other side of the road. Britain is part of a small minority of countries that drive on the left. To what end? Cars have to be built special for those markets. Traffic rules cannot be made universal worldwide. And for what? There is no trade-off to make, it's completely inconsequential which side you take. The only justification is "it must be this way because it's always been this way", which is a popular non-argument.

To the extent that motorized traffic works smoothly on the "left system", it also affects pedestrians. And in London there are some very clear signs that the left system isn't all that smooth. For starters, there's printing on the street at every pedestrian crossing, "look left", "look right", to tell us where the traffic is coming from. I've never seen this anywhere else, and it wouldn't be necessary if people understood how the traffic works.

You would expect that if the Brits are dedicated to the left system then everything would work accordingly. But it doesn't. When you're walking down the street on the right hand side, sometimes you're against the stream, sometimes with it. In the subway, where they have instructions for everything, they often have partitions in the middle of a walkway. In some places the sign says "keep left", in others "keep right". When you get to the escalator, you're supposed to stand on the right, and walk on the left, in blatant contradiction to the left system. The escalators themselves are flimsy on it, sometimes the one going up is on the right, sometimes it's on the left. Sometimes you're coming out of a walkway on the right and crossing over to the escalator on the left, clashing with the people coming down and switching to the right.

havenet: network perimeter test

November 17th, 2008

Network connections fail all the time, we've all been there. There are so many things that can go wrong, the network adapter driver can fail, the dhcp server can revoke the lease, the wifi router can disappear, the routing may be wrong at some point along the line, the dns server can be overloaded, or the remote host may be down. Those are some of the possibilities, and it can be quite a pain to track down the problem.

But the first thing to do is to figure out exactly what is working and what isn't. If you know that much then at least you know where to start. My goal here is to create a fairly simple test to examine the status of the network connection, leading up to a working internet connection. One constraint that I have is that I like it to be portable, so that I can carry it around along with my dotfiles. That means I would like it to work in any location just as long as I can get a shell, it should not require any dependencies.

A fully functional network connection looks like this:

What I do is try to detect the parameters of the network step by step, using the regular tools like route, ifconfig. Once I know what the hosts are, I do a ping. Now, a ping obviously isn't a foolproof test; if you're on a network that doesn't allow outgoing icmp then it's entirely possible that you can tcp out anyway. So what you really should do is tcp on port 80, not ping. But ping is extremely portable, whereas doing a tcp/udp probe is asking a lot more from the environment, needing something like nmap or hping.

Once you've established that the connection is working, and you want to know more about the network, you can go further with something like netscan.

The code is relatively stupid and messy, but that's the way bash is.

# Author: Martin Matusiak <numerodix@gmail.com>
# Licensed under the GNU Public License, version 3


function havenet {
	local init="$(toolsinit)"

	platforminit
	case "$PLATFORM" in
		"Linux")
			echo "Platform: $PLATFORM"
			run_havenet "$init";;
		*)
			echo "Platform: $PLATFORM (local network detection not supported)"
			run_haveinet "$init";;
	esac
}

function haveinet {
	local init="$(toolsinit)"
	platforminit
	echo "Platform: $PLATFORM"
	run_haveinet "$init"
}

function platforminit {
	if $(which uname &>/dev/null); then
		PLATFORM=$(uname 2>/dev/null)
	fi
}

function toolsinit {
	local tools="true"
	local missing=()


	local cmds=(/sbin/route /sbin/ifconfig ping nmap)
	local args=(" -n" "" " -c1 -W2" " -T3")
	local names=(route ifconfig ping nmap)

	local i=-1
	while [ $i -lt $(( ${#names[@]} - 1 )) ]; do i=$(( $i+1 ))
		if [ 0 -eq $(which ${cmds[$i]} &>/dev/null ; echo $?) ]; then
			tools="$tools;local ${names[$i]}=\"${cmds[$i]}${args[$i]}\""
		else
			missing[${#missing[@]}]="${cmds[$i]}"
		fi
	done


	if [ ${#missing[@]} -gt 0 ]; then
		echo -e "Missing tools: ${cred}${missing[*]}${creset}" 1>&2
	fi

	echo "$tools"
}

function run_havenet {

	eval "$@"

	local localranges="169.254 10 172.(1[6-9]|2[0-9]|3[0-1]) 192.168"


	### Scan networks
	
	echo -e "${cyellow} + Scanning for networks...${creset}"
	test=$($route 2>/dev/null | egrep "^[1-9]")
	if [[ $? != 0 ]]; then
		echo -e "    ${cred}none found${creset}"
	else
		local nets=$(echo "$test" | sort | awk '{ print $1 }')
		for net in $nets; do
			local gw=$($route 2>/dev/null | egrep "^$net" | awk '{ print $3 }')
			printf "    ${cgreen}%-15s${creset} ${ccyan}%s${creset}\n" "$net" "/ $gw"
		done

		### Detect ips

		local ips=
		for net in $nets; do
			local r=$(echo $net | sed "s/.0$//g" | sed "s/.0$//g" | sed "s/.0$//g")
			local ip=$($ifconfig 2>/dev/null | grep "inet addr:$r" | sed "s/inet addr:\([0-9.]*\).*$/\1/g")
			ips="$ip $ips"
		done

		echo -e "${cyellow} + Detecting ips...${creset}"
		test=$(echo "$ips" | egrep -v "^[ ]+$")
		if [[ $? != 0 ]]; then
			echo -e "    ${cred}none found${creset}"
		else
			local on_lan=1
			for ip in $ips; do
				printf "    ${cgreen}%-15s${creset}  %s" "$ip" "ping: "
				test=$($ping $ip 2>/dev/null)
				if [[ $? != 0 ]]; then
					echo -e "${cred}failed${creset}"
				else
					local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
					echo -e "${cgreen}$t ms${creset}"
				fi

				### Test ips for lan
				local ip_on_lan=0
				for prefix in $localranges; do
					test=$(echo "$ip" | egrep "^$prefix" 2>/dev/null)
					if [[ $? == 0 ]]; then
						ip_on_lan=1
					fi
				done
				on_lan=$(( $on_lan & $ip_on_lan ))
			done


			if [ $on_lan -eq 1 ]; then
				
				### Detect gateways if on lan

				echo -e "${cyellow} + Detecting gateways (network is local)...${creset}"
				test=$($route 2>/dev/null | grep UG)
				if [[ $? != 0 ]]; then
					echo -e "    ${cred}none found${creset}"
				else
					local gws=$(echo "$test" | awk '{ print $2 }')
					for gw in $gws; do
						printf "    ${cgreen}%-15s${creset}  %s" "$gw" "ping: "
						test=$($ping $gw 2>/dev/null)
						if [[ $? != 0 ]]; then
							echo -e "${cred}failed${creset}"
						else
							local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
							echo -e "${cgreen}$t ms${creset}"
						fi
					done

					### Try inet connection if we have a gateway 
					run_haveinet "$@"
				fi
			else

				### Try inet connection, we're on wan
				run_haveinet "$@"
			fi
		fi
	fi

}


function run_haveinet {

	eval "$@"

	local rootname="A.ROOT-SERVERS.NET."
	local rootip="198.41.0.4"
	
	local dnsport="53"

	local inethosts="yahoo.com google.com"
	local inetport="80"


	### Test inet connection

	echo -e "${cyellow} + Testing internet connection...${creset}"
	echo -en "    ${ccyan}$rootname  ${cgreen}$rootip${creset}   ping: "
	test=$($ping $rootip 2>/dev/null)
	if [[ $? != 0 ]]; then
		echo -e "${cred}failed${creset}"
	else
		local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
		echo -e "${cgreen}$t ms${creset}"
	fi

	### Detect dns

	echo -e "${cyellow} + Detecting dns servers...${creset}"
	test=$(cat /etc/resolv.conf 2>/dev/null | grep ^nameserver)
	if [[ $? != 0 ]]; then
		echo -e "    ${cred}none found${creset}"
	else
		local dnss=$(echo "$test" | awk '{ print $2 }')
		for dns in $dnss; do
			printf "    ${cgreen}%-15s${creset}  %s" "$dns" "ping: "
			test=$($ping $dns 2>/dev/null)
			if [[ $? != 0 ]]; then
				echo -en "${cred}failed${creset}"
			else
				local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
				echo -en "${cgreen}$t ms${creset}"
			fi


			local proto="tcp" ; local udpflags=""
			if [[ `whoami` = "root" ]]; then
				proto="udp"; udpflags="-sU -PN"
			fi
			echo -en "  dns/$proto: "
			test=$($nmap $dns $udpflags -p $dnsport 2>/dev/null)
			if ! echo "$test" | grep "$dnsport/$proto" | grep "open" &>/dev/null; then
				echo -e "${cred}failed${creset}"
			else
				local t=$(echo "$test" | grep "scanned in" | sed "s/^.*in \([0-9.]*\) seconds.*$/\1/g")
				t=$(echo $t*1000 | bc)
				echo -e "${cgreen}$t ms${creset}"
			fi
		done
	fi

	### Test inet dns

	echo -e "${cyellow} + Testing internet dns...${creset}"

	for inethost in $inethosts; do
		printf "    ${cgreen}%-15s${creset}  %s" "$inethost" "ping: "
		test=$($ping $inethost 2>/dev/null)
		if [[ $? != 0 ]]; then
			echo -en "${cred}failed${creset}"
		else
			local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
			echo -en "${cgreen}$t ms${creset}"
		fi

		echo -en "  http: "
		test=$($nmap $inethost -p $inetport 2>/dev/null)
		if ! echo "$test" | grep "$inetport/tcp" | grep "open" &>/dev/null; then
			echo -e "${cred}failed${creset}"
		else
			local t=$(echo "$test" | grep "scanned in" | sed "s/^.*in \([0-9.]*\) seconds.*$/\1/g")
			t=$(echo $t*1000 | bc)
			echo -e "${cgreen}$t ms${creset}"
		fi
	done

}

UPDATE: Replacing with newer version that is a bit more clever.

UPDATE2: Added tool detection and platform detection.

Chuck: properly farsical

November 15th, 2008

A lot of really bad "comedy" movies have been made to portray the despair of suburbia. People whose lives revolve around work in a big supermarket or other chain, empty most of the time, so they try to find something, anything, to distract themselves from the daily routine.

The premise for Chuck is the same. He's a geek, he has a pity-friend geekier than him. He works at a big electronics chain. And he has a "normal" sister who wants him to be "normal".

Then it happens. His old college buddy, a CIA agent gone rogue, sends him a message containing every government secret he's stolen in his "rogueness". Chuck somehow absorbs the whole thing, the computer breaks, and now he's the only one with the secrets. Except he's still the geeky suburbia guy, so two agents from competing agencies show up to make sure nothing "happens" to him. Needless to say, he cannot divulge anything to his sister or his friend, so he has to pretend like nothing has changed. The agents, in turn, get jobs near him and have to fit into the suburban landscape.

You're probably thinking "with a premise like that it could so easily suck". And I'm with you. But it doesn't. Chuck is pretty good in his role, and the whole spying thing is sufficiently farsical to be funny, but not so overdone that it's stupid.

what's in a fixed point?

November 9th, 2008

The fixed point is a very intuitive idea that we know from daily life. It's the notion that if something is a certain way, and you do something to change it, it will change. Some things you can go on changing forever by repeating the same action, but other things reach a limit beyond which repeating the action has no effect. Suppose you are going 50km/h in your car and you step on the brake. The car slows down. You step on the brake again, the car slows down again. But eventually the car will have come to a complete stop and stepping on the brake doesn't do anything anymore. The point at which the action has no effect anymore has a scary math name: a fixed point.

It's easy enough to write a function that finds the fixed point of another function f. You apply f to the argument and you get a value, you apply f to that and you get a value, you apply f to that and you get a value etc. And every time you check if the new value is different from the old. (Or even if it's just sufficiently similar, Newton-Raphson says hello.) Here is how it goes:

fixfinder :: (Eq a) => (a -> a) -> a -> a
fixfinder f arg =
    let val = f arg
    in if val == arg
        then arg
        else (fixfinder f val)

{-
*Main> fixfinder sqrt 68
1.0
-}

We can try it on a function whose fixed point we know, like the square root. Back in school, did you ever hit the square root key on your calculator repeatedly out of shear boredom? Eventually you'd get 1. (You can also take the square root of 0 and get 0, the second fixed point, but that's not particularly exciting.)

So far so good, now comes the mysterious part. The fixed point idea exists in programming, but in a different guise. In Data.Function there is a function called fix. It makes a very odd promise: to find the fixed point of a function without using a value. Que? How can you return the fixed point value (leaving aside for the moment the question of how you can even calculate it) if you don't have a single value to begin with? Heck, without an input value you don't even know what type the output is, if f is a polymorphic function.

fix :: (a -> a) -> a
fix f = f (fix f)

{-
*Main> fix sqrt
*** Exception: stack overflow
-}

The function doesn't look promising at all. It applies f, but there is no termination condition. Once you reach the fixed point (if there is one), how do you stop? It obviously can't figure out the square root function.

It turns out that fix is a trick used to perform recursion in languages that don't have a recursion primitive (ie. the compiler reaches an expression containing the name of the function in its own body and doesn't know what to do). The trick is that you write a function expecting among other things, a function argument (fix). Then, at the point in your function where you need to recurse, you call fix. Fix then calls the function back, so it's a sort of mutual recursion. In pure lambda calculus fix is called the y-combinator. The formula is so ridiculously cryptic that some have taken to tattoo it on their arms, obviously given up on remembering.

So what do you get out of it? Solely the fact that you get around calling the function within itself, from what I can see. And clearly that's all it does too. How do you prevent the seemingly inevitable infinite loop? You put the termination condition in your semantic function. So you write your recursive function exactly the same, but you give it an extra argument, fix. Then, at the point of recursion, instead of calling the function, you call fix. It's so bizarre that I've written out the evaluation sequence to shed some light on it.

Daredevil that I am, I'm using the factorial function. What's happening here, supposedly, is that fix is computing the fixed point of fac. We can then take that result and apply it to a number, it finds the factorial, it doesn't diverge.

What's happening here? It looks like a sort of loop unrolling, which can clearly proceed ad infinitum, were it not for Haskell's lazy nature. And, one can speculate, it's unrolling the recursion exactly the number of times it needs to be expanded (but then again, evaluation with a value already does that), but how could you possibly know that before you have a value to calculate with? It's not actually computing anything, is it? How is this any different from any old recursive function?

What fac really does is take one step toward the factorial. Multiply one factor, then call fix, which calls fac again. Eventually, the termination condition within fac kicks in. But that doesn't mean we've found the fixed point of fac, which is fac(1) = 1 and fac(2) = 2.  In fact, it seems to me we're walking right past these two fixed points, and calling fac one last time with n=0, because how else can fac terminate?

There is a lot more to fixed points, there's even something called a fixed point datatype that my small brain completely fails to comprehend. The most sane description on fix that I found is in the Haskell Book if you want to take a look. I wish you luck.

the cleaning eye

November 6th, 2008

I'm often amazed at our natural ability to handle information. I know that we make a big deal out of google's ability to find things (and it is a bit deal). But our natural ability to contextualize, and just as crucially to hide information, is unlike anything man has built so far. Just imagine what would happen if your brain showed you all the information it has, spread across the living room floor. You would not only completely forget what you were doing, you'd also never be able to find anything ever again.

We have tried to emulate this contextual ability through what we like to call modes, or profiles, or presets. Fancy cars have the ability to tune the ride either for speed, or for comfort. Digital watches have modes of operation, so when you want use the stopwatch all the other displays vanish and you're in stopwatch mode. The idea is that you change one setting, the mode, and that triggers a whole range of sensible contextual settings appropriate to that mode.

There is definitely a lot of modal functionality in our visual perception. For instance, we can't perceive a very wide spectrum of luminosity, so when you go into a dark you room your eyes need to adjust. And in that mode, if you look at something very bright, it will blind you. You won't be able to see anything else. Another example is the way we see patterns. Most of the time, when you have your eyes open, you see the same level of detail all the time. It might be interesting to ask whether your eyes might be seeing more than your brain decides to "show" you. Again, hiding unnecessary information is valuable. But if you really look closely at something, even from the same distance, you begin to notice things that your "regular" vision doesn't see. Little details appear, details that are not generally "important" to the way you look at it, but since you've switched to detail mode, you now see them. Patterns in the material, shadows on an uneven surface, spots where the material is scratched.

I like to call this mode the cleaning eye. Have you ever noticed that when you start cleaning everything looks different? The cleaning eye is one particular mode that has to do with analyzing the surface and spotting things on the surface that are not part of the surface. We are not very sophisticated at this, there is one way to make a determination. It's called the cleaning test. Try to clean it, and if it comes loose, it's dirt. If it's dirt, then you know that everything else on this surface that looks like that is also dirt. This test can give misleading results. (Have you ever used a cleaning liquid that was too potent, and you ended up damaging the surface you were supposed to be cleaning?)

What's interesting to me about the cleaning eye is the emotional responses that go with it. There are two opposing forces. On the one hand, you want to spot dirt, because that's the only way to justify what you're doing. Why am I cleaning this, there's nothing to clean here, what a waste of time. But once you switch to cleaning mode, it doesn't take long before you find dirt, no matter how clean the thing is. So you start cleaning, and once you exhaust the supply of dirt, you move on to another area.

Now comes phase two. Your eyes have been focused on finding dirt for so long that you start noticing that in this new area there are spots of fine dirt that you didn't notice before. You think to yourself huh, that's weird, I didn't see this in the first area I was cleaning. So you go back, and suddenly, there it is. You got the big, obvious specs of dirt, but you missed these smaller ones. Now you have to make a decision. Do I ignore this, and hope that noone else will notice it either, and I'll be in the clear? Or do I do a thorough job and clean as much as I can?

Let's say you choose the latter option. So you're cleaning and it's really getting boring, cause there is so much more fine dirt than there is obvious, big dirt. Emotionally, there is no satisfaction from cleaning, because the more you clean the more details your eyes find that you didn't see before. Once you get rid of the really fine dirt and move on, you invariable notice you missed something over here. And over there. And everywhere.

In theory, the process of cleaning proceeds until there's no more dirt visible. But you'll never get there, because there's always more dirt, smaller dirt, or dirt that won't come off easily. You could clean your bathroom until it's completely pristine, and spend the whole weekend doing that, but would that really make you happy? In a week there will be dirt again, and in a month the dirt will be visible on a regular basis. All this time and effort you spent one weekend, and for what?

The truth, of course, is that it's impossible to get anything completely clean. You would have to actually remove all the molecules that don't belong.

So at some point you reach your limit. That's enough, I'm sick of cleaning. You stop cleaning, you sit back and relax for a minute. You're not feeling happy, because you know there is still more dirt over there. But how long can you go on cleaning? Alright, forget it. Your mind drifts off to something else you'd rather be thinking about. Cleaning starts to fade in your mind. Fifteen minutes later your mind is completely occupied with something else.

Now something interesting happens. Someone goes into the bathroom. Wow, it is really clean in here! Woh, what? You go in yourself. Hey, look at that, I don't remember the last time it was this clean. Interestingly, the pay off comes not from cleaning "until it's clean", but from giving up on it. You switch from cleaning mode and stop using your cleaning eye. Now the image before you is contrasted with the way you remember the bathroom, and you see the difference. Hey, it looks clean.