<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Real-Time Web Log</title>
	<atom:link href="http://canonical.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://canonical.wordpress.com</link>
	<description>Content-free</description>
	<lastBuildDate>Sat, 18 Apr 2009 06:48:56 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
		<url>http://www.gravatar.com/blavatar/3d5925bf4cb1b6c0336888fe047e797e?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Real-Time Web Log</title>
		<link>http://canonical.wordpress.com</link>
	</image>
			<item>
		<title>Simple CouchDB: Feed Caching</title>
		<link>http://canonical.wordpress.com/2009/02/25/simple-couchdb-feed-caching/</link>
		<comments>http://canonical.wordpress.com/2009/02/25/simple-couchdb-feed-caching/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 04:42:13 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=79</guid>
		<description><![CDATA[For those of you that haven&#8217;t heard of CouchDB, it is a document-oriented database system unlike MySQL or PostgreSQL aimed at solving certain problems differently and often more elegantly than its RDBMS counterparts. I won&#8217;t go into any more detail than that.
In designing and mocking up a site that consumes RSS/Atom feeds, I wanted to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=79&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>For those of you that haven&#8217;t heard of <a href="http://couchdb.apache.org">CouchDB</a>, it is a document-oriented database system unlike MySQL or PostgreSQL aimed at solving certain problems differently and often more elegantly than its RDBMS counterparts. I won&#8217;t go into any more detail than that.</p>
<p>In designing and mocking up a site that consumes RSS/Atom feeds, I wanted to come up with a very simple solution for deployment that didn&#8217;t involve caching in the same way I had been caching some other data objects. I didn&#8217;t want to have the user trigger a cache replacement for a few reasons (I&#8217;ll talk about them a little). First, a few solutions you might come up with:</p>
<p><strong>Just pull the feed when the page gets hit.</strong></p>
<p>This is not really an appropriate solution unless the feed you are consuming is inside your organization or something to that effect. I think this realization is obvious to most people, but it&#8217;s certainly the easiest way of doing things, so I can&#8217;t help but wonder how many sites try this.</p>
<p><strong>Pull the feed once and cache it for some length of time.</strong></p>
<p>This works better than the first solution. I think it&#8217;s passable, but it still suffers from some weaknesses that are dealbreakers for many people. First of all, what if the target site goes down? Aside from the usual error-handling code, you&#8217;ll need to make sure you don&#8217;t stick failed results in your cache. One nasty issue that might bite you here is that if the cache TTL expires triggering a cache miss and pulling a fresh feed when the target site is down, suddenly all of your other visitors are going to miss against the cache and, depending on your backend, you might not even be able to pull stale results because they have been invalidated by the expired TTL.</p>
<p><strong>Pull the feed periodically and fetch it from your local store.</strong></p>
<p>This is the situation for which I&#8217;m employing CouchDB.</p>
<p>What&#8217;d I do?</p>
<ol>
<li>Wrote a short script that can be run from cron to fetch the feeds I want. This ended up being 60 lines with comments and error handling, without any CouchDB libraries.</li>
<li>Used <a href="http://wiki.apache.org/couchdb/Formatting_with_Show_and_List">_show</a> to set up a &#8220;view&#8221; whereby my client could simply request the feed from CouchDB in exactly the same way as it would request a view from the actual URI. Not even simple JSON decoding is needed by the client, just point your feed consuming library at the URI. I can&#8217;t stress enough how cool this is.</li>
</ol>
<p>Because URIs for feeds are unique, each of my feeds could even use its URI as the id in the database! Perfect. When a remote feed goes down, the cron fetcher skips updating that feed and the feed simply doesn&#8217;t get refreshed for the length of the downtime. No extra error handling needed beyond the usual. The implementation ends up being dead simple, fast, and (because of CouchDB) scalable if you need it.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=79&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2009/02/25/simple-couchdb-feed-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>PHP tip: LimitIterator</title>
		<link>http://canonical.wordpress.com/2009/01/25/php-tip-limititerator/</link>
		<comments>http://canonical.wordpress.com/2009/01/25/php-tip-limititerator/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 02:43:11 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=64</guid>
		<description><![CDATA[If you&#8217;ve ever found yourself writing the anti-pattern:

$i = 0;
foreach ($iterable as $element) {
    if ($i &#62;= 5)
        break;

    $element-&#62;doStuff();
    $i++;
}

You might be able to make use of PHP&#8217;s SPL:

foreach (new LimitIterator($iterable, 0, 5) as $element) {
   [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=64&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>If you&#8217;ve ever found yourself writing the anti-pattern:</p>
<pre>
$i = 0;
foreach ($iterable as $element) {
    if ($i &gt;= 5)
        break;

    $element-&gt;doStuff();
    $i++;
}
</pre>
<p>You might be able to make use of PHP&#8217;s <a href="http://www.php.net/~helly/php/ext/spl/">SPL</a>:</p>
<pre>
foreach (new LimitIterator($iterable, 0, 5) as $element) {
    $element-&gt;doStuff();
}
</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=64&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2009/01/25/php-tip-limititerator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>Simple Oracle Instant Client Installation on Debian Linux</title>
		<link>http://canonical.wordpress.com/2009/01/04/simple-oracle-instant-client-installation-on-debian-linux/</link>
		<comments>http://canonical.wordpress.com/2009/01/04/simple-oracle-instant-client-installation-on-debian-linux/#comments</comments>
		<pubDate>Sun, 04 Jan 2009 11:25:38 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=24</guid>
		<description><![CDATA[Introduction
I&#8217;ve found that the documentation for getting this working is lacking, probably because not all that many people have to do it. Most related links would lead you to believe the process involves Makefile hacks, library shuffling, and any number of difficult-for-the-next-guy-to-reproduce (might be you!) steps. My main goal in writing this is to make [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=24&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h2>Introduction</h2>
<p>I&#8217;ve found that the documentation for getting this working is lacking, probably because not all that many people have to do it. Most related links would lead you to believe the process involves Makefile hacks, library shuffling, and any number of difficult-for-the-next-guy-to-reproduce (might be you!) steps. My main goal in writing this is to make it as simple as possible, but no simpler. Additionally, I&#8217;d like as much as possible to explain <strong>why</strong> I chose to do something along with <strong>how</strong> I chose to do it.</p>
<p>As the post title implies, this is Debian-specific, though I&#8217;ve used several other distributions and I see no reason why this post can&#8217;t be fairly simply adapted to them. Leave me a comment if these instructions are useful to you and especially if you were able to get it working with another distribution.</p>
<h2>What You&#8217;ll Need</h2>
<p>The Oracle Instant Client is distributed <a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html">here</a> as a binary package. Navigate to the <strong>Platform Downloads</strong> section and pick out your architecture. I used the <strong>Basic Lite</strong> because I do not need translations, but you could just as easily use the <strong>Basic</strong> package if you do. You will also need the <strong>SDK</strong> package if you want anything else to be able to use the Instant Client. I do, because I want to set up Perl and PHP to use the Instant Client. Additionally, I need the <strong>SQL*Plus</strong> package to do simple administrative tasks for our department such as password changes. This may not be something you need. If not, you can safely leave it out. Download the RPMs, and you&#8217;re on your way.</p>
<p>One neat trick if you&#8217;re like me and don&#8217;t want to set up an Oracle account is to use a service called <a href="http://www.bugmenot.com/">BugMeNot</a> to use an account that someone else has set up. <strong>profile.oracle.com</strong> seems to have the accounts that worked for me. If you like the service, don&#8217;t ruin it for everyone else by doing stupid things with the account. If you want to create an account, you can easily do that instead.</p>
<h2>Installation</h2>
<p>Now that you have the RPMs you need, we&#8217;ll convert them into packages that Debian can use. This will make it easier to do package management. Use a utility called <code>alien</code> to convert the RPMs into <code>.deb</code> packages that you can then install using <code>dpkg</code>. If you don&#8217;t have <code>alien</code>, <code>apt-get install alien</code>.</p>
<p><code><br />
# Replace the filename with the RPM you want to convert.<br />
# You can specify multiple RPMs with one command if you have them.<br />
alien oracle-instantclient-foo.rpm<br />
</code></p>
<p>Now that you have the packages:</p>
<p><code><br />
# Do this for all of your packages.<br />
dpkg -i oracle-instantclient-foo.deb<br />
</code></p>
<p>and now they&#8217;re installed!</p>
<h2>Configuration</h2>
<p>The next step is to configure Oracle&#8217;s <code>tnsnames.ora</code>, which tells Oracle a little bit about the database(s) you&#8217;ll be connecting to. This will be site-specific. Before I go any farther, I&#8217;d like to define something I&#8217;ll use from here on out: <code>ORACLE_HOME</code>. This allows me to refer to that, wherever it may be on your system. By default, my Debian systems (both Etch and Lenny) put the Instant Client in <code>/usr/lib/oracle/{version}/client</code> (64-bit systems will have <code>client64</code> instead of <code>client</code>). <strong>Anywhere you see this in my post, replace <code>ORACLE_HOME</code> with your local path to the Instant Client</strong>. That said, you will now put your <code>tnsnames.ora</code> file into <code>ORACLE_HOME/network/admin/tnsnames.ora</code>. Ask your local DBA for help with this part if you don&#8217;t know what I&#8217;m talking about.</p>
<p>Essentially, you&#8217;re done with the required parts! Easy, wasn&#8217;t it? Now, if you want <strong>SQL*Plus</strong> to work, you&#8217;ll probably need to tell the linker where to find the Oracle libraries, since they aren&#8217;t on the linker path by default. On a Debian system, the linker looks in <code>/etc/ld.so.conf.d</code> for files that it can source. To make my local changes easy to reproduce, I made a new file called <code>oracle.conf</code> and placed it in <code>/etc/ld.so.conf.d</code>. All this file contains is:</p>
<p><code><br />
ORACLE_HOME/lib<br />
</code></p>
<p>Then, run <code>ldconfig</code> with no arguments to get the linker to source the files, and you&#8217;re set. Now, you&#8217;re ready to test it! Simply type</p>
<p><code><br />
ORACLE_HOME/bin/sqlplus<br />
</code></p>
<p>and you should be able to go about your normal Oracle administration. Have fun!</p>
<p>When I tried this for the first time, I got some complaints about <code>libaio</code>. If you see similar complaints after trying to run <code>sqlplus</code>, try:</p>
<p><code><br />
apt-get install libaio1<br />
</code></p>
<p>to install the asynchronous I/O libraries.</p>
<h2>Finishing Touches</h2>
<p>The Oracle Instant Client is an interesting beast since it requires an <code>ORACLE_HOME</code> environment variable to operate. My database connection libraries inject that appropriate environment variable when an Oracle database is connected to. If you don&#8217;t do something like this, your connections will fail. Optionally, you can do other things such as add this to Apache&#8217;s environment so it will always be available, or you can place this environment variable in the environment of users that run certain scripts.</p>
<h2>Optional: PHP Integration</h2>
<p>We&#8217;ll be installing the OCI8 module for PHP. You&#8217;ll need to make yourself root for this. You&#8217;ll also need to have installed the <strong>SDK</strong> mentioned earlier, and probably have <strong>gcc</strong> and <strong>make</strong> installed.</p>
<p><code><br />
cd /usr/local/src<br />
pecl download oci8<br />
zcat oci8-version.numbers.here.tgz | tar xvf -<br />
cd oci8-version.numbers.here<br />
# For the phpize step, you might have to install php5-dev<br />
# if it doesn't already exist.<br />
phpize<br />
# Remember, replace ORACLE_HOME with your ORACLE_HOME!<br />
./configure --with-oci8=instantclient,ORACLE_HOME/lib<br />
make<br />
make install<br />
</code></p>
<p>Next, you&#8217;ll need to make sure your newly installed PHP module gets loaded when Apache starts up. You do this by adding a file to <code>/etc/php5/conf.d</code> called <code>oci8.ini</code> (or anything, really) and make sure it contains the line:</p>
<p><code><br />
extension=oci8.so<br />
</code></p>
<p>Restart Apache and you should be good to go.</p>
<h2>Optional: Perl Integration</h2>
<p>You&#8217;ll need to make yourself root. You might also need the <strong>gcc</strong> and <strong>make</strong> packages if you don&#8217;t have them already on your system. To reduce confusion because of the literal <code>ORACLE_HOME</code> environment variable, I&#8217;m using the more generic path. The <code>ORACLE_HOME</code> that follows is literally the environment variable you need to set.</p>
<p><code><br />
# The following two lines are needed by the installer so that it builds<br />
# the module against the correct Oracle libraries. This is also useful<br />
# if you need to build the module against different versions.<br />
# Remember to replace {version} with the version you want to<br />
# build against.<br />
export ORACLE_HOME=/usr/lib/oracle/{version}/client<br />
export LD_LIBRARY_PATH=${ORACLE_HOME}/lib<br />
# The following line does the same thing as a normal CPAN install<br />
# (e.g. cpan DBD::Oracle) except it does not require the tests to<br />
# pass, because they won't pass (the database credentials the<br />
# test uses are always invalid). Check the output of the test runner<br />
# though, because you want the first test (loading the module) to<br />
# pass, even if the rest fail.<br />
perl -MCPAN -e "CPAN::Shell-&gt;force(qw(install DBD::Oracle));"<br />
</code></p>
<h2>Conclusion</h2>
<p>This should get you well on your way. If any of this looks confusing, it&#8217;s probably just because I wrote a lot. Setting up everything described in this post can only take 5-10 minutes if executed reasonably quickly.</p>
<p>Please leave comments if this was helpful to you or if you have places where I can explain myself better or am just flat out wrong. Good luck!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=24&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2009/01/04/simple-oracle-instant-client-installation-on-debian-linux/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>Using flags for language choice</title>
		<link>http://canonical.wordpress.com/2008/10/27/using-flags-for-language-choice/</link>
		<comments>http://canonical.wordpress.com/2008/10/27/using-flags-for-language-choice/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 07:25:35 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=20</guid>
		<description><![CDATA[I ran across a post recently about using flags in your UI as a way for a user to select the language of the text (and possibly UI direction). While I agree with the post, the main point that drives me to use text in the native language as the way to choose the native [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=20&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I ran across a <a href="http://css.dzone.com/news/you-should-never-use-flags-for">post</a> recently about using flags in your UI as a way for a user to select the language of the text (and possibly UI direction). While I agree with the post, the main point that drives me to use text in the native language as the way to choose the native language could be emphasized more as a way to help people think about what a flag represents as opposed to what a language name represents.</p>
<p><strong>A national flag represents a nation (country). A language name represents a language.</strong></p>
<p>Take a look at <a href="http://www.youtube.com/">YouTube</a> or <a href="http://news.google.com/">Google News</a>. YouTube best illustrates this point. Take a minute and visit the homepage, and check out the country and language selections at the top. Both flags <strong>and</strong> language names are used! Google News takes a similar approach, except without the use of flags at all, instead opting to use the name of the country. This illustrates the point I think should be clearer. When I click on the flag of Germany in YouTube&#8217;s UI, I now get content primarily from Germany, but my UI is still in English. When I click on <i>Deutsch</i>, I get a German user interface. I can also have a German user interface with content from or relevant to France. I don&#8217;t think there&#8217;s anything necessarily wrong or confusing with switching the user&#8217;s interface to the <i>language most likely to be used</i> in the country that the content is primarily from, but that really depends on your users. Of course, so does everything, and if your users want flags to represent languages, that&#8217;s what they&#8217;ll get, and nobody on the internet is going to convince them otherwise :)</p>
<p>Summary of my personal uses:</p>
<p><strong>Use the German flag when</strong> the content is German in origin or relevant to Germany<br />
<strong>Use <i>Deutsch</i> when</strong> the user interface will be switched to that language</p>
<p>Consider also that not everyone is able to see flags, and if your site is accessible you will need to have the text explaining the flag anyway. Doing things as described above keeps things very simple, easy for users to understand, and makes clear the distinction between geographic content relevance and content language.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=20&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2008/10/27/using-flags-for-language-choice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>IPv6-enabled home network with OpenBSD</title>
		<link>http://canonical.wordpress.com/2008/07/02/ipv6-enabled-home-network-with-openbsd/</link>
		<comments>http://canonical.wordpress.com/2008/07/02/ipv6-enabled-home-network-with-openbsd/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 05:25:26 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=15</guid>
		<description><![CDATA[My goal is to make my home network as simple as possible, but not to use IPv6 exclusively. That said, wherever possible I have enabled and preferred IPv6 to shake out any issues and to see where things can be improved. I try to mimic a &#8220;realistic&#8221; dual stack environment because that is the most [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=15&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>My goal is to make my home network as simple as possible, but not to use IPv6 exclusively. That said, wherever possible I have enabled and preferred IPv6 to shake out any issues and to see where things can be improved. I try to mimic a &#8220;realistic&#8221; dual stack environment because that is the most useful balance to me so that I can continue to get things done while automatically preferring IPv6 wherever possible.</p>
<p>Here is a simple ASCII diagram of my physical network:</p>
<pre>[ LAN ] -- [ WAP/switch ] -- [ OpenBSD 4.3 ] -- { Internet }</pre>
<p>The end result for those that don&#8217;t want to read the whole thing is an extremely stable and functional LAN that supports IPv6-enabled devices easily and automatically without denying anything to IPv4-only hosts. Windows Vista clients, for example, can simply plug in or associate with my WAP and have IPv6 connectivity with <strong>zero</strong> configuration. I realize this is relatively trivial (and hopefully my explanation is as trivial) but I feel like this is important: I commonly hear that IPv6 is very difficult to use or difficult to set up. While there are some things you need to know to set up an IPv6 network (as with IPv4), there is (or rather, should be) <strong>absolutely nothing</strong> you need to know as a client in a properly configured dual-stack environment. When a user decides to go to <a href="http://freebsd.org">freebsd.org</a> they should need to do a little sleuthing to figure out that most, if not all, of their network communication just took place over IPv6 ;) </p>
<p>I will go through the steps I took (neatly sidestepping the mistakes I made&#8230;) to set this up as well as posting any relevant configuration files I have. I&#8217;ll try to keep this segmented into easily visible sections, because I don&#8217;t like splitting this kind of thing up into multiple blog posts. Additionally, before I begin, I am going to use <strong>example</strong> IPv6 addresses within the <a href="http://tools.ietf.org/html/rfc3849">RFC 3849</a> documentation-use-only IPv6 prefix, and <strong>example</strong> IPv4 addresses from TEST-NET described in <a href="http://tools.ietf.org/html/rfc3330">RFC 3330</a> instead of my own. The IPv6 documentation prefix is <code>2001:db8::/32</code> and IPv4 TEST-NET is <code>192.0.2.0/24</code>. I will use my private addresses (in <code>10.0.0.0/8</code> address space) as they actually are configured on my home network. What does this mean for you? Quoting from RFC 3849, &#8220;[a]ddresses within this block should not appear on the public Internet,&#8221; so don&#8217;t expect any of these addresses to work for you without altering them!</p>
<h3>Step 1: Check configuration</h3>
<p>Since this post is about OpenBSD, I&#8217;m using OpenBSD as an example. First of all, there are some <code>sysctl</code> options to be sure you have set to allow you to forward packets and be a well-behaved router.</p>
<h4>/etc/sysctl.conf</h4>
<pre>
# 1=Permit forwarding (routing) of IPv4 packets
net.inet.ip.forwarding=1

# 1=Permit forwarding (routing) of IPv6 packets
net.inet6.ip6.forwarding=1

# 1=Permit IPv6 autoconf (forwarding must be 0)
net.inet6.ip6.accept_rtadv=0
</pre>
<p>Next, make sure you have a <code>pf.conf</code> that you are content with, because in a minute you will (hopefully) become connected via IPv6. Here is a barebones <code>pf.conf</code> which is a literal copy and paste from the <code>pf.conf</code> currently on my OpenBSD box. <strong>If you&#8217;re thinking about copying and pasting this, please make sure it matches your security policies. I like my <code>pf.conf</code> to be more liberal than many people, so if you don&#8217;t understand what this does I would recommend <code>man 5 pf.conf</code>.</strong></p>
<h4>/etc/pf.conf</h4>
<pre>
# Macros
ext_if="rl0"
int_if="xl0"

# Tables

# Options
set block-policy return
set skip on lo

# Normalization
scrub in
scrub out

# Queuing

# Translation
nat on $ext_if inet from ! ($ext_if) -&gt; ($ext_if)

# Filtering
pass in
pass out
</pre>
<p>Make sure <code>pf</code> is enabled:</p>
<pre>pfctl -e</pre>
<p>and that your ruleset is loaded:</p>
<pre>pfctl -f /etc/pf.conf</pre>
<p>where <code>/etc/pf.conf</code> is the location of your <code>pf.conf</code> (this is default).</p>
<h3>Step 2: Get connected</h3>
<p>If you&#8217;re in the USA, statistically you probably do not have native IPv6 connectivity. This is a little unfortunate, but thankfully there are organizations who are willing to allow us to use their services to tunnel IPv6 over the existing IPv4 network to get to their point of presence, and from there the traffic can travel over the IPv6 internet. While this is not ideal, this will have to do for most of us. If you have native IPv6 connectivity, you&#8217;re probably laughing at me :)</p>
<p>I used <a href="http://tunnelbroker.net">Hurricane Electric</a> as my tunnel broker. Once I was signed up, I asked for a /64. One nice thing about Hurricane Electric (and this might be true for other tunnel brokers as well, I have no idea) is that they provide customized configurations for nearly any operating system.</p>
<p>I&#8217;ll explain more about this later, but I&#8217;d like to show the information Hurricane Electric gave me here (using the example prefixes instead of mine) so you can tell how to apply this to your own tunnel (and I&#8217;m sure other tunnel brokers do it similarly). Hopefully the explanation afterward will give these values some meaning if they don&#8217;t already make sense to you:</p>
<pre>
Server IPv4 address:    192.0.2.74
Server IPv6 address:    2001:db8:1f04:4c9::1/64
Client IPv4 address:    192.0.2.44
Client IPv6 address:    2001:db8:1f04:4c9::2/64
Routed /64:  	        2001:db8:1f05:4c9::/64
</pre>
<p><strong>Server</strong> marks Hurricane Electric&#8217;s IPv4 and IPv6 tunnel endpoints, and <strong>Client</strong> marks my IPv4 and IPv6 tunnel endpoints.<br />
<strong>Routed /64</strong> is the subnet I am assigned. Note that it differs slightly (<code>1f05</code> instead of <code>1f04</code>) from the tunnel endpoints.</p>
<p>Since I&#8217;m setting up my OpenBSD 4.3 box as one of the endpoints of the tunnel, I selected OpenBSD and had them generate a configuration based on the assigned addresses. Here was the configuration generated for me (note the line continuation):</p>
<pre>
ifconfig gif0 tunnel 192.0.2.44 192.0.2.74
ifconfig gif0 inet6 alias 2001:db8:1f04:4c9::2 \
                          2001:db8:1f04:4c9::1 prefixlen 128
route -n add -inet6 default 2001:db8:1f04:4c9::1
</pre>
<p>You could happily copy and paste this, but chances are if you&#8217;ve read this far you&#8217;re going to want to know what exactly this is doing. I know I did, as I don&#8217;t like to simply copy and paste configuration from other people without knowing what it does first. The following is kind of verbose, but it might help some people to understand better what the above commands mean.</p>
<p>The first line says &#8220;<code>ifconfig</code>, I want to operate on a generic tunneling interface (<code>gif0</code>, <code>man 4 gif</code> for more information) to create a <code>tunnel</code> from my IPv4 address assigned to me by my ISP (<code>192.0.2.44</code>) to another IPv4 address somewhere else on the internet (<code>192.0.2.74</code>).&#8221; The tunnel concept is no more complex than thinking of a virtual tube that connects two points. While the internet may route the physical packets between the two endpoints 30 hops around the world, as far as the logic is concerned, the tunnels are directly connected. You can think of this tunnel as the underlying &#8220;road&#8221; or transport on top of which our IPv6 packets will travel to get to a place <strong>where they can be routed natively</strong>, as we (I) do not yet have native IPv6 connectivity to the internet.</p>
<p>The next line says &#8220;<code>ifconfig</code>, I want to operate on <code>gif0</code> again, this time specifying things about IPv6 (<code>inet6</code>). I would like to create a new address for this interface as opposed to altering any existing addresses (<code>alias</code>), and I would like this address to be <code>2001:db8:1f04:4c9::2</code>. Since we&#8217;re talking about a tunnel, I want the other end (Hurricane Electric&#8217;s end) of my tunnel to be <code>2001:db8:1f04:4c9::1</code>. Finally, since I&#8217;m dealing with just a single host address on a point-to-point link, I will use <code>prefixlen 128</code>.&#8221;</p>
<p>Dead simple so far, right? The last line says &#8220;I&#8217;d like to adjust my routing tables (<code>route -n</code>, don&#8217;t worry about the -n for now but you can read the man page for <code>route(8)</code> if you&#8217;re curious) to <code>add</code> an IPv6 (<code>-inet6</code>) route which will be my <code>default</code> route (if my machine doesn&#8217;t know exactly where to send packets, they go here), and I want them to head toward the &#8220;far end&#8221; of my tunnel which is <code>2001:db8:1f04:4c9::1</code>, where hopefully they&#8217;ll eventually be routed and arrive at their destination.&#8221; Note here that we specify the &#8220;far end&#8221; of the tunnel. We want our packets to go <strong>through</strong> the tunnel to the other end where they&#8217;ll be picked up by Hurricane Electric, not simply go to our end of the tunnel and stop short of their destination.</p>
<p><code>gif(4)</code> is a neat little pseudo-interface that can encapsulate any combination of IPv6 or IPv4 packets based on how it is configured. Now that we&#8217;ve set up a <code>gif(4)</code> interface (<code>gif0</code> above), it will see that since the tunnel is set up via IPv4 (the first line above) that IPv6 packets traveling through it need to get encapsulated inside IPv4 packets so they can be routed through the IPv4 internet. Once they reach Hurricane Electric at the other end, Hurricane Electric&#8217;s endpoint is set up to unpack (decapsulate) the packets and route them over the native IPv6 internet to their destination. The reverse happens exactly as you&#8217;d expect; IPv6 packets encapsulated in IPv4 packets coming in from the Hurricane Electric tunnel to our <code>gif(4)</code> interface get decapsulated and shuffled across our LAN to their destination as IPv6 packets.</p>
<p>At this point, you&#8217;ll want to assign your own IPv6 addresses to your interfaces so that you can access them via IPv6. Hurricane Electric assigned me the <code>2001:db8:1f05:4c9::/64</code> subnet as shown above, and you must assign these addresses out of the available allocated space. Working from our example, then, these are some sample valid addresses:</p>
<pre>
2001:db8:1f05:4c9::10
2001:db8:1f05:4c9::dead:beef
2001:db8:1f05:4c9::420
</pre>
<p>You can use <code>ifconfig inet6 alias</code> to do such configuration and an example, for completeness, of assigning an address to one of your interfaces might be</p>
<pre>
ifconfig xl0 inet6 alias 2001:db8:1f05:4c9::10 prefixlen 64
</pre>
<h3>Step 3: Advertise</h3>
<p>Now that we&#8217;re ready to go and you&#8217;ve verified that you can do something like:</p>
<pre>
ping6 ipv6.google.com
</pre>
<p>and you get replies, you can move on to telling other IPv6 capable hosts on your network about your connectivity, and how they can get some. OpenBSD ships with <code>rtadvd</code> (<strong>r</strong>ou<strong>t</strong>er <strong>adv</strong>ertisement <strong>d</strong>aemon) which we will use for exactly this purpose.</p>
<p>Again, the configuration file first:</p>
<h4>/etc/rtadvd.conf</h4>
<pre>
xl0:\
        :addr="2001:db8:1f05:4c9::":prefixlen#64:raflags#64:
</pre>
<p>It might look like noise at first, so I&#8217;ll break it down. <code>man 5 rtadvd.conf</code> will be useful for more details.</p>
<p>Each field in this configuration file is separated by a <code>:</code> character. The first line starts off with an interface that <code>rtadvd</code> is going to advertise on. You may notice that <code>xl0</code> is my internal interface from my <code>pf.conf</code>. This is because I want <code>rtadvd</code> to advertise the information that follows on my LAN. The backslash and whitespace that follows is simply to make it easy to track things in a large file; they are completely optional. The next section is <code>addr="2001:db8:1f05:4c9::"</code>. This gives the address prefix to advertise to hosts. With IPv6, you advertise a prefix of some length and the hosts then fill in the rest themselves. Therefore I am advertising the prefix for the network you saw above. The next section is <code>prefixlen#64</code>. You may notice that string values are distinguished from their corresponding identifiers with <code>=</code> and numeric values are distinguished with <code>#</code>. This <code>prefixlen</code> section tells hosts how long the prefix that I&#8217;m advertising is. As the address <code>2001:db8:1f05:4c9::</code> expands to <code>2001:db8:1f05:4c9:0000:0000:0000:0000</code>, I have to say which part of that I&#8217;m advertising, and which part is left up to the host to choose for itself. This says I&#8217;m advertising the first <code>64</code> bits of the address (The first 4 colon-delimited sections), leaving the host receiving this advertisement to deduce that it can pick the other 64 bits for itself. The last section is perhaps the least well-understood. This field <code>raflags#64</code> stands for <strong>r</strong>outer <strong>a</strong>dvertisement <strong>flags</strong>, and they carry, you guessed it, flags about the nature of the router advertisement. There are two flags we are interested in. They are documented in <code>rtadvd.conf</code> with the following:</p>
<pre>
raflags
        (num) Flags field in router advertisement message header.  Bit 7
        (0x80) means Managed address configuration flag bit, and Bit 6
        (0x40) means Other stateful configuration flag bit.  The default
        value is 0.
</pre>
<p>I will simplify this slightly to make it as easy as possible to understand at first (hopefully) so if you want details or the authoritative source, refer to <a href="http://tools.ietf.org/html/rfc4861">RFC 4861</a>, page 19 for more information.</p>
<p>The <code>M</code> flag says that the host will need to get addresses via DHCPv6. In other words, it tells the host that it shouldn&#8217;t pick its own identifier (remember those last 64 bits above?), because the network policy is to ask a central location (<strong>M</strong>anaged, see?) for an address first. This will likely trigger DHCPv6 in hosts that support it.</p>
<p>The <code>O</code> flag says that the host may obtain <strong>O</strong>ther information from a central location as appropriate, also using DHCPv6. In other words, if you&#8217;d like to make available DNS servers, time servers, etc via DHCP, you&#8217;ll want this flag turned on so that hosts ask you about them. Note that this is separate from the address configuration. You may have (and I do indeed do it this way) the <code>O</code> flag set while the <code>M</code> flag is not set, indicating that hosts can pick their own addresses but if they want other neat information they should ask. Note that this is a little more flexible than DHCP available for IPv4, and allows for better separation of network management if you don&#8217;t want the &#8220;all-or-nothing&#8221; approach that DHCP for IPv4 offers.</p>
<p>The value is <code>64</code> for <code>raflags</code>, which is the <strong>decimal value</strong> (and I personally think the man page is confusing in this regard) of the hexadecimal value <code>0x40</code>, meaning that I have the <code>O</code> flag set, but the <code>M</code> flag remains unset. This is because, in order for users to feel like they have connectivity out of the box, they will need DNS services, and I will provide them with a DNS server address to use (via DHCPv6) as I will show in a moment, so the host needs to know that it can ask for it.</p>
<p>Once you&#8217;ve got everything set up like you want it, start the server with</p>
<pre>
/usr/sbin/rtadvd xl0
</pre>
<p>where <code>xl0</code> is the interface you want rtadvd to operate on. <code>xl0</code> is my internal interface.</p>
<h3>Step 4: DNS</h3>
<p>I&#8217;d like to be able to resolve DNS over IPv6 for machines that support it, and it required a little tweaking on my part to get it working like I wanted it to.</p>
<p>First, I ran <code>rndc-confgen</code> to generate a key to use to communicate with the running DNS server, and did the appropriate things with it. Take a look at the man page for <code>rndc-confgen</code>; I won&#8217;t go into the details, but you&#8217;ll need to substitute yours below (for <code>YOUR_OWN_SECRET_HERE</code> if you choose to use my configuration file.</p>
<h4>/var/named/etc/named.conf (partial)</h4>
<pre>
key "rndc-key" {
        algorithm hmac-md5;
        secret "YOUR_OWN_SECRET_HERE";
};

acl clients {
        10.1.1.0/24;
        2001:db8:1f05:4c9::/64;
        127.0.0.0/8;
        ::1/128;
};

controls {
        inet 127.0.0.1 port 953
                allow { 127.0.0.1; } keys { "rndc-key"; };
};

options {
        listen-on    { any; };
        listen-on-v6 { any; };

        empty-zones-enable yes;

        allow-recursion { clients; };
};

logging {
        category lame-servers { null; };
};
</pre>
<p>This tells BIND to listen on all of my interfaces but only recursively resolve queries from my local IPv4 and IPv6 networks, which I&#8217;ve gone over above. I&#8217;ve also done some other things to the default shipped configuration like allowed <code>version</code> queries. If you&#8217;re unhappy with my security policies, you&#8217;ll need to make sure you modify this file to match yours before putting it into production. With this in place, I simply started the server by executing</p>
<pre>/usr/sbin/named</pre>
<p>Check <code>/var/log/daemon</code> to make sure everything started properly.</p>
<h3>Step 5: DHCPv6 extras</h3>
<p>This part isn&#8217;t quite as standard on OpenBSD, yet. I decided to go with <a href="http://sourceforge.net/projects/wide-dhcpv6">WIDE-DHCPv6</a> for no particular technical reason, but it is simple to build and configure.</p>
<p>Once I unpacked the software, I changed into its directory and did</p>
<pre>
./configure &amp;&amp; make &amp;&amp; sudo make install
</pre>
<p>which builds it and installs the software to <code>/usr/local</code>. If you need/want it somewhere else, you can use the standard <code>configure</code> options to alter the prefixes and some other things. My OpenBSD box is a Pentium III running at 1GHz, and it takes a very small amount of time (2 minutes, if that) to configure, build, and install.</p>
<p>Even easier than installing this software is configuring it (in my case at least). I created a file called <code>/usr/local/etc/dhcp6s.conf</code> to configure the server, and the file looks like this:</p>
<h4>/usr/local/etc/dhcp6s.conf</h4>
<pre>option domain-name-servers 2001:db8:1f05:4c9::10;</pre>
<p>which simply tells the DHCPv6 server to hand out the IPv6 address <code>2001:db8:1f04:4c9::10</code> as the primary IPv6-accessible DNS server. Windows Vista clients, for example, if given one or more IPv6 DNS servers, prefer the IPv6 DNS servers over the IPv4 DNS servers.</p>
<p>You can now start the daemon with</p>
<pre>/usr/local/sbin/dhcp6s xl0</pre>
<p>substituting <code>xl0</code> for the interface you would like it to listen on (<code>xl0</code> is my internal interface) and the path to the server for the path you used if you installed it to a different location.</p>
<h3>Step 6: Finalize</h3>
<p>Now that we&#8217;ve set it all up, let&#8217;s make our configuration persistent across reboots.</p>
<p>I used <code>/etc/rc.local</code> to start WIDE-DHCPv6&#8217;s <code>dhcp6s</code> on boot.</p>
<h4>/etc/rc.local</h4>
<pre>
echo -n 'starting local daemons:'

# Add your local startup actions here.

echo -n ' dhcp6s'

/usr/local/sbin/dhcp6s xl0

echo '.'
</pre>
<p>My <code>/etc/rc.conf.local</code> looks like this (you may not need all of these):</p>
<h4>/etc/rc.conf.local</h4>
<pre>
dhcpd_flags=""
named_flags=""
ntpd_flags="-s"
rtadvd_flags="xl0"

pf=YES
</pre>
<p>and I have three <code>hostname.if</code> files:</p>
<h4>/etc/hostname.gif0</h4>
<pre>
tunnel 192.0.2.44 192.0.2.74
inet6 alias 2001:db8:1f04:4c9::2 128
dest 2001:db8:1f04:4c9::1

!route -n add -inet6 default 2001:db8:1f04:4c9::1
</pre>
<h4>/etc/hostname.xl0</h4>
<pre>
inet 10.1.1.1 255.255.255.0 10.1.1.255
inet6 alias 2001:db8:1f05:4c9::10 64
</pre>
<h4>/etc/hostname.rl0</h4>
<pre>
dhcp NONE NONE NONE
</pre>
<p>You may need to change some things, for example I obtain my <code>rl0</code> IPv4 address via DHCP, so my first line of <code>hostname.rl0</code> contains the right incantation to obtain the address that way.</p>
<p>It was also pointed out to me that assigning an IPv6 address to this external interface <strong>if you are using a setup like mine</strong> may cause routing confusion (and in fact did in my case!)</p>
<h3>Conclusion</h3>
<p>I hope this at least gives you a headstart when it comes to setting up a home network on OpenBSD. This isn&#8217;t necessarily intended as a guide, more as a way for me to document my thought process as I set up my network. That said, I have written it with people reading as a way to get ideas for themselves in mind, so I would appreciate comments about places where you think this can be improved. Chances are I&#8217;ve made a mistake in my thinking or have given out bad information, and I&#8217;d appreciate corrections to that effect even more.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=15&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2008/07/02/ipv6-enabled-home-network-with-openbsd/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>Are the RIAA&#8217;s DMCA takedown notices legitimate?</title>
		<link>http://canonical.wordpress.com/2008/06/05/are-the-riaas-dmca-takedown-notices-legitimate/</link>
		<comments>http://canonical.wordpress.com/2008/06/05/are-the-riaas-dmca-takedown-notices-legitimate/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 00:43:53 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/?p=14</guid>
		<description><![CDATA[By now, many people are aware that the RIAA has been going after people (specifically university students) they believe are violating the copyrights of their member companies. Other people have written articles on specifically how the RIAA (or more realistically, companies the RIAA hire) do this, so if you haven&#8217;t done so, I&#8217;d recommend reading [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=14&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>By now, many people are aware that the RIAA has been going after people (specifically university students) they believe are violating the copyrights of their member companies. Other people have <a href="http://chronicle.com/free/2008/05/2821n.htm">written articles</a> on specifically how the RIAA (or more realistically, companies the RIAA hire) do this, so if you haven&#8217;t done so, I&#8217;d recommend reading about it.</p>
<p>Many universities have policies, whether written or unwritten, that dictate some sort of action against students when emails are received requesting that infringing content be removed from the computers serving that content.</p>
<p>In most cases, universities do a variation of the following:</p>
<ol>
<li>Look up the student&#8217;s information based on the IP address(es) listed in the email</li>
<li>Disable the student&#8217;s internet access</li>
<li>Follow up with the student in some way (require that some document be signed before internet access is restored, ask that they meet with a university employee or judicial officer, etc.)</li>
<li>Restore the student&#8217;s internet access</li>
</ol>
<p>One of the many issues that I have with this process is that in almost all cases the email is <strong>never verified</strong>, nor is it <strong>verifiable</strong>. Most of the time there is a persona certificate sent along with this email, but the email itself is <b>not digitally signed</b>. Two different emails sent to two separate institutions contained such persona certificates that hashed to the same value. Therefore, if somebody were to spoof such an email, attaching that certificate to the email would make that email as authentic as any emails supposedly sent from the RIAA.</p>
<p>The problem here is that institutions are taking action against students without even attempting to verify the authenticity of the emails they receive. Universities claim that they want to avoid potential problems, and so they are complying with the text of these emails. What happens, then, when students realize their university is taking action against them from what is essentially an anonymous threat? What happens when spoofed emails result in action taken against students?</p>
<p>Who&#8217;s to say this isn&#8217;t happening now?</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/14/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/14/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=14&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2008/06/05/are-the-riaas-dmca-takedown-notices-legitimate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>bind(2) failed on Linux?</title>
		<link>http://canonical.wordpress.com/2007/12/10/bind2-failed-on-linux/</link>
		<comments>http://canonical.wordpress.com/2007/12/10/bind2-failed-on-linux/#comments</comments>
		<pubDate>Tue, 11 Dec 2007 03:09:07 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/2007/12/10/bind2-failed-on-linux/</guid>
		<description><![CDATA[I’ll start this off with an example. How many of you running a Linux variant have seen the following in your logs?
sshd[6238]: Server listening on :: port 22.
sshd[6238]: error: Bind to port 22 on 0.0.0.0
When I first discovered this I had a couple theories about why this might be happening, but all I really knew [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=11&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I’ll start this off with an example. How many of you running a Linux variant have seen the following in your logs?</p>
<p><code>sshd[6238]: Server listening on :: port 22.<br />
sshd[6238]: error: Bind to port 22 on 0.0.0.0</code></p>
<p>When I first discovered this I had a couple theories about why this might be happening, but all I really knew for sure was that I couldn’t reproduce the problem on an OpenBSD or FreeBSD system. Soon enough, I came across numerous blog and list posts with sledgehammer answers such as “disable IPv6 support in the kernel!” I didn’t know what was going on at the time, but I certainly wasn’t satisfied by this answer. I went looking for behavior specific to Linux and came across this excerpt from Linux’s ipv6(7):</p>
<p><code>IPv4 connections can be handled with the v6 API by using the v4-mapped-on-v6 address type; thus a program only needs only to support this API type to support both protocols. This is handled transparently by the address handling functions in libc.</code></p>
<p><code>IPv4 and IPv6 share the local port space. When you get an IPv4 connection or packet to a IPv6 socket its source address will be mapped to v6 and it will be mapped to v6.</code></p>
<p>That’s more like the information I’m looking for. From what I’ve gathered, this v4-mapped addressing behavior is supposed to make it simpler for applications to be configured during the IPv4 to IPv6 transition (<a href="http://people.apache.org/~trawick/v4mapped.html">you only need to specify one Listen directive</a> in Apache, for example).</p>
<p>I personally dislike the idea of the v4-mapped-on-v6 address type. Put simply, when I create an INET6 socket, I expect that I’m going to do communication over that protocol. I wouldn’t expect to do IPX communication on an INET socket, why should I expect to do INET communication on an INET6 socket? Furthermore, if I have an application like sshd and I give it the -6 parameter, my expectation is that it will no longer use IPv4 for communication. It will, however, do IPv4 communication via v4-mapped addresses on certain systems and this may cause problems for administrators who believe their system is only listening for certain types of communication when in reality it is listening for others as well. I believe if you’re going to write software that listens for both IPv4 and IPv6 communication, you should be writing <a href="http://www.kame.net/newsletter/19980604/">AF-independent</a> software, and not have to rely on something that may make your life more difficult in the future. You’re going to have to touch the code anyway to update it (if you even have to), so you might as well get in there and do it right. The downside due to the v4-mapped behavior being the default is that those who wish to write portable AF-independent code (at least using the method linked above, if there is a better way I’d like to know about it) will need to explicitly turn on the socket option IPV6_V6ONLY if the system supports it.</p>
<p>If you don’t want this v4-mapped behavior at all in Linux, the following should turn it off globally, but will reset on the next reboot unless you make it permanent (see your distribution documentation for details):</p>
<p><code>net.ipv6.bindv6only = 1</code></p>
<p>In any case, I prefer the default behavior of the BSDs who, at the time of this writing, have disabled (by default) the v4-mapped addressing. You can always turn it on using the inverse of the socket option method described above.</p>
<p>I’ve submitted a <a href="https://bugzilla.mindrot.org/show_bug.cgi?id=1392">patch</a> to the Portable OpenSSH project. I fully expect to get flamed to dust because of something I’ve overlooked, but as far as I can tell setting the socket option in OpenSSH as the patch does should bring Portable OpenSSH on systems using v4-mapped addresses more in line with the behavior of OpenSSH on OpenBSD.</p>
<p><strong>Update:</strong> The <a href="https://bugzilla.mindrot.org/show_bug.cgi?id=1392">patch</a> has been accepted by the Portable OpenSSH project.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/11/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/11/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=11&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2007/12/10/bind2-failed-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>FreeBSD + PHP + OCI8 segfault fix</title>
		<link>http://canonical.wordpress.com/2007/09/12/freebsd-php-oci8-segfault-fix/</link>
		<comments>http://canonical.wordpress.com/2007/09/12/freebsd-php-oci8-segfault-fix/#comments</comments>
		<pubDate>Wed, 12 Sep 2007 22:56:19 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/2007/09/12/freebsd-php-oci8-segfault-fix/</guid>
		<description><![CDATA[At work I manage FreeBSD servers mostly running web applications. One of the databases we need to be able to talk to is an Oracle database, so all I need to be able to do is connect, perform queries, and retrieve results. We need to be able to do this from PHP.
On FreeBSD, one obvious [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=10&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>At work I manage FreeBSD servers mostly running web applications. One of the databases we need to be able to talk to is an Oracle database, so all I need to be able to do is connect, perform queries, and retrieve results. We need to be able to do this from PHP.</p>
<p>On FreeBSD, one obvious option is to use oracle8-client, which is a binary port of Oracle’s client libraries for Linux. The PHP OCI8 extension port has this as a dependency, so with no configuration aside from building PHP with OCI8 support, you now have oracle8-client on your system.</p>
<p>Everything was incredibly simple to install, except for one problem. Now, with the OCI8 extension enabled in php.ini, the following occurs:</p>
<p><code><br />
user@host:~&gt; php hello.php<br />
Hello world!<br />
Segmentation fault<br />
user@host:~&gt;<br />
</code></p>
<p>The contents of hello.php don’t matter, but now <strong>all PHP scripts</strong> run from the command line <strong>always</strong> segfault on exit. This includes <code>pear</code> and other CLI utilities written in PHP. Using gdb I was able to trace unloading of the OCI8 library to a call in Zend/zend_API.c (DL_UNLOAD) which calls dlclose(3) on a FreeBSD system. After doing some <a href="http://www.mail-archive.com/php-bugs@lists.php.net/msg36497.html">reading</a>, I can only assume that the Oracle library is doing something incorrectly such as registering a function to be called at exit via atexit(3). In that case, we would call dlclose(3) after the function(s) are registered, but then when we exit and those registered functions get called, we get a segmentation fault as we’ve unmapped the memory they live in! While that may not be precisely what is happening in this case, as far as I can tell I’m dealing with a bug in the Oracle library.</p>
<p>We were able to run like this (in production too) for quite some time before I found a solution, because everything in the script could run before the segfault occurred. However, the return code would always be nonzero (so scripts that properly checked return codes from CLI PHP scripts had to be modified), it would spam the kernel logs, and generally annoy myself and our developers. Also, OCI8 connections made through httpd and mod_php were unaffected as the PHP module and extensions get loaded into memory, but not unloaded during the normal course of execution.</p>
<p>My patch is not elegant but works fine:</p>
<p><code><br />
--- Zend/zend_API.c.orig    Wed Sep 12 12:40:21 2007<br />
+++ Zend/zend_API.c Wed Sep 12 12:43:45 2007<br />
@@ -1912,9 +1912,11 @@</p>
<p> #if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H)<br />
 #if !(defined(NETWARE) &amp;&amp; defined(APACHE_1_BUILD))<br />
+/*<br />
    if (module-&gt;handle) {<br />
        DL_UNLOAD(module-&gt;handle);<br />
    }<br />
+*/<br />
 #endif<br />
 #endif<br />
 }<br />
</code></p>
<p>which essentially stops PHP from calling dlclose(3) on modules when it is exiting. As far as I have tested this works just fine because PHP is exiting anyway, but I would not use this patch if the dlclose(3) was called normally during runtime without exiting immediately afterwards. If you care to apply this patch, I saved the above text in a file called <code>patch-Zend::zend_API.c</code>, placed it in <code>/usr/ports/lang/php5/files</code>, and rebuilt PHP by executing <code>portupgrade -f php5</code>. Ports will automatically patch zend_API.c appropriately, and you should be good to go. The system I tested all of this on:</p>
<p>FreeBSD 6.2-RELEASE-p6<br />
PHP 5.2.3<br />
oracle8-client-0.1.1_1</p>
<p>There are some other <a href="http://mrtenente.infosys.lt/blog/?p=22">instructions</a> out there but I have found no need for the instant client, nor can I see how the instant client is even used by PHP in the example given there. That means you don’t need the Linux compatibility module loaded into your FreeBSD kernel, a Linux base system, or any of Oracle’s instant client packages (which require registration to download anyway).</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/10/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/10/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=10&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2007/09/12/freebsd-php-oci8-segfault-fix/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>Thunderbird IMAP folder checking</title>
		<link>http://canonical.wordpress.com/2007/06/11/thunderbird-imap-folder-checking/</link>
		<comments>http://canonical.wordpress.com/2007/06/11/thunderbird-imap-folder-checking/#comments</comments>
		<pubDate>Mon, 11 Jun 2007 18:40:48 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/2007/06/11/thunderbird-imap-folder-checking/</guid>
		<description><![CDATA[At work, most of us use procmail to conveniently filter our mail into folders to keep a semblance of organization. I don’t know how it took me so long to find this, because I know I’ve tried to search for it before. Lo and behold, it’s located (maybe newly?) on the Tips and Tricks page. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=9&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>At work, most of us use <a href="http://www.procmail.org">procmail</a> to conveniently filter our mail into folders to keep a semblance of organization. I don’t know how it took me so long to find this, because I know I’ve tried to search for it before. Lo and behold, it’s located (maybe newly?) on the <a href="http://www.mozilla.org/support/thunderbird/tips#beh_downloadstartup">Tips and Tricks</a> page. This great feature I’m talking about is the simple ability for Thunderbird to check all of my folders for new mail automatically, rather than only my Inbox. I know about folder subscriptions, the problem with those is that I have several profiles for which I’d have to do this on each of them, and I’d have to redo them every time I wiped my profile and started fresh.</p>
<p>Now that I’ve figured out how to do this, I’m pretty set on Thunderbird as my email client of choice.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=9&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2007/06/11/thunderbird-imap-folder-checking/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
		<item>
		<title>PHP’s extensions.ini: order matters</title>
		<link>http://canonical.wordpress.com/2007/03/05/phps-extensionsini-order-matters/</link>
		<comments>http://canonical.wordpress.com/2007/03/05/phps-extensionsini-order-matters/#comments</comments>
		<pubDate>Mon, 05 Mar 2007 20:56:47 +0000</pubDate>
		<dc:creator>Gordon</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://canonical.wordpress.com/2007/03/05/phps-extensionsini-order-matters/</guid>
		<description><![CDATA[I’m sure some of you have experienced strange errors after upgrading PHP extensions, specifically in my case using FreeBSD’s ports. The errors would look something like this:
php: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20060613/soap.so' - /usr/local/lib/php/20060613/soap.so: Undefined symbol "ps_globals" in Unknown on line 0
php: PHP Warning:  PHP Startup: Unable to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=8&subd=canonical&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I’m sure some of you have experienced strange errors after upgrading PHP extensions, specifically in my case using FreeBSD’s ports. The errors would look something like this:</p>
<p><code>php: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20060613/soap.so' - /usr/local/lib/php/20060613/soap.so: Undefined symbol "ps_globals" in Unknown on line 0</code><br />
<code>php: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20060613/xsl.so' - /usr/local/lib/php/20060613/xsl.so: Undefined symbol "dom_node_class_entry" in Unknown on line 0</code></p>
<p>Obviously I’m having problems here with the SOAP and XSL PHP extensions, but this problem has manifested itself before with numerous other extensions, so these are just examples. My usual solution was to simply rebuild the extension(s) causing problems. This worked for me, and it will most likely also work for you, but not for the reason you might expect. The problem appears to be a case of “hey you linked me against an {older|invalid} shared library and now I can’t resolve all of my symbols” that you see when you build programs incrementally from source without ensuring consistency, or try to load modules into a Linux kernel that were built against a previous kernel release. Because I’ve seen similar issues before, I thought I was doing the right thing, but I was a little frustrated as it seemed that ports wasn’t doing its job. Realistically I wasn’t that far off.</p>
<p>When PHP parses <code>extensions.ini</code>, it doesn’t appear to do correct (or any?) checks on the modules for interdependency. While ideally all of the modules would be independent of one another, they aren’t. PDO, for example, is an extension all by itself, but its drivers are clearly dependent on the PDO extension. The reason rebuilding specific extensions works for me is that ports does something automagic (very clean, too) when building extensions: it checks <code>extensions.ini</code> for the module’s existence when it installs or deinstalls a specific module. It cleans up for you by removing the module’s entry when you deinstall the module, and it adds an entry when you install a module. This meant that when I went to install that specific module, ports placed the corresponding entry <b>at the bottom</b> of <code>extensions.ini</code>. I can still build extensions in any order I want (assuming we’re not building extensions with different ABIs/APIs) but if I load a module before I load its dependency, the module is going to complain about whatever it needs from its dependency at runtime.</p>
<p>I solved this problem by building a known good <code>extensions.ini</code> and placed it next to the real <code>extensions.ini</code> in the filesystem, and I simply copy it over when I rebuild extensions. I use the <a href="http://php.net">php.net</a> documentation to initially discover dependencies, and add and remove them from my known good configuration as needed.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/canonical.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/canonical.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/canonical.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/canonical.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/canonical.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/canonical.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/canonical.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/canonical.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/canonical.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/canonical.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/canonical.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/canonical.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=canonical.wordpress.com&blog=653173&post=8&subd=canonical&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://canonical.wordpress.com/2007/03/05/phps-extensionsini-order-matters/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6883ce8d4b5561eee7e7b8794f7351f5?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Gordon</media:title>
		</media:content>
	</item>
	</channel>
</rss>