<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-30244035-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

Posts
Your browser does not support JavaScript. Click to read the latest news.</description><title>Teknicool</title><generator>Tumblr (3.0; @teknicool)</generator><link>http://teknicool.tumblr.com/</link><item><title>The Story of the CD</title><description>&lt;p&gt;CDs are pretty old technology by now, but &lt;a href="http://www.exp-math.uni-essen.de/~immink/pdf/cdstory.htm"&gt;this&lt;/a&gt; story of its development from an engineer&amp;#8217;s point of view is quite interesting.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I was not aware just how much of a flop Laservision was:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt; I started in 1973 working on servo systems and electronics, and we considered that if one could store video with audio information optically then one could also manage audio only. The research management at the time dismissed this idea saying that audio was far too simple, and not worth the effort, so we, at research, left it alone for the time being. And then came the launch of Laservision in 1975, which was a monumental flop. It flopped hugely, and of some 400 players that were sold some 200 were returned because buyers had been under the misapprehension that it would also record programmes - of course it could not.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It&amp;#8217;s also interesting to see this concerning how the size of CDs was decided upon:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;The disk diameter is a very basic parameter, because it relates to playing time. All parameters then have to be traded off to optimise playing time and reliability. The decision was made by the top brass of Philips. &amp;#8216;Compact Cassette was a great success&amp;#8217;, they said, &amp;#8216;we don&amp;#8217;t think CD should be much larger&amp;#8217;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;As it was, we made CD 0.5&amp;#160;cm larger yielding 12&amp;#160;cm. (&lt;strong&gt;There were all sorts of stories about it having something to do with the length of Beethoven&amp;#8217;s 9th Symphony and so on, but you should not believe them.&lt;/strong&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://teknicool.tumblr.com/post/52707474498</link><guid>http://teknicool.tumblr.com/post/52707474498</guid><pubDate>Wed, 12 Jun 2013 00:01:47 +1000</pubDate><category>technology</category></item><item><title>Binary Prefix Names</title><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Binary_prefix"&gt;Binary prefixes&lt;/a&gt; are still not very commonly used, so it&amp;#8217;s no wonder there&amp;#8217;s some confusion about them. For example, I have seen use of the incorrect term &amp;#8220;mibibyte&amp;#8221;. The derivation of the correct names to use is quite simple though.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Each binary prefix is a combination of an SI decimal prefix and the word &amp;#8220;binary&amp;#8221;. To create each prefix, simply take the first two letters of the decimal prefix and append &amp;#8220;bi&amp;#8221;. For example:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;kilo + binary = kibi (so we would have a kibibyte/KiB)&lt;/li&gt;
&lt;li&gt;mega + binary = mebi&lt;/li&gt;
&lt;li&gt;giga + binary = gibi&lt;/li&gt;
&lt;li&gt;tera + binary = tebi&lt;/li&gt;
&lt;li&gt;peta + binary = pebi&lt;/li&gt;
&lt;li&gt;exa + binary = exbi&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;With this rule in mind it&amp;#8217;s easy to make sure that you&amp;#8217;re using the correct names (rare as that use may be).&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/52703378344</link><guid>http://teknicool.tumblr.com/post/52703378344</guid><pubDate>Tue, 11 Jun 2013 22:21:00 +1000</pubDate><category>technology</category></item><item><title>C Facilities in C++: use cname or name.h?</title><description>&lt;p&gt;The C++11 standard defines 25 headers for C standard library facilities (17.6.1.2 part 3). These are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&amp;lt;cassert&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;ccomplex&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cctype&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cerrno&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cfenv&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cfloat&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cinttypes&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;ciso646&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;climits&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;clocale&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cmath&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;csetjmp&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;csignal&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstdarg&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstdbool&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstddef&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstdint&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstdio&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstdlib&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cstring&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;ctgmath&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;ctime&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cuchar&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cwchar&amp;gt;&lt;/li&gt;
&lt;li&gt;&amp;lt;cwctype&amp;gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For each of these headers named in the form c&lt;em&gt;name&lt;/em&gt;, there are equivalent headers named in the form &lt;em&gt;name&lt;/em&gt;.h for compatibility with C (Annex D, section 6).&lt;/p&gt;
&lt;p&gt;The difference between the two is the following (according to Annex D, section 6, part 3):&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;c&lt;em&gt;name&lt;/em&gt;: all of the appropriate names and definitions are placed into the std namespace. Implementations are also free to put the same names and definitions into the global namespace scope.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;name&lt;/em&gt;.h: all of the appropriate names and definitions are placed into the global namespace scope.  Implementations are also free to put the same names and definitions into the std namespace.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I can only imagine that the original motivation for the c&lt;em&gt;name&lt;/em&gt; header variety was to give C++ programs a way to avoid polluting the global namespace. However, since they&amp;#8217;re currently free to introduce all names and definitions into the global namespace scope, they are useless for this purpose.&lt;/p&gt;
&lt;p&gt;Using the c&lt;em&gt;name&lt;/em&gt; headers gives you the following alternatives for portability issues:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;If you develop on a system where c&lt;em&gt;name&lt;/em&gt; headers really do declare everything in the std namespace, you could potentially get clashes later on when you use a perfectly standards-compliant compiler that also puts all of the symbols into the global namespace scope.&lt;/li&gt;
&lt;li&gt;If you develop on a system where all of the names are brought into the global namespace (as well as std) the code could fail to compile on a perfectly standards-compliant compiler that only declares them in std (e.g., if you forget to qualify something with std::).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Using the &lt;em&gt;name&lt;/em&gt;.h variety of the headers, portability issues should only occur in the situation where you develop on a compiler that puts the names into the std namespace, then later on you attempt to use a compiler that only puts them into the global namespace. In this case you could see errors where names were qualified by std::.&lt;/p&gt;
&lt;p&gt;Therefore, it appears the best practice for the moment is probably to ignore the c&lt;em&gt;name&lt;/em&gt; headers and just use &lt;em&gt;name&lt;/em&gt;.h. The only caveat really is that the name.h headers are included as part of the deprecated compatibility features in the standard, so they could disappear in future versions. Their removal would seem unlikely given the compatibility issues it would cause, and in the worst case it&amp;#8217;s not something that would need to be considered until compilers start implementing the next version of the standard.&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/22336375980</link><guid>http://teknicool.tumblr.com/post/22336375980</guid><pubDate>Fri, 04 May 2012 06:31:29 +1000</pubDate><category>c++</category><category>programming</category></item><item><title>What is an inode, and how does it relate to links?</title><description>&lt;p&gt;An inode on a Unix-style filesystem stores metadata for a file, with the filename and data stored elsewhere. This metadata includes things such as the file size, location of the data, owner and permission information, timestamps, etc.&lt;/p&gt;
&lt;p&gt;Each inode is identified by an integer that&amp;#8217;s unique within the filesystem. A directory stores filenames and their corresponding inode numbers.&lt;/p&gt;
&lt;p&gt;So, a hard link is just any standard directory entry that directly maps a filename to an inode number. This is why a hard link cannot cross filesystems, the inode number is only unique on the original filesystem. It&amp;#8217;s also not possible to create a hard link to a directory.&lt;/p&gt;
&lt;p&gt;The data stored in an inode includes a counter giving the number of hard links referring to it. The rm command simply reduces this count by one.&lt;/p&gt;
&lt;p&gt;A symbolic link is quite different to a hard link, it is a special file (or potentially a special directory entry, depending on implementation) that stores a reference to another file as a relative or absolute path. Because of this they can point to files on different filesystems, to directories, or even to targets that don&amp;#8217;t exist. On POSIX systems they aren&amp;#8217;t required to support the full set of file status information of other files. The permissions for a symbolic link will usually apply to just to the actual link itself (e.g., relevant when deleting the link), while access to the referenced data will be controlled by the permissions of the target file.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.linfo.org/inode.html"&gt;&lt;a href="http://www.linfo.org/inode.html"&gt;http://www.linfo.org/inode.html&lt;/a&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.linfo.org/hard_link.html"&gt;&lt;a href="http://www.linfo.org/hard_link.html"&gt;http://www.linfo.org/hard_link.html&lt;/a&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Symbolic_link"&gt;&lt;a href="http://en.wikipedia.org/wiki/Symbolic_link"&gt;http://en.wikipedia.org/wiki/Symbolic_link&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/22316579569</link><guid>http://teknicool.tumblr.com/post/22316579569</guid><pubDate>Thu, 03 May 2012 21:54:42 +1000</pubDate></item><item><title>Throttle Client Connection Rate with iptables</title><description>&lt;p&gt;Unfortunately, a public webserver can get a lot of unwanted or outright malicious connection attempts that slow down access for other users or waste resources. Even my own webserver, which receives very few genuine hits, gets thousands of requests and occasionally denial of service attacks.&lt;/p&gt;
&lt;p&gt;There is, unfortunately, not just a single package you can install or a box to tick to automatically get some defence from denial of service attacks, intrusion detection, automatic filtering of other unwanted traffic, and everything else you might want. There are some programs and projects that are worth investigating for doing some of these things though (e.g. &lt;a href="http://www.rfxn.com/projects/"&gt;R-FX Networks projects such as advanced policy firewall and brute force detection&lt;/a&gt;, &lt;a href="http://www.ossec.net/main/"&gt;OSSEC&lt;/a&gt;, &lt;a href="http://deflate.medialayer.com/"&gt;(D)Dos Deflate&lt;/a&gt;, &lt;a href="http://www.fail2ban.org/wiki/index.php/Main_Page"&gt;fail2ban&lt;/a&gt;). In general though, something like a DDoS could appear the same to the server as a lot of legitimate traffic. You can find a lot of examples of &lt;a href="http://www.itnews.com.au/News/234834,five-ways-to-defend-against-a-ddos-attack.aspx"&gt;methods&lt;/a&gt; &lt;a href="http://www.rackspace.com/managed_hosting/services/security/ddosmitigation/"&gt;to&lt;/a&gt; &lt;a href="http://www.symantec.com/connect/articles/closing-floodgates-ddos-mitigation-techniques"&gt;mitigate&lt;/a&gt; &lt;a href="http://www.dslreports.com/shownews/Experiences-with-DDOS-mitigation-Part-I-93853"&gt;DDoS&lt;/a&gt; attacks on the Internet, but if you&amp;#8217;re just running a small site on a VPS, a lot of these options are not practical.&lt;/p&gt;
&lt;p&gt;In any case, it&amp;#8217;s useful to understand how the Linux kernel firewall is configured using &lt;a href="http://en.wikipedia.org/wiki/Iptables"&gt;iptables&lt;/a&gt;. This is because it&amp;#8217;s used behind the scenes by some of the tools mentioned above, and is available on basically any Linux system without installing extra software. So, we will use iptables to configure the firewall to limit the rate of new connections from each IP address. It could end up being better to do it using one of the tools mentioned above. It won&amp;#8217;t really help much against a DDoS. It could be problematic if a lot of users access the server from behind one IP address (e.g., through a proxy server). In such a case, you might need to &lt;a href="http://www.cyberciti.biz/faq/iptables-invert-ip-or-protocol-with/"&gt;disable&lt;/a&gt; this filtering for such a proxy&amp;#8217;s IP address. However, it is a simple way of stopping a few malicious clients occupying too many of the server&amp;#8217;s resources, without needing to install any extra software.&lt;/p&gt;
&lt;h3&gt;1. Configuration for Custom Firewall Rules&lt;/h3&gt;
&lt;p&gt;This section is OpenSUSE-specific. For other distributions there would be a different way of entering custom iptables commands to be executed during firewall configuration.&lt;/p&gt;
&lt;p&gt;To enter custom firewall rules in OpenSUSE (at least from 11.1 to the latest 12.1, maybe back even further than that) do the following:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;In /etc/sysconfig/SuSEfirewall2, uncomment the line: #FW_CUSTOMRULES=&amp;#8221;/etc/sysconfig/scripts/SuSEfirewall2-custom&amp;#8221;. Make sure to comment out the nearby line FW_CUSTOMRULES=&amp;#8221;&amp;#8220;.&lt;/li&gt;
&lt;li&gt;Now, the custom rules that are described below will be entered into the fw_custom_after_chain_creation function in /etc/sysconfig/scripts/SuSEfirewall2-custom. The rules to enter are described in the next section.&lt;/li&gt;
&lt;li&gt;Once the rules have been entered, run &lt;em&gt;/etc/init.d/SuSEfirewall2_setup restart&lt;/em&gt;. Verify that the new rules have been loaded by running &lt;em&gt;iptables -L&lt;/em&gt;, and checking that the new rules are listed where expected.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;
&lt;h3&gt;2. The iptables Commands&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;The Linux kernel firewall is &lt;a href="http://en.wikipedia.org/wiki/Netfilter"&gt;implemented&lt;/a&gt; using various tables containing chains of rules. As network packets flow through the system and are processed appropriately, there are various stages where they are subject to being tested against a chain of rules from such a table. The predefined tables are:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;filter:&lt;/em&gt; the default table operated on by iptables.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;nat:&lt;/em&gt; only consulted for packets creating a new connection.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;mangle:&lt;/em&gt; used for altering packets.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;raw:&lt;/em&gt; higher priority table used for configuring exemptions from connection tracking.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;div&gt;Each of these tables contains various predefined rule chains, and it&amp;#8217;s possible to add extra rule chains if so desired. For example, the filter table has predefined chains named INPUT (packets are subject to processing using the rules in this chain of the filter table if they&amp;#8217;re destined for an incoming socket), FORWARD (for packets being routed by the machine), and OUTPUT (for locally generated packets). A packet could be subject to processing by multiple rule chains during its lifetime. &lt;a href="http://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Netfilter-packet-flow.svg/2000px-Netfilter-packet-flow.svg.png"&gt;This diagram&lt;/a&gt; is useful for visualising how packets flow through the system and the various filter chains (&lt;a href="http://en.wikipedia.org/wiki/File:Netfilter-packet-flow.svg"&gt;sourced from here&lt;/a&gt;). The network layer is what we&amp;#8217;re most interested in at the moment. You can see the various locations in the dataflow that the predefined chains for each of the tables are traversed. iptables is the userspace command that is used to modify the rules in the chains.&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;So, what actually happens when a packet traverses one of these rule chains? Well, packets are tested against each of the rules in a chain in order. If a match is encountered, then one of the following occurs depending on the target configured for the matching rule:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;&lt;li&gt;The packet can be passed to a user-defined chain for further processing.&lt;/li&gt;
&lt;li&gt;ACCEPT: the packet is allowed to pass through this table towards its destination.&lt;/li&gt;
&lt;li&gt;DROP: the packet is dropped and won&amp;#8217;t be processed any further.&lt;/li&gt;
&lt;li&gt;QUEUE: pass the packet to userspace (see the &lt;a href="http://linux.die.net/man/8/iptables"&gt;iptables man page&lt;/a&gt; for more details).&lt;/li&gt;
&lt;li&gt;RETURN: stop traversing this rule chain and continue processing at the next rule in the calling chain.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;If the end of a built-in chain is reached or a match made to a rule with value RETURN in a built-in chain, the target is determined by the policy for that rule chain.&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;There are also target extensions available when configuring a rule in iptables, so there are more options than just those above. E.g., you can specify a REJECT target, which is the same as a DROP except that an error packet is sent back in response to the rejected packet.&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;So, what we need to do is use iptables to append to an appropriate rule chain. To do this, add the following commands to your iptables script. These commands filter incoming packets for port 80 (the HTTP server):&lt;/div&gt;
&lt;div&gt;
&lt;pre&gt;    #Max connections monitored over this many seconds.&lt;br/&gt;    MAX_CONNECTIONS_PERIOD=30&lt;br/&gt;    #Max connections per IP over the monitored period.&lt;br/&gt;    MAX_CONNECTIONS=7&lt;br/&gt;    #Action to take for blocked connection attempts, should be DROP or REJECT.&lt;br/&gt;    DACTION="DROP"&lt;br/&gt;    #Append to the INPUT chain in the filter table. &lt;br/&gt;    iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --name "HTTPConns" --rcheck --seconds ${MAX_CONNECTIONS_PERIOD} --hitcount ${MAX_CONNECTIONS} -j ${DACTION}&lt;br/&gt;    iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --name "HTTPConns" --set&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;The numbers selected for MAX_CONNECTIONS_PERIOD and MAX_CONNECTIONS are just for testing. You would need to decide on appropriate numbers for your server, but this number of allowed connections is probably too low.&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;So, what are the two iptables commands entered above actually accomplishing? We&amp;#8217;ll start off by looking at the second iptables command in the script. The command breaks down as follows:&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;-A INPUT: this is saying that we wish to append to the INPUT chain in the current table. Because we didn&amp;#8217;t specify a table using -t, it will append to the filter table. So, we&amp;#8217;re going to add a rule to the filter table, and that rule will be appended to the chain that&amp;#8217;s traversed by packets going to local sockets.&lt;/li&gt;
&lt;li&gt;-p tcp: The rule will match packets using the TCP protocol.&lt;/li&gt;
&lt;li&gt;&amp;#8212;dport 80: The rule will match packets destined for port 80.&lt;/li&gt;
&lt;li&gt;-i eth0: The rule will match packets coming through this interface. You may need to modify the command if the traffic will not be coming through eth0.&lt;/li&gt;
&lt;li&gt;-m state &amp;#8212;state new: Specifies that we want to apply some filtering using the &amp;#8220;state&amp;#8221; module, and then indicates that the state module should only let this rule match packets initiating a connection or for which there has only been communication in one direction so far.&lt;/li&gt;
&lt;li&gt;-m recent &amp;#8212;name &amp;#8220;HTTPConns&amp;#8221; &amp;#8212;set: Specifies that we want to apply some filtering using the &lt;a href="http://snowman.net/projects/ipt_recent/"&gt;&amp;#8220;recent&amp;#8221;&lt;/a&gt; module. This module allows us to create and manipulate lists of packet source IPs. Each list entry stores some number of packet arrival times for that IP address (maximum number is 20 by default, see ip_pkt_list_tot on the &lt;a href="http://linux.die.net/man/8/iptables"&gt;man page&lt;/a&gt;). For this command we use &amp;#8212;set mode, which matches all incoming packets, but will cause the source address to be added to such a list (named &amp;#8220;HTTPConns&amp;#8221;). If the source address already exists in the list, the entry is simply updated to record the arrival of this new packet (removing the least recent arrival time if the maximum packet list size limit has been reached).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So, this second command will add a rule that matches packets for new incoming connections to the HTTP server on eth0. When a match occurs it updates or creates an entry for the source IP in a list named &amp;#8220;HTTPConns&amp;#8221;. This rule specifies no target, so whether a match occurs or not will have no impact on the packet&amp;#8217;s eventual fate. However, before a packet can get to the rule added by this command, it must pass through the rule added by the first command, which we&amp;#8217;ll look at now.&lt;/p&gt;
&lt;p&gt;The first command is similar, but the target for matching packets is DROP and different parameters are passed to the &amp;#8220;recent&amp;#8221; module. Those parameters are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&amp;#8212;name &amp;#8220;HTTPConns&amp;#8221;: this is our custom name for the source IP list to operate on.  HTTPConns is just a descriptive name, you can use a different name, or just specify no name to use the default list.&lt;/li&gt;
&lt;li&gt;&amp;#8212;rcheck:  makes it so that this rule will only match if the source address is already in the list. The table access is read-only, no hit will be recorded.&lt;/li&gt;
&lt;li&gt;&amp;#8212;seconds ${MAX_CONNECTIONS_PERIOD}  &amp;#8212;hitcount ${MAX_CONNECTIONS}: restricts the rule to only match when MAX_CONNECTIONS packets arriving within the previous MAX_CONNECTIONS_PERIOD seconds are associated with the list entry for the source IP.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So, the first rule will match packets where a HTTPConns table entry exists for the source address and it records at least MAX_CONNECTIONS hits occurring within the last MAX_CONNECTIONS_PERIOD seconds. When such a match occurs, the packet is dropped. This means that packets initiating new connections will initially pass through the rule added by the first command. The second command will simply register a hit for that source address in the HTTPConns list. However, once the number of new connections from a particular source IP reaches our configured limit for the chosen time period, any new connections will be dropped by the first rule until enough time passes and packets once again begin to pass through to the second rule.&lt;/p&gt;
&lt;div&gt;
&lt;h3&gt;3. Monitoring the Behaviour&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;Using &lt;em&gt;iptables -vL | grep HTTPConns&lt;/em&gt;, we can see the number of packets matching each rule. For example:&lt;/div&gt;
&lt;pre&gt; pkts bytes target     prot opt in     out     source               destination         
    6   360 DROP       tcp  --  eth0   any     anywhere             anywhere            tcp dpt:http state NEW recent: CHECK seconds: 30 hit_count: 7 name: HTTPConns side: source 
 5651  280K            tcp  --  eth0   any     anywhere             anywhere            tcp dpt:http state NEW recent: SET name: HTTPConns side: source 
&lt;/pre&gt;
&lt;div&gt;In this example we can see that 6 packets have been dropped, 5651 accepted.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;We can also view the actual table of source connection state in /proc/net/xt_recent/HTTPConns. In this file we can see which source IPs have an entry, and the times recorded for each update to the table (times are 2^32 + uptime in milliseconds on my system).&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;It&amp;#8217;s also useful to look at the web server&amp;#8217;s access log (with Apache, probably /var/log/apache2/access_log). For Apache, I found it useful to add %k %X %P %D %m to the access_log &lt;a href="http://httpd.apache.org/docs/current/mod/mod_log_config.html"&gt;output format&lt;/a&gt;, to get more information about each access.&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;You can test whether the filtering is working as expected by making connections (e.g., using &lt;em&gt;printf &amp;#8220;GET /\n\n&amp;#8221; | nc server_ip_address 80 -q 10&lt;/em&gt;) and checking that the behaviour is as expected.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;&lt;br/&gt;4. Improvements&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;&lt;li&gt;The above filtering will do nothing to protect against the number of connections from each IP address, it will only limit the rate at which new connections can be made to a sensible maximum. It is therefore also worth looking at the &lt;a href="http://www.cyberciti.biz/faq/iptables-connection-limits-howto/"&gt;connlimit module&lt;/a&gt;. You would not want to reduce the number of active connections by adjusting the keepalive idle timeout in Apache, or the maximum number of keepalive requests it allows per connection, as this would be ineffective and could affect performance for normal traffic.&lt;/li&gt;
&lt;li&gt;You may not want the filtering to apply to connections from some machines (e.g., your administration machine or a particular proxy server). If that&amp;#8217;s the case you could look at white-listing particular source addresses.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><link>http://teknicool.tumblr.com/post/20211649831</link><guid>http://teknicool.tumblr.com/post/20211649831</guid><pubDate>Sat, 31 Mar 2012 16:09:00 +1100</pubDate><category>firewall</category><category>iptables</category><category>linux</category><category>opensuse</category></item><item><title>#Pragma Once is Better Than Include Guards</title><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Include_guard"&gt;Include guards&lt;/a&gt; always seemed like an inconvenient way of making sure header files are only included once to me. Surely it would be better to have a special preprocessor directive to indicate the less common case where you really do want to allow your header to be included multiple times?&lt;/p&gt;
&lt;p&gt;Whatever the case, &lt;em&gt;#pragma once&lt;/em&gt; has existed for a very long time as an alternative to include guards. Why would you want to use it?&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;You can copy and paste it. It&amp;#8217;s inevitable that somebody will copy and paste one header to start writing another and forget to update the include guard symbol.&lt;/li&gt;
&lt;li&gt;Filename-based conventions for include guard symbols can experience conflicts. Additionally, if you want to refactor code and move the location of some files around, you must remember to update the include guards (and inevitably someone will forget).&lt;/li&gt;
&lt;li&gt;Pragma once is fast to type and only one line. You could potentially write a macro or script for your editor to automate insertion of include guards (e.g. create a correct symbol based on the filename or generate a UUID), but it&amp;#8217;s probably wasted time.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;
&lt;div&gt;For whatever reason, use of #pragma once is not especially widespread. There&amp;#8217;s usually no compelling reason not to use it though. Arguments against its use are usually:&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Pragma once isn&amp;#8217;t portable:&lt;/strong&gt; This is virtually never a practical consideration. It&amp;#8217;s supported properly on all common C/C++ compilers. This includes GCC (&lt;a href="http://gcc.gnu.org/gcc-3.4/changes.html"&gt;properly since 2004 with GCC 3.4&lt;/a&gt;), Comeau, Clang, Intel, and Microsoft. By properly, I mean a file is included only once even if it&amp;#8217;s included again through a symbolic or hard link. I would assume virtually any other C/C++ compiler would support this pragma too, or they could be incompatible with code that works on the compilers that get used for virtually everything in the real world.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pragma once can&amp;#8217;t work properly:&lt;/strong&gt; &lt;a href="http://gcc.gnu.org/onlinedocs/gcc-4.6.2/cpp/Alternatives-to-Wrapper-_0023ifndef.html"&gt;GCC&amp;#8217;s documentation&lt;/a&gt; says that the only reason not to use it is because it&amp;#8217;s not standard, so that should be one indication that this argument is false. It works properly unless you go out of your way to break it or have a buggy preprocessor.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;There are two example situations where you could end up breaking pragma once that I can think of, and neither would form the basis of a particularly compelling argument against using it:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;The first example is a code base that contains multiple copies of some headers, where it&amp;#8217;s possible for compilation of a source file to involve including more than one of the copies. &lt;em&gt;#pragma once&lt;/em&gt; will fail because the copies are separate files, where include guards would work because all the copies would check for the same symbol.&lt;/li&gt;
&lt;li&gt;The second example is a code base where it&amp;#8217;s possible for compilation of a source file to involve including the same header multiple times via different links. Use of &lt;em&gt;#pragma once&lt;/em&gt; will cause issues if this code is accessed through or copied onto a file system that doesn&amp;#8217;t support such links (e.g., some network shares, old filesystems) or through a file archive format that doesn&amp;#8217;t support storing it. This is because the different links will now appear to the preprocessor as multiple independent files.&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;The first example is not an argument against pragma once at all. Having multiple copies of the same header is poor from a maintenance point of view and will be less efficient to build than if the header exists in only one location. If multiple copies need to be made for some reason (e.g., some sort of build system?) they should be made as links.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;The second example is a more realistic situation, but in the situations where problems occur (loss of the link information) it degenerates into the same case as the first example. Even if the code duplication isn&amp;#8217;t an issue, the fact that the preprocessor will have to open and process each of the copies is still a consideration.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;br/&gt;It would appear that to use #pragma once without issue you need only comply with the following two guidelines:&lt;/div&gt;
&lt;div&gt;&lt;ol&gt;&lt;li&gt;Don&amp;#8217;t use an obscure compiler or a really old one.&lt;/li&gt;
&lt;li&gt;Don&amp;#8217;t make multiple copies of the same header in your code base. If you really must, do it using symbolic links and don&amp;#8217;t share or distribute the code using a means that doesn&amp;#8217;t support symbolic links.&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Given these very light requirements, there would seem to be no reason not to consign include guards to history for the most part. So far as I&amp;#8217;m concerned, it&amp;#8217;s not worth paying me to spend a second maintaining or generating include guard symbols for virtually no reason. In the very worst case, if one day a code base using &lt;em&gt;#pragma once&lt;/em&gt; needs to have include guards added for some reason, a script to add include guards to every file containing a &lt;em&gt;#pragma once&lt;/em&gt; directive would be relatively easy to write. Therefore, there&amp;#8217;s no opportunity cost in using the extra convenience of &lt;em&gt;#pragma once&lt;/em&gt; now, just the unlikely possibility that a script could need to be written in the future.&lt;/div&gt;
&lt;p&gt;&lt;br/&gt;Links:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/1695807/why-isnt-c-cs-pragma-once-an-iso-standard"&gt;Discussion at StackOverflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://teknicool.tumblr.com/post/19908569863</link><guid>http://teknicool.tumblr.com/post/19908569863</guid><pubDate>Mon, 26 Mar 2012 06:31:00 +1100</pubDate><category>c++</category><category>programming</category></item><item><title>Unsigned is a Special Case</title><description>&lt;p&gt;&lt;span&gt;It does seem that the conventional wisdom nowadays is that unsigned integer types should only be used as a special case. &lt;/span&gt;For example, this is the approach presented in &lt;a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml"&gt;Google&amp;#8217;s C++ style guide&lt;/a&gt;, and for C# and &lt;a href="https://blogs.oracle.com/darcy/entry/unsigned_api"&gt;Java&lt;/a&gt;. I definitely agree with this, but there are developers who insist on using unsigned in C/C++ wherever they think a value won&amp;#8217;t need to be negative as a form of self-documentation. Below are several reasons why I disagree with this approach.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;u&gt;Avoid Mixing of Types&lt;/u&gt;&lt;/span&gt;&lt;br/&gt;In order to avoid having code littered with inconvenient and error-prone casts, implicit signed/unsigned type conversions, comparing signed/unsigned values, and so on, it&amp;#8217;s better to choose to use either signed or unsigned in most code.&lt;/p&gt;
&lt;p&gt;You cannot use unsigned everywhere or restrict signed to special cases. Too many standard APIs return long or int, many more than use unsigned or types such as size_t. Very often you use signed values because you really do want to be able to represent negative values. Even if these requirements don&amp;#8217;t apply to the function you&amp;#8217;re writing, they probably do apply to the code generating the parameters to pass into your function.&lt;/p&gt;
&lt;p&gt;Therefore, it&amp;#8217;s best to use signed types most of the time.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;u&gt;Asserting Value out of Range&lt;/u&gt;&lt;/span&gt;&lt;br/&gt;&lt;span&gt;You cannot rely on overflow of a signed value by 1 giving a negative value, it could very well just go up to a higher value than you thought possible because the compiler decided that behaviour was more efficient to implement (e.g., this might be the case with scalar int32_t arithmetic on a machine with 64b registers). This is because signed overflow is undefined. Unsigned overflow, on the other hand, is defined. E.g., ensuring standards-compliant wrapping for 32b values on a CPU with 64b registers can potentially incur a cost.&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span&gt;Despite this, &lt;/span&gt;the behaviour of signed types is usually useful for quickly detecting bugs for values/arguments expected to be positive. We can easily assert(a_value &amp;gt;= 0). This means we can always detect cases where the value has inadvertently went negative without underflow, and depending on the code that&amp;#8217;s generated we might even detect some over/underflow to negative values. The number of times I&amp;#8217;ve had such assertions pick up an issue quickly during testing, or pick up precondition violations due to bugs in the code calling my functions, is huge.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;For an unsigned integer, because it&amp;#8217;s guaranteed to wrap back to another valid positive value by the C++ standard, all we can really do for function parameters is check against a maximum &amp;#8220;sensible&amp;#8221; value. That&amp;#8217;s definitely not self-documenting behaviour, and deciding on such a value could be problematic. If we do this, we&amp;#8217;ve also likely gained nothing compared to using a signed type. We need to document the maximum allowed value (so we&amp;#8217;ve lost any purported advantage of the unsigned type self-documenting the allowed values) and we need to add an assertion. This is the same as for the signed case, except it&amp;#8217;s fairly likely with a signed value that the caller can avoid a cast, even if it saves no casts inside the function.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Signed Arithmetic is More Intuitive&lt;/u&gt;&lt;br/&gt;&lt;span&gt;Signed values are generally more intuitive to use because we&amp;#8217;re used to being able to use signed values in mathematics. The infinite loop example given in Google&amp;#8217;s style guide (shown below) seems a bit ridiculous, but if you&amp;#8217;ve written enough code it&amp;#8217;s likely you&amp;#8217;ve written something as silly.&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;for (unsigned int i = foo.Length()-1; i &amp;gt;= 0; --i)&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;Usually the bugs that you would encounter are a bit more subtle. E.g., some intermediate calculation encountering underflow somewhere because two values are the wrong way around, and you&amp;#8217;re left to track down where an unexpectedly huge value is originating from.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Given that there&amp;#8217;s likely no advantage in using unsigned in many such cases, why not just use a signed type?&lt;/span&gt;&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;&lt;u&gt;When to use Unsigned Types&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Even if signed types appear best to use as a general integer representation (even when you consider negative values invalid), there are several cases where unsigned types are called for. Some of those are:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Where you need defined over/underflow behaviour. As mentioned before, this is undefined for signed types, so you cannot rely on whatever your compiler happens to do. There are many cases where having such behaviour defined is useful. E.g., you can take the difference between two unsigned values c = (a - b), and even if there&amp;#8217;s underflow you know that (a - c) == b.&lt;/li&gt;
&lt;li&gt;Where you&amp;#8217;re doing bit manipulation and want to avoid sign extension.&lt;/li&gt;
&lt;li&gt;Cases where the extra positive range really is useful. Almost always, if you&amp;#8217;re going so close to the limit of a data type&amp;#8217;s range, you&amp;#8217;d be better off going to a larger type. However, sometimes that&amp;#8217;s not practical. E.g., most integer image components, or file access APIs with only a 32b offset.&lt;/li&gt;
&lt;li&gt;Where you&amp;#8217;re operating on a binary data format that defines unsigned fields, probably because of the above reason.&lt;/li&gt;
&lt;li&gt;There are some situations where use of an unsigned type would allow a compiler to generate more efficient code. E.g., division of an unsigned value by a power of two constant could just be right shift, but for a signed type extra code is needed to handle the negative case. Handling of unsigned 64 bit integers on a 32 bit CPU should be faster than signed. For most code, any performance differences are not significant enough to be worth considering, especially since there are cases where signed values can be more efficient too.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;
&lt;div&gt;The most commonly encountered unsigned type from standard APIs is size_t, which is the type of sizeof(). In general, the approach I use is to cast such values to a signed type as large as ptrdiff_t. This means you can&amp;#8217;t store the the length of a byte array larger than 2GB on a typical 32b compiler. If such a case is a possibility then an alternative must be considered, but in general this convention introduces no restrictions and avoids mixing of signed and unsigned types.&lt;/div&gt;
&lt;p&gt;&lt;span&gt;&lt;u&gt;&lt;br/&gt;Interesting Reads on the Topic&lt;/u&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.airs.com/blog/archives/120"&gt;Signed overflow handling and optimisation in GCC, and discussion of the -fno-strict-overflow option&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://critical.eschertech.com/2010/04/07/danger-unsigned-types-used-here/"&gt;Examples of the error-prone implicit conversion behaviour for C/C++ when mixing signed and unsigned integer types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://teknicool.tumblr.com/post/19874412396</link><guid>http://teknicool.tumblr.com/post/19874412396</guid><pubDate>Sun, 25 Mar 2012 14:41:00 +1100</pubDate><category>c++</category><category>programming</category></item><item><title>Desktop Printers that aren't Laser or Inkjet</title><description>&lt;p&gt;Complete dominance of desktop printing by laser and inkjet is just something I&amp;#8217;d always taken for granted since dot matrix disappeared. Apparently there are other technologies getting around though.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pctechguide.com/52Lasers_LED_printers.htm"&gt;LED printers&lt;/a&gt; have apparently been around since Casio introduced the technology in the mid 1990′s. They’re very similar to laser printers. Both shine light onto a statically charged photosensitive drum. The spots that are exposed to the light reverse their charge. It is these spots that attract the toner, which is then rolled onto the paper. In laser printers there is generally a single laser and a moving lens arrangement that allows the laser to scan across the drum illuminating the desired locations. An LED printer simply has an array of LEDs that is passed over the drum.&lt;/p&gt;
&lt;p&gt;The primary advantage of LED printers over laser is apparently their reduced complexity. The laser mechanism is relatively large and complicated with moving parts, as &lt;a href="http://www.youtube.com/watch?v=5o_Cxndvjbk"&gt;this animation&lt;/a&gt; demonstrates. Because of this LED printers can be smaller and less expensive to manufacture than an otherwise equivalent laser printer. LED printers are also generally considered to have a speed advantage over laser printers. The main disadvantages of the technology are that it’s difficult to pack the LEDs densely enough the match the resolution of the best laser printers, and that there are concerns about some of the LEDs failing over time. However, these issues are apparently not insurmountable as LED printers are sold by companies including Lexmark and &lt;a href="http://www.okidata.com/mkt/html/nf/LED_color.html"&gt;Oki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A much different type of printer is referred to as a &lt;a href="http://www.office.xerox.com/solid-ink/solid-ink-sticks/enus.html"&gt;solid ink printer&lt;/a&gt;, and is sold only by Xerox. The technology was acquired by Xerox when they bought Tektronix, who invented it in 1986. These use crayon-like sticks for colour. The printer melts the sticks and a printhead sprays the melted solid onto a heated drum. The drum is rolled onto the page where the ink solidifies quickly.&lt;/p&gt;
&lt;p&gt;These printers have several peculiar traits. It is easy to see how much of the solid ink is left by opening up the printer, and it is possible to top the supply up at any time while ever there is still space to put in more sticks. Due to the way the colour is applied it can be possible to scratch it back off the page. There are also no empty ink tanks or toner cartridges to dispose of. This has obvious environmental benefits, though the power consumption required to melt the ink counteracts this somewhat. An ink purge is also required if the printer it turned off and the portion of already melted ink in reservoirs is allowed to solidify again, so the printer may need to be left on most of the time to avoid excessive ink consumption. See &lt;a href="http://en.wikipedia.org/wiki/Solid_ink"&gt;here&lt;/a&gt; for more details.&lt;/p&gt;
&lt;p&gt;The solid ink cost per page is reportedly &lt;a href="http://printscan.about.com/b/2010/10/19/xeroxs-solid-ink-keeps-cost-per-page-low.htm"&gt;somewhere between&lt;/a&gt; that of laser and inkjet printers, as is the amount of noise while running and the performance for text (though going closer to laser than inkjet). The print speed in general is good though as the printing is done in a single pass. Graphics are also vibrant, though photo fidelity doesn’t match that of the best inkjets (partially made up for by how much more quickly the printing is finished).&lt;/p&gt;
&lt;p&gt;On the surface, solid ink printers sound like a good compromise between laser and inkjet because they produce sharp text as well as high quality colour graphics at high speed. Given that they’re only made by one company and the cheapest one available is currently &lt;a href="http://www.office.xerox.com/printers/color-printers/colorqube-8570/enus.html"&gt;$599 US&lt;/a&gt; (after a $100 rebate), it’s hard to see these printers replacing laser or inkjet anytime soon, even without considering the power consumption issues. Xerox is promoting these printers as environmentally friendly and &lt;a href="http://www.cnet.com.au/printers/0,239035535,339288553,00.htm" title="CNET article on new Xerox printers."&gt;continuing to develop&lt;/a&gt; the technology, but they also appear to be &lt;a href="http://www.pcworld.com/article/164531/xeroxs_breakthrough_solid_ink_color_printers_should_you_care.html"&gt;focussing more on the high-end section of the market&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It doesn’t exactly look like we’re about to see ink jet or laser disappear, but it seems like there are some interesting alternatives getting around.&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/19741580307</link><guid>http://teknicool.tumblr.com/post/19741580307</guid><pubDate>Fri, 23 Mar 2012 06:30:05 +1100</pubDate><category>printer</category><category>technology</category><category>hardware</category></item><item><title>Super Printer</title><description>&lt;p&gt;The most powerful machine sold by Apple computer in 1985 had pretty impressive specifications by the standards of the day. It had a 12&amp;#160;MHz 68k CPU, 1.5&amp;#160;MB of RAM (1&amp;#160;MB used as a frame buffer), and 512&amp;#160;KB of ROM, all for only $6995 US. This machine was not, however, part of the new Macintosh series. It was a printer.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://docs.info.apple.com/article.html?artnum=112474" title="Laserwriter Specifications"&gt;Laserwriter&lt;/a&gt; was the first printer with a &lt;a href="http://en.wikipedia.org/wiki/PostScript"&gt;Postscript&lt;/a&gt; interpreter. Having a powerful interpreted page description language allowed it to render the sort of documents people could generate in desktop publishing programs, but in order to do it at an acceptable speed and quality the printer needed to be a beast. By today’s standards it wasn’t even all that good, just a 300 DPI laser printer supporting an old version of Postscript. It needs to be put in context though. The HP Laserjet from 1984 ($3495 US) had an 8&amp;#160;MHz CPU and 128&amp;#160;KB of RAM. It printed using the Courier typeface, and when it came to graphics it could manage at best a 75 dpi bitmap around 1 inch square due to memory limitations. Increased memory in the 1985 Laserjet Plus meant graphics performance wasn’t so completely appalling, but it wasn’t until the Laserjet III that advanced features such as text of a size other than 10 or 12 point were supported.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s interesting to see that printing used to be one of the most demanding tasks tackled by desktop computer hardware. When did this change though, because the ability to print complex documents has been taken for granted for a long time now?&lt;/p&gt;
&lt;p&gt;The fastest Macintosh available at the time the Laserwriter was released had only one third as much RAM and only two thirds of its CPU clockspeed. It wasn’t until 1987 that Apple introduced a Macintosh with more CPU power than the Laserwriter. For a time there were even some cheaper Laserwriters in the product line with less CPU power that used a simpler page description language (e.g., the &lt;a href="http://docs.info.apple.com/article.html?artnum=112478" title="IISC Specifications"&gt;Laserwriter IISC&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Things hadn’t changed much by 1991. In October of that year the new Laserwriter (the IIg) was the second fastest machine available from Apple (25&amp;#160;MHz 68030, 5&amp;#160;MB of RAM upgradable to 32&amp;#160;MB), second only to the mighty &lt;a href="http://en.wikipedia.org/wiki/Macintosh_IIfx" title="Wikipedia IIfx"&gt;Macintosh IIfx&lt;/a&gt;. This was not the case by 1994 though. The scale of the change can be seen below by looking at the ratios for clockspeed and RAM between Apple’s highest clockspeed computer and their best printer. The graph plots the best Macintosh specification divided by the best printer specification, so at 1.0 they are equal and above that point the Macintosh is better.&lt;/p&gt;
&lt;p&gt;&lt;img alt="MacVsPrinterChart" src="https://docs.google.com/spreadsheet/oimg?key=0AvNLzeQxLqm0cHVxdjlFQ2FhR3RreVFUODVjc2tUSUE&amp;amp;oid=1&amp;amp;zx=n5z487rvpce0"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="MacVsPrinterTable" src="http://farm8.staticflickr.com/7207/6999709947_e4cb0b18e3.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;The pace of increases in printer computing resources really dropped off during the 1990s, even in 1995 the printers were far less powerful than the computers. It seems that it didn&amp;#8217;t really take that long before the compute requirements were relatively well satisfied.&lt;/p&gt;
&lt;p&gt;There are a lot of other problems like this that are a bit amusing to look back on now. Things have come a long way for audio, for example, to go from PC speaker output and synthesized effects to the host-based user-space floating point audio processing that&amp;#8217;s now used in Windows (though some aspects of the new audio support &lt;a href="http://en.wikipedia.org/wiki/Multimedia_Class_Scheduler_Service"&gt;haven’t been completely without issue&lt;/a&gt;). I imagine it will be a long time before we can think the same thing for problems like realistic 3D graphics processing though.&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/19689322653</link><guid>http://teknicool.tumblr.com/post/19689322653</guid><pubDate>Thu, 22 Mar 2012 06:30:05 +1100</pubDate><category>apple</category><category>printer</category><category>technology</category><category>cpu</category></item><item><title>Next Gen Console Graphics</title><description>&lt;p&gt;There have recently been rumours about the new XBox surfacing on the Internet. Maybe they&amp;#8217;re not even pure fantasy. The &lt;a href="http://au.ign.com/articles/2012/01/24/xbox-720-will-be-six-times-as-powerful-as-current-gen"&gt;latest report&lt;/a&gt; is that the graphics are expected to be approximately AMD Radeon 6670 level, around six times faster than the XBox 360′s graphics and around 20 percent faster than Wii U. We can be fairly sure it’s &lt;a href="http://www.techradar.com/news/gaming/consoles/amd-xbox-720-graphics-will-equal-avatar--980233"&gt;something from AMD&lt;/a&gt;, but it’s worth considering this claim further.&lt;/p&gt;
&lt;p&gt;To begin with, let’s look at the reported claims compared to &lt;a href="http://en.wikipedia.org/wiki/Xenos_(graphics_chip)"&gt;XBox 360′s Xenos&lt;/a&gt; and the Wii U’s GPU. Details of the XBox 360′s GPU are well-known. We’ll just have to go on the rumours for the other two. The Wii U is supposed to be using a Radeon 4000 series GPU with &lt;a href="http://translate.google.com/translate?js=n&amp;amp;prev=_t&amp;amp;hl=en&amp;amp;ie=UTF-8&amp;amp;layout=2&amp;amp;eotf=1&amp;amp;sl=ja&amp;amp;tl=en&amp;amp;u=http%3A%2F%2Fgame.watch.impress.co.jp%2Fdocs%2Fseries%2F3dcg%2F20110611_452478.html"&gt;about 1 TFLOPS throughput&lt;/a&gt;, most often speculated to be Radeon HD 4850 level (RV770). Something similar to the slightly newer &lt;a href="http://techreport.com/articles.x/16820"&gt;Radeon HD 4770 &lt;/a&gt;(which was about the same performance and around half the size due to using 40nm fabrication process instead of 55nm), would seem more likely though, so we’ll use the specifications for it instead. For the new XBox, we’ll just assume something identical to a Radeon HD 6670.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_m16regvWOU1r9tbbl.png"/&gt;&lt;/p&gt;
&lt;p&gt;Sources: &lt;a href="http://en.wikipedia.org/wiki/Xenos_(graphics_chip)"&gt;1&lt;/a&gt;, &lt;a href="http://www.anandtech.com/show/2682/4"&gt;2&lt;/a&gt;, &lt;a href="http://www.anandtech.com/show/3774/welcome-to-valhalla-inside-the-new-250gb-xbox-360-slim"&gt;3&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Comparison_of_AMD_graphics_processing_units"&gt;4&lt;/a&gt;, &lt;a href="http://www.beyond3d.com/content/articles/4/3"&gt;5&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are a few noticeable things here. Firstly, the 6670 is not really any better than a 4770 as a chip. It’s smaller, lower power, and has less shader processing power, but generally has a performance advantage that would appear mostly due to extra memory bandwidth. On PC it’s generally a little faster in benchmarks published on the Internet (e.g., for 3DMark Vantage GPU score &lt;a href="http://www.guru3d.com/article/radeon-hd-6670-review/5"&gt;about 13% faster&lt;/a&gt;, &lt;a href="http://www.hwcompare.com/10907/radeon-hd-4770-vs-radeon-hd-6670-oem-1gb/"&gt;around 26% faster in Mafia 2&lt;/a&gt;). So, approximately 20% faster than Wii U would seem within the realm of possibility based on these two GPUs. Given that the memory used in the consoles could be markedly different to that on the desktop cards though, it’s difficult to say.&lt;/p&gt;
&lt;p&gt;As for being six times faster than the XBox GPU, it’s hard to see that happening. The FLOPS rating is a bit over three times higher, and that’s where the largest difference occurs. There may be some way you could work it out to be six times for some particular operation, but in general it doesn’t appear you could expect anything like six times higher frame rates for the same output. This part of the rumour was always questionable though, since it would imply that the Wii U’s GPU is five times faster than the XBox 360 too, and nobody has been claiming that. Nintendo’s&lt;a href="http://www.youtube.com/watch?v=Shch7LNkVXw"&gt; tech demos&lt;/a&gt; appear a little bit better than what current consoles can do at 720p, but presumably running at 1080p (e.g., look at &lt;a href="http://www.youtube.com/watch?v=3WqNMgdzzjU&amp;amp;t=1m7s"&gt;how well&lt;/a&gt; Uncharted compares to the Wii U tech demo).&lt;/p&gt;
&lt;p&gt;So it would seem that, assuming this rumour isn’t a complete fabrication, the big news is that Microsoft is likely aiming to update the console to have moderately better graphics (as opposed to the big step between previous generations) and a standard resolution of 1080p, while also keeping costs and power consumption low. It would come out about a year after the Wii U, and be a little bit more powerful (at least in terms of GPU). This is a large difference to the approach of PS3 and XBox 360, which were about as powerful as they could be within the amount of money people would reasonably pay for a console.&lt;/p&gt;
&lt;p&gt;The difference in games should definitely be noticeable, but in a way it’s disappointing to think how much further they might have went. For example, a Radeon HD7770 would be about the same die area as the XBox 360′s parent GPU was at launch, and it would really bring a big performance jump (it probably really would be six times faster than the XBox 360). The increase in software development budgets to fully exploit such power, as well as a desire for Microsoft to compete on price against the Wii U, would be factors potentially working against such a machine.&lt;/p&gt;
&lt;p&gt;It the next XBox were to come out with a 6670 level of graphics processing power, it would leave the door open for Sony to come along and greatly surpass the performance of everyone else. In that case it might be risky for Sony to come out with a significantly more expensive console and take on larger software development budgets, though. Most likely, Sony would end up targeting a similar cost level.&lt;/p&gt;
&lt;p&gt;If this rumour does turn out to be true, it will also have an impact on PC gaming. PC graphics have stagnated a bit as the content for most games is shared with the console versions. A relatively moderate improvement in the graphics performance for next generation consoles would mean only a relatively moderate improvement in the appearance of cross-platform games. That would be a disappointment, since many PCs are already far more powerful than a Wii U. &lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/19636401470</link><guid>http://teknicool.tumblr.com/post/19636401470</guid><pubDate>Wed, 21 Mar 2012 06:30:00 +1100</pubDate><category>xbox</category><category>wii</category><category>amd</category><category>radeon</category><category>technology</category></item><item><title>Hibernate Broken in Windows after Installing Linux</title><description>&lt;p&gt;Recently, hibernate stopped working in Windows on my laptop. It turned out the problem was caused by the way that OpenSUSE was installed.&lt;/p&gt;
&lt;p&gt;It appears that Windows tries to make resuming from hibernate as seamless as possible. This involves making it so that when you turn the computer back on, it automatically boots back into the same Windows installation (if you have more than one) and restores from the hibernation file. This seems like a reasonable idea. It prevents changes being made from another OS installation that could cause restoration issues (the volume is also marked as “in use” to try to stop such changes). Having the computer automatically restore back to its original state also makes hibernation seem more like other sleep states from the user’s point of view.&lt;/p&gt;
&lt;p&gt;The problem occurs when the hard disk’s active partition doesn’t contain a Windows installation. In such a situation, Windows (at least Windows Vista) decides that it cannot hibernate safely because it cannot make sure that the system will go back to its original state when it’s turned back on. Unfortunately, it doesn’t give any indication of this to the user. When you choose to hibernate it starts the operation, then just presents you with the login screen as if you chose “Switch User” instead.&lt;/p&gt;
&lt;p&gt;The default installation options for OpenSUSE resulted in the Linux root partition getting marked as active, so this is what made hibernation stop working in Windows Vista. It’s fairly easy to fix the problem though.&lt;/p&gt;
&lt;p&gt;Note: be very careful adjusting these options and have a boot DVD on hand, because if something doesn’t work out you might end up with a system that won’t boot at all.&lt;/p&gt;
&lt;p&gt;To fix the problem, you need to adjust how the boot loader is installed. If you’re using SUSE, this is quite easy. Just boot into SUSE and open YaST. Open the Boot Loader options. Press on the Boot Loader Installation tab. Make sure “Boot Loader Type” is set to GRUB. Under ”Boot Loader Location”, make sure ”Boot from Master Boot Record” is checked and make sure that “Boot from Boot Partition”, “Boot from Extended Partition”, and “Boot from Root Partition” are all unchecked. This was all I needed to change. Press OK and after it finishes writing the new configuration check that your system can still boot back into Linux and Windows OK. If it can, then all you need to do now is mark the Windows system partition as active again.&lt;/p&gt;
&lt;p&gt;To mark a partition as active in Windows, you can use the disk management section of the computer management administrative tool. Make sure you only do this &lt;strong&gt;after &lt;/strong&gt;making the changes to the bootloader installation described above, or you won’t be able to boot into Linux anymore (though at least hibernate will work). Windows will not allow you mark any Linux partition as active because it thinks they don’t have a bootable system on them. It’s also possible to mark a partition as active using parted in Linux (or the gparted GUI).&lt;/p&gt;</description><link>http://teknicool.tumblr.com/post/19605987707</link><guid>http://teknicool.tumblr.com/post/19605987707</guid><pubDate>Tue, 20 Mar 2012 12:51:00 +1100</pubDate><category>linux</category><category>opensuse</category><category>windows</category><category>hibernate</category></item></channel></rss>
