<?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/"
	>

<channel>
	<title>David Underhill &#187; David Underhill</title>
	<atom:link href="http://dound.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://dound.com</link>
	<description>dound&#039;s space on the web</description>
	<lastBuildDate>Sun, 13 Jun 2010 23:17:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rate limiting users requests on app engine (optionally with Captchas)</title>
		<link>http://dound.com/2010/06/rate-limiting-gae-with-captchas/</link>
		<comments>http://dound.com/2010/06/rate-limiting-gae-with-captchas/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 22:59:55 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[rate limit]]></category>

		<guid isPermaLink="false">http://dound.com/?p=447</guid>
		<description><![CDATA[You may have some functionality on your app engine site that you want to protect from robots and prevent users from executing too frequently.  For example, perhaps users can leave comments but you only want them to be able to leave a comment every N seconds &#8211; faster than that and the &#8220;user&#8221; is [...]]]></description>
			<content:encoded><![CDATA[<p>You may have some functionality on your app engine site that you want to protect from robots and prevent users from executing too frequently.  For example, perhaps users can leave comments but you only want them to be able to leave a comment every <code>N</code> seconds &#8211; faster than that and the &#8220;user&#8221; is either a bot or is not using the system as intended.</p>
<p>One way to discourage this behavior is to limit how often a user can take a certain action to a fixed rate.  I&#8217;ve created a <code>RateLimiter</code> class which handles the logic of tracking how quickly a user is making requests, and determines when your code (optionally) should challenge the user with a captcha before allowing them to continue.  If you simply want to rate limit the user&#8217;s requests, you can ignore the captcha business and just return an error to the user whenever they exceed the allowed rate.</p>
<p>The source is available at <a href="http://gist.github.com/437051#file_rate_limit.py">http://gist.github.com/437051</a> (including the optional captcha handling code).</p>
<p><strong>Example Usage:</strong><br />
The example code below shows a rate limiter which allows a user to interact with a particular page once every 2 seconds.  It also gives the user 3 &#8220;tokens&#8221; which allows the user to violate this limit by up to 3 requests.  Tokens are consumed if a user makes a request within 2 seconds of the previous request.  Tokens are returned if the user if the user slows down, or if the user solves a captcha.</p>
<p>This example is written as if the request is expected to be made via JavaScript on your page.  The client-side JavaScript would check the response for the <code>'captcha-show'</code> text and prompt the user with a captcha if that test was present.  When the captcha is answered, another AJAX call would be made to send the user&#8217;s response to the <code>CaptchaHandler</code> class in <a href="http://gist.github.com/437051#file_rate_limit.py">rate_limit.py</a>.  You are free to integrate the captcha challenge however you like.  Just call <code>RateLimiter.captcha_solved()</code> or <code>RateLimiter.rate_limit(uid, captcha_solved=True)</code> when the user meets your challenge (it doesn&#8217;t even have to be a captcha).</p>
<p><script src="http://gist.github.com/437051.js?file=example.py"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/06/rate-limiting-gae-with-captchas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Country and State Chooser JavaScript Widget</title>
		<link>http://dound.com/2010/05/country-and-state-chooser-javascript-widget/</link>
		<comments>http://dound.com/2010/05/country-and-state-chooser-javascript-widget/#comments</comments>
		<pubDate>Sat, 08 May 2010 04:23:31 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://dound.com/?p=436</guid>
		<description><![CDATA[I&#8217;ve put together a simple JavaScript widget which dynamically populates a state dropdown box when a country is selected.  The widget includes states for the United States, Canada, and a few other countries.   It should be trivial to modify the script to use a list of countries and states of your choosing. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve put together a simple JavaScript widget which dynamically populates a state dropdown box when a country is selected.  The widget includes states for the United States, Canada, and a few other countries.   It should be trivial to modify the script to use a list of countries and states of your choosing.  The full source is below.  A <a href="http://gist.github.com/raw/394325/4b7294bc9b64ffbb852bbb542d430db5adde3a6c/location_picker-min.js">minified version</a> is also available.  Enjoy!</p>
<p><script src="http://gist.github.com/394325.js?file=location_picker.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/05/country-and-state-chooser-javascript-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing JCustomUploader: a simple Java-based file uploader</title>
		<link>http://dound.com/2010/04/announcing-jcustomuploader/</link>
		<comments>http://dound.com/2010/04/announcing-jcustomuploader/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 05:49:53 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[applet]]></category>
		<category><![CDATA[file uploader]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JCustomUploader]]></category>

		<guid isPermaLink="false">http://dound.com/?p=419</guid>
		<description><![CDATA[Today I released JCustomUploader, a simple, Java-based file uploader. It can run as an applet on your website (Java 1.4 or higher) or as part of a desktop application. This software is open-source and free to use or include in your own project.  Please check out the JCustomUploader homepage for more information.
Here is a [...]]]></description>
			<content:encoded><![CDATA[<p>Today I released <a href="http://www.dound.com/projects/JCustomUploader">JCustomUploader</a>, a simple, Java-based file uploader. It can run as an applet on your website (Java 1.4 or higher) or as part of a desktop application. This software is open-source and free to use or include in your own project.  Please check out the <a href="http://www.dound.com/projects/JCustomUploader">JCustomUploader homepage</a> for more information.</p>
<p>Here is a screenshot of the UI (with fake &#8220;random&#8221; failures inserted to show how failures are handled):</p>
<p><a href="http://dound.smugmug.com/Computers/Software/jcustomuploader/11901354_MvAkC#842327202_SV92J-A-LB"><img src="http://dound.smugmug.com/photos/842327202_SV92J-L.png" alt="JCustomUploader UI"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/04/announcing-jcustomuploader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FAST Google App Engine Sessions (and RPX integration)</title>
		<link>http://dound.com/2010/04/google-app-engine-sessions-and-rpx-integration/</link>
		<comments>http://dound.com/2010/04/google-app-engine-sessions-and-rpx-integration/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 04:16:30 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[app-engine]]></category>
		<category><![CDATA[gae-sessions]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[sessions]]></category>

		<guid isPermaLink="false">http://dound.com/?p=307</guid>
		<description><![CDATA[The Google App Engine infrastructure provides many services, but sessions is not one of them.  There are several Python-based session middlewares which already do this so I considered them first (spoiler: I ended up writing my own and it is orders of magnitudes faster than the alternatives: gae-sessions).
Beaker is a solid implementation, but it [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://code.google.com/appengine/">Google App Engine</a> infrastructure provides many services, but sessions is not one of them.  There are several Python-based session middlewares which already do this so I considered them first (spoiler: I ended up writing my own and it is <a href="http://wiki.github.com/dound/gae-sessions/comparison-with-alternative-libraries">orders of magnitudes faster than the alternatives</a>: <strong><a href="http://github.com/dound/gae-sessions">gae-sessions</a></strong>).</p>
<p><a href="http://beaker.groovie.org/">Beaker</a> is a solid implementation, but it lacks support for memcache on app engine.  This means every request must go to the datastore to fetch session data &#8211; yuck.</p>
<p><a href="http://gaeutilities.appspot.com/">gaeutilities</a> is designed for app engine and takes advantage of both memcache and the datastore.  Unfortunately, the code is a bit heavyweight &#8211; it is coupled to unrelated functionality (e.g., &#8220;flash&#8221; messaging) and it is complicated by support for options I do not need (e.g., cookie-only sessions and automatic token rotation).  Most significantly, its performance suffers from excess API calls and inefficient model storage.</p>
<p>Since I was unsatisfied with these options, I wrote my own sessions middleware, <a href="http://github.com/dound/gae-sessions">gae-sessions</a>.  It strives to be lightweight, fast (but reliable), secure, and easy to use.  I ended up with a pretty small library (200 lines of code) which met these goals.  It uses memcache (for speed) and the datastore (for reliability) but only reads and writes  when it must.  db.Model objects are efficiently stored by converting them to protobufs instead of using the automatic pickling functionality (which is slow since app engine lacks cPickle).</p>
<p>Consider <a href="http://github.com/dound/gae-sessions">gae-sessions</a> if you need sessions support for a Python web application hosted on Google&#8217;s app engine.  The project includes demo code which you can run without modification on the app engine development server.  The demo shows gae-sessions working with an <a href="http://openid.net/">OpenID</a>-based authentication system powered by <a href="http://www.rpxnow.com">RPX</a> (check it out to see how easy it is to integrate with RPX).</p>
<p><strong>Update</strong>: I&#8217;ve created an <a href="http://bit.ly/gae-sessions"><strong>in-depth comparison page</strong></a> which compares both the features and performance of alternative sessions libraries (beaker, geautilities, gmemsess, and suas) with gae-sessions.</p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/04/google-app-engine-sessions-and-rpx-integration/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Python logging and performance: how to have your cake and eat it too</title>
		<link>http://dound.com/2010/02/python-logging-performance/</link>
		<comments>http://dound.com/2010/02/python-logging-performance/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 05:08:48 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[comment]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[preprocess]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://dound.com/?p=268</guid>
		<description><![CDATA[I love Python&#8217;s logging module.  I use it all the time to log a wide variety of information &#8212; messages to help me debug as well as informative messages for the user.  Though you can toggle which messages you want to be printed, if the Python interpreter encounters a logging method call it [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.python.org">Python</a>&#8217;s <a href="http://docs.python.org/library/logging.html">logging module</a>.  I use it all the time to log a wide variety of information &#8212; messages to help me debug as well as informative messages for the user.  Though you can toggle which messages you want to be printed, if the Python interpreter encounters a logging method call it still creates the string for the log message (the argument to the method) (sadly there Python doesn&#8217;t have <a href="http://www.haskell.org/haskellwiki/Performance/Laziness">lazy evaluation</a> like <a href="http://www.haskell.org/">Haskell</a>).  If creating this string is expensive, then your application&#8217;s performance may suffer.  Unfortunately, there is no Python preprocessor (like C&#8217;s <a href="http://gcc.gnu.org/onlinedocs/cpp/">cpp</a> &#8230; though <a href="http://code.google.com/p/preprocess/">preprocess</a> might be able to do it) so it is difficult to automatically remove a large number of logging statements prior to running an application in a production environment.</p>
<p>The best solution I&#8217;ve seen is to prefix logging statements with <code>if __debug__:</code> so that they are optimized away by <code>python -O</code> (see <a href="http://stackoverflow.com/questions/2006190/python-equivalent-of-define-func-or-how-to-comment-out-a-function-call-in-p">this post on StackOverflow</a>).  I like it, but it unfortunately requires this statement to be prefixed to every logging statement I don&#8217;t want in a production environment.  That&#8217;s a lot of ugly extra code and it isn&#8217;t easy to change which statements it applies to either.</p>
<p>I decided to write a script which automatically parses a Python file and replaces logging statements of a particular level with a <code>pass</code> statement and a commented out copy of the logging code.  It can also do the reverse operation.  It has some limitations (see the code, or run the script with the <code>--help</code> option), but it should work for most Python files.  I used it for the <a href="http://yuba.stanford.edu/vns">VNS</a> project and it successfully operated on every file in the project.  It also improved performance dramatically &#8211; the maximum throughput of the VNS simulator <a href="http://yuba.stanford.edu/vns/2010/02/fairness/">increased by 25%</a>!  In comparison, running the code with <a href="http://psyco.sourceforge.net/">Psyco</a> only garnered a 6% improvement (though pretty substantial for the minimal <a href="http://github.com/dound/vns/commit/54d5415a43043062ae6195b828707692b9231aab">13 lines</a> I had to add to take advantage of it).</p>
<p>I think this script is worth using before running your code in a production environment if you are a heavy user of the logging module like I am.  You can find the code <a href="http://www.siafoo.net/snippet/348">here</a> (it is hosted on <a href="http://www.siafoo.com">Siafoo</a>, a neat site for sharing code).  Here&#8217;s the latest version of the code:<br />
<script type='text/javascript' src='http://www.siafoo.net/snippet/348/embed.js?nolinenos'></script></p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/02/python-logging-performance/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Overcoming Linux Screen Resolution Limitations (EDID)</title>
		<link>http://dound.com/2010/01/overcoming-linux-screen-resolution-limitations/</link>
		<comments>http://dound.com/2010/01/overcoming-linux-screen-resolution-limitations/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 02:23:15 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[EDID]]></category>
		<category><![CDATA[modeline]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[resolution]]></category>
		<category><![CDATA[X11]]></category>
		<category><![CDATA[xrandr]]></category>

		<guid isPermaLink="false">http://dound.com/?p=244</guid>
		<description><![CDATA[A little while ago I picked up a 26&#8243; monitor (NEC MultiSync LCD2690WUXi).  Unfortunately, I found that when I connected the monitor to my Ubuntu Linux box that I could only use up to 1280&#215;1028 &#8212; even though the monitor&#8217;s native resolution was 1920&#215;1080!  I also had this problem on my Windows and [...]]]></description>
			<content:encoded><![CDATA[<p>A little while ago I picked up a 26&#8243; monitor (<a href="http://www.necdisplay.com/Products/Product/?product=1713e080-c8e3-4aab-9447-73dacb301b84">NEC MultiSync LCD2690WUXi</a>).  Unfortunately, I found that when I connected the monitor to my <a href="http://www.ubuntu.com/">Ubuntu</a> <a href="http://www.linux.org/">Linux</a> box that I could only use up to 1280&#215;1028 &#8212; even though the monitor&#8217;s native resolution was 1920&#215;1080!  I also had this problem on my <a href="http://www.microsoft.com/WINDOWS/">Windows</a> and <a href="http://www.opensuse.org/">SuSE</a> machines, so I suspect the monitor is not properly reporting its maximum resolution via <a href="http://en.wikipedia.org/wiki/EDID">EDID</a>.</p>
<p>I used the command-line utility <a href="http://www.thinkwiki.org/wiki/Xorg_RandR_1.2">xrandr</a> to fix the problem.  Running the tool with no arguments prints a list of displays and available display modes for each.  This is handy since you need the name assigned to your display by your OS for the next step.  Next, use the &#8220;&#8211;newmode&#8221; option with xrandr and specify the <a href="http://en.wikipedia.org/wiki/XFree86_Modeline">modeline</a> which describes the display configuration you wish to use.  This <a href="http://xtiming.sourceforge.net/cgi-bin/xtiming.pl">modeline generator</a> might help you create the modeline you need.  Once you create the new mode, use the &#8220;&#8211;addmode&#8221; option to add it to the list of modes supported by your monitor.</p>
<p>Finally, add this command to your <code>~/.xprofile</code> file (or something similar) so that when you start your machine the new mode is automatically added and available (this way Ubuntu automatically reselects it too).  This is what I ended up adding to my <code>~/.xprofile</code> file:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">xrandr <span style="color: #660033;">--newmode</span> <span style="color: #ff0000;">&quot;1920x1200_50Hz&quot;</span> <span style="color: #000000;">128</span>,<span style="color: #000000;">300</span> <span style="color: #000000;">1920</span> <span style="color: #000000;">1968</span> <span style="color: #000000;">2000</span> <span style="color: #000000;">2079</span> <span style="color: #000000;">1200</span> <span style="color: #000000;">1203</span> <span style="color: #000000;">1209</span> <span style="color: #000000;">1234</span> +hsync <span style="color: #660033;">-vsync</span>
xrandr <span style="color: #660033;">--addmode</span> HDMI-<span style="color: #000000;">0</span> <span style="color: #ff0000;">&quot;1920x1200_50Hz&quot;</span></pre></div></div>

<p>Note: If you set your <a href="http://en.wikipedia.org/wiki/Refresh_rate">refresh rate</a> too high, your monitor will probably flicker occasionally.  If this happens, try lowering the refresh rate by lowering the pixel clock value (the first number in the modeline).</p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/01/overcoming-linux-screen-resolution-limitations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe Acrobat Pro 9 Activation Problem Workaround</title>
		<link>http://dound.com/2010/01/acrobat-pro-9-activation-problem-workaround/</link>
		<comments>http://dound.com/2010/01/acrobat-pro-9-activation-problem-workaround/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 23:27:51 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[Adobe]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://dound.com/?p=237</guid>
		<description><![CDATA[A little while ago I bought Adobe Creative Suite CS4 Design Standard so that I could use Photoshop and Acrobat Pro on my Windows 7 machine (which I use for photo editing and organizing).  Installing, registering, and activating the 64-bit version was painless, except for one problem: whenever I launched Acrobat, it would work [...]]]></description>
			<content:encoded><![CDATA[<p>A little while ago I bought <a href="http://www.adobe.com/products/creativesuite/designstandard/">Adobe Creative Suite CS4 Design Standard</a> so that I could use <a href="http://www.adobe.com/products/photoshop/photoshop/">Photoshop</a> and <a href="http://www.adobe.com/products/acrobat/">Acrobat Pro</a> on my Windows 7 machine (which I use for photo editing and organizing).  Installing, registering, and activating the 64-bit version was painless, except for one problem: whenever I launched Acrobat, it would work fine for a few seconds until I was interrupted by an annoying dialog box which stated: &#8220;<em>Adobe Acrobat was installed as part of a suite. To enable Adobe Acrobat, please start another component of this suite (such as Adobe Photoshop).</em>&#8221;  After clicking &#8220;Ok&#8221; Acrobat would shutdown.</p>
<p>Needless to say, this made the Acrobat part of my installation useless.  Strangely, the dialog persisted even if I was already running Photoshop when I started Acrobat.  I tried deactivating and reactivating, reinstalling, and so forth &#8212; all to no avail.</p>
<p>Google didn&#8217;t seem to have any advice on the matter, so I gave in and tried calling technical support.  Though the representative was nice, he unfortunately didn&#8217;t have an immediate solution to the problem.  I kept playing around with my installation and stumbled across something that worked &#8212; instead of running the 64-bit version of Photoshop, I ran the ordinary version (it is installed in your start menu alongside the 64-bit version).  Ever since then Acrobat has worked fine (even when it is the only Adobe product running)!</p>
<p>It seems like the 64-bit version of Photoshop doesn&#8217;t properly communicate the activation details to Acrobat &#8212; a pretty bizarre (and annoying) bug for an Adobe product (which I am usually very fond of).  Thankfully, the workaround is pretty simple &#8212; just run the regular version of Photoshop (presumably running Illustrator or any of the other programs in the suite would also do the trick).</p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2010/01/acrobat-pro-9-activation-problem-workaround/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integrating Twisted with a pcap-based Python packet sniffer</title>
		<link>http://dound.com/2009/09/integrating-twisted-with-a-pcap-based-python-packet-sniffer/</link>
		<comments>http://dound.com/2009/09/integrating-twisted-with-a-pcap-based-python-packet-sniffer/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 00:53:34 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[pcap]]></category>
		<category><![CDATA[pcapy]]></category>
		<category><![CDATA[raw socket]]></category>
		<category><![CDATA[sniffer]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://dound.com/?p=223</guid>
		<description><![CDATA[Twisted is an awesome event-driven networking engine.  Unfortunately, it does not have good support for interfacing with raw sockets (unlike its support for many network protocols, which is amazing).  Anyway, I recently needed to work with raw sockets so I had to find a way to make it work with Twisted.  Though [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twistedmatrix.com/">Twisted</a> is an awesome event-driven networking engine.  Unfortunately, it does not have good support for interfacing with <a href="http://en.wikipedia.org/wiki/Raw_socket">raw sockets</a> (unlike its <a href="http://twistedmatrix.com/documents/8.1.0/api/twisted.protocols.html">support</a> for many network protocols, which is amazing).  Anyway, I recently needed to work with raw sockets so I had to find a way to make it work with Twisted.  Though Twisted does have a module (<a href="http://twistedmatrix.com/trac/wiki/TwistedPair">twisted.pair</a>) which tries to provide some support for raw sockets, the module is poorly documented and requires a library which is not readily available.</p>
<p>Luckily, I stumbled on a module which works on top of the <a href="http://www.tcpdump.org/">libpcap</a> packet capture library called <a href="http://oss.coresecurity.com/projects/pcapy.html">pcapy</a>.  It is simple to use, and thread-safe &#8212; and easy to integrate into a Twisted-based project.</p>
<p>I put together a short sample (see below) which shows how to capture raw packets alongside the main Twisted event loop.  It would be trivial to extend this example to also write to a raw socket (using an ordinary <a href="http://docs.python.org/library/socket.html">Python socket</a>).  This example can also be downloaded <a href="http://dound.com/wp/files/twisted_and_pcap_together.py">here</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># This sample shows how to run a libpcap-based packet sniffer concurrently with</span>
<span style="color: #808080; font-style: italic;"># the Twisted framework.  The Twisted component is an &quot;Echo&quot; TCP server</span>
<span style="color: #808080; font-style: italic;"># (listening on port 9999) which prints everything it receives.  When a client</span>
<span style="color: #808080; font-style: italic;"># connects, it starts the pcap thread.  When the pcap thread receives a packet,</span>
<span style="color: #808080; font-style: italic;"># it sends a message to the client telling it the size of the received packet.</span>
<span style="color: #808080; font-style: italic;"># Finally, when the client disconnects the program is terminated.</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># To try this contrived example out, run this script as root (so that it can use</span>
<span style="color: #808080; font-style: italic;"># pcap) and then connect to the echo server (e.g., telnet localhost 9999).  Note</span>
<span style="color: #808080; font-style: italic;"># that the pcap parameters are hard-coded.  This code uses twisted 8.0.2 and</span>
<span style="color: #808080; font-style: italic;"># pcapy-0.10.4.</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> pcapy <span style="color: #ff7700;font-weight:bold;">import</span> open_live
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span>.<span style="color: black;">protocol</span> <span style="color: #ff7700;font-weight:bold;">import</span> Protocol, Factory
<span style="color: #ff7700;font-weight:bold;">from</span> twisted.<span style="color: black;">internet</span> <span style="color: #ff7700;font-weight:bold;">import</span> reactor
&nbsp;
<span style="color: #808080; font-style: italic;"># pcap settings</span>
DEV          = <span style="color: #483d8b;">'eth0'</span>  <span style="color: #808080; font-style: italic;"># interface to listen on</span>
MAX_LEN      = <span style="color: #ff4500;">1514</span>    <span style="color: #808080; font-style: italic;"># max size of packet to capture</span>
PROMISCUOUS  = <span style="color: #ff4500;">1</span>       <span style="color: #808080; font-style: italic;"># promiscuous mode?</span>
READ_TIMEOUT = <span style="color: #ff4500;">100</span>     <span style="color: #808080; font-style: italic;"># in milliseconds</span>
PCAP_FILTER  = <span style="color: #483d8b;">''</span>      <span style="color: #808080; font-style: italic;"># empty =&gt; get everything (or we could use a BPF filter)</span>
MAX_PKTS     = -<span style="color: #ff4500;">1</span>      <span style="color: #808080; font-style: italic;"># number of packets to capture; -1 =&gt; no limit</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> run_pcap<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># the method which will be called when a packet is captured</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> ph<span style="color: black;">&#40;</span>hdr, data<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'pcap heard: when=%s sz=%dB'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>hdr.<span style="color: black;">getts</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># thread safety: call from the main twisted event loop</span>
        reactor.<span style="color: black;">callFromThread</span><span style="color: black;">&#40;</span>f, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># start the packet capture</span>
    p = open_live<span style="color: black;">&#40;</span>DEV, MAX_LEN, PROMISCUOUS, READ_TIMEOUT<span style="color: black;">&#41;</span>
    p.<span style="color: black;">setfilter</span><span style="color: black;">&#40;</span>PCAP_FILTER<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Listening on %s: net=%s, mask=%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>DEV, p.<span style="color: black;">getnet</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, p.<span style="color: black;">getmask</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">loop</span><span style="color: black;">&#40;</span>MAX_PKTS, ph<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># a silly echo server which prints what it receives and sends info about the</span>
<span style="color: #808080; font-style: italic;"># size of each packet captured on DEV</span>
<span style="color: #ff7700;font-weight:bold;">class</span> Echo<span style="color: black;">&#40;</span>Protocol<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> connectionLost<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, reason<span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">os</span>._exit<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># kill the whole process</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> connectionMade<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># run pcap in another thread (it will run forever)</span>
        reactor.<span style="color: black;">callInThread</span><span style="color: black;">&#40;</span>run_pcap, <span style="color: #008000;">self</span>.<span style="color: black;">pcapDataReceived</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> dataReceived<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'echo got: %s'</span> <span style="color: #66cc66;">%</span> data
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> pcapDataReceived<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, sz<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">transport</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'pcap got: %uB<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #66cc66;">%</span> sz<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># starts the silly echo server on port 9999</span>
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    factory = Factory<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    factory.<span style="color: black;">protocol</span> = Echo
    reactor.<span style="color: black;">listenTCP</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">9999</span>, factory<span style="color: black;">&#41;</span>
    reactor.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://dound.com/2009/09/integrating-twisted-with-a-pcap-based-python-packet-sniffer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>OpenFlow takes Best Demo and Best Paper at SIGCOMM 2009</title>
		<link>http://dound.com/2009/08/openflow-takes-best-demo-and-best-paper-at-sigcomm-2009/</link>
		<comments>http://dound.com/2009/08/openflow-takes-best-demo-and-best-paper-at-sigcomm-2009/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 22:02:53 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[OpenFlow]]></category>

		<guid isPermaLink="false">http://dound.com/?p=218</guid>
		<description><![CDATA[For the second year in a row, the OpenFlow team has captured the Best Demo award at SIGCOMM 2009.  Read the post on the OpenFlow blog for more details!  Though I only focused on one of the interfaces, all four of the OpenFlow demos built their GUIs on the ENVI framework which I [...]]]></description>
			<content:encoded><![CDATA[<p>For the second year in a row, the <a href="http://www.openflowswitch.org">OpenFlow</a> team has captured the Best Demo award at <a href="http://conferences.sigcomm.org/sigcomm/2009/">SIGCOMM 2009</a>.  Read the <a href="http://www.openflowswitch.org/wp/2009/08/openflow-wins-best-demo-and-best-poster-awards-at-sigcomm/">post on the OpenFlow blog</a> for more details!  Though I only focused on one of the interfaces, all four of the OpenFlow demos built their GUIs on the <a href="http://www.openflowswitch.org/wp/gui/">ENVI framework</a> which I created with the OpenFlow team!</p>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2009/08/openflow-takes-best-demo-and-best-paper-at-sigcomm-2009/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Overcoming Vista Screen Resolution Limitations with an ATI video card</title>
		<link>http://dound.com/2009/07/overcoming-vista-screen-resolution-limitations-with-an-ati-video-card/</link>
		<comments>http://dound.com/2009/07/overcoming-vista-screen-resolution-limitations-with-an-ati-video-card/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 20:27:30 +0000</pubDate>
		<dc:creator>David Underhill</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[resolution]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://dound.com/?p=209</guid>
		<description><![CDATA[I recently picked up a 26&#8243; monitor (NEC MultiSync LCD2690WUXi &#8211; great price, even new, and excellent color gamut).  Unfortunately, I found that when I connected to the monitor in Vista (which I use when I want to run Adobe products) that I could only use up to 1280&#215;1028 &#8212; even though the monitor&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I recently picked up a 26&#8243; monitor (<a href="http://www.necdisplay.com/Products/Product/?product=1713e080-c8e3-4aab-9447-73dacb301b84">NEC MultiSync LCD2690WUXi</a> &#8211; great price, even new, and excellent color gamut).  Unfortunately, I found that when I connected to the monitor in Vista (which I use when I want to run <a href="http://www.adobe.com/products/photoshoplightroom/">Adobe products</a>) that I could only use up to 1280&#215;1028 &#8212; even though the monitor&#8217;s native resolution was 1920&#215;1080!  It took a lot of searching, trial, and error to piece together a solution, but the following steps should enable you to run your monitor at full resolution if you have an <a href="http://ati.amd.com/">ATI video card</a>:</p>
<p><b>Update to the latest ATI driver and Catalyst Control Center</b> (optional) &#8211; This should be straightforward if you own a desktop, but on my Dell laptop ATI&#8217;s installers won&#8217;t upgrade your drivers (or even install new ones after you&#8217;ve uninstalled the old ones &#8212; apparently only the OEM drivers will install).  Anyway, Ruud Ketelaars has developed &#8220;<a href="http://www.driverheaven.net/modtool.php">Mobility Modder</a>&#8221; which can tweak the installation files so that you can upgrade your laptop&#8217;s ATI drivers.  You can find his software and instructions <a href="http://www.driverheaven.net/modtool.php">here</a> (scroll down).</p>
<p><b>Add the max resolution of your monitor to the available options:</b></p>
<ol>
<li>Open ATI&#8217;s Catalyst Control Center (CCC) by right-clicking on your desktop and clicking on the &#8220;Catalyst Control Center&#8221; option.</li>
<li>Make sure you are in advanced mode (lots of menus on the left side).</li>
<li>One of the menu options on the left side will be something like &#8220;Digital Panel (DVI) 2&#8243; and will probably be listed just under &#8220;Notebook Panel Properties 0&#8243; if you are using a laptop.  Click on the &#8220;HDTV Support&#8221; submenu of the &#8220;Digital Panel&#8221; menu.</li>
<li>Under &#8220;HDTV Support&#8221;, click the checkbox next to the resolution and refresh rate which you want to enable for your monitor.  For my monitor, this was &#8220;1920&#215;1080p50&#8243; (50Hz).</li>
<li>Click &#8220;Ok.&#8221;</li>
<li>Open Display Settings like usual and you&#8217;ll be able to choose the new resolutions you enabled (right-click on the desktop, choose Personalize, then Display Settings)</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://dound.com/2009/07/overcoming-vista-screen-resolution-limitations-with-an-ati-video-card/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
