Squidly Goodness
Source: vex.fabulo.us
Credits: Vex Streeter
Dated: 2011-01-17
Tentacular magic for SL (Squidifying your viewer)
You might have seen Tateru Nino’s article Proxying Second Life HTTP Textures with Squid … And then gotten frustrated for any of a number of reasons. This mini-article expands on Tateru’s excellent post, adding two big hints: first use the right version of Squid and second how to get it working without fancy firewall rules. The bottom line is that using these two extra tricks you can get a (much!) larger than 1G texture cache working with existing SL client software and even get it all running on a single machine!
Obviously, this procedure will only really be interesting if you are running a Second Life viewer using HTTP textures – I’ve tested using both Linux and Windows versions of a number of official Viewer 2s as well as Phoenix (and Firestorm).
So hop in your deep sea submarine and follow me below the waves in search of the elusive… Second Life Squid! …
Latest isn’t always greatest!
First off, don’t use Squid 3! I know, I know – why would you want to use a crufty old squid when there is a nice bright and shiny new squid? Well, here’s the thing: first, texture requests are always addressed to the sim where the texture is seen. This is generally a fine thing, but the straightforward approach of caching would mean that the same texture seen on two different sims would be cached twice. For common textures this is a big waste of space and bandwidth.
But wait! it is even worse! Each request is identified by a “cap” UUID that authenticates the requester to the sim – also a fine thing, but it means that if two users see the same texture on the same object, on the same sim, the retrieve request will be different and, so, will be cached separately. Tateru’s article discusses these problems at the end in the “caching caveats” section and Robin Cornelius mentions the StoreURLRewrite fix in the comments (see below for my solution).
However, it turns out that when Squid was rewritten for version 3, the developers didn’t port the very feature we need. Instead, you want to back yourself up to Squid 2.7, which is likely still to be available for whatever OS you’d like.
What if I don’t have a Linux firewall?
Yes, you should always have a firewall protecting your windows machine from the jungle of the Intertubes (and if you don’t please don’t send me email or MS Office documents!) Most people just use commodity routers with integrated firewalls at home. If you had an efficient texture cache, you might also want to consider running such a cache on the same machine as your SL client: yes, it would compete with your client for CPU time, but you also could have as large a cache as you’d like and save your bandwidth for other purposes. Also, such a scheme would allow an SL laptop to get the benefits of a big cache without losing it when it gets moved from network to network.
Obviously you could not use the approach that Tateru suggests – SOCKS5 and explicit setting of HTTP proxy inside your viewer would enable this use but most http-texture enabled viewers have broken settings, only using the proxy setting with the internal browser to look at web pages (and media streams?). But it turns out that there is a simpler way available and you can use it now.
The viewers use a standard opensource library libCurl as its HTTP client. LibCurl has a neat feature that, by default, it looks at various environment variables to configure proxies. While this feature can be disabled, it is perfectly functional in the SL viewers that I’ve tried. This allows you to tell all http use in the viewer to go through whatever proxy you’d like, either on lan machine or localhost, simply by setting the right environment variable.
A 20G local cache for your SL
So here’s my recipe. There are lots of variations possible here, and I’m sure there is a lot of room for improvement, but the bottom line is that this works, today. The scenario that I’m describing is setting up a 20G squid texture cache for use only by viewers running on the same machine. I’ll focus on doing this on Linux (since that’s what I’ve set up), but other OSes are actually pretty similar – I’ll include notes on others along the way.
-
- Install Squid 2.7 (NOT 3.anything!). Don’t do anything fancy here, just get it installed as is.
- Make the changes to the configuration file /etc/squid/squid.conf. I like interspersing the changes into the “right” section wherever possible, In my own file, I’ve marked my additions with “(vex)”. Note that anything after a “#” is a comment and is ignored by squid. Also, order matters! In particular, if the first rule to apply to a URL says “don’t allow” then it will not be allowed, even if a later rule would negate that restriction.
- add (or change) the cache_dir line to specify a biggish cache. I promised 20G, so make sure you’ve got that much spare space and then do this:
1# comment out thedefault(ifit isn't already)- 100M just isn't enough! (vex)2#cache_dir ufs /var/spool/squid100162563# big cachefortextures (vex)4cache_dir aufs /var/spool/squid2000016256I’m specifying a cache of 20000 megabytes there, distributed inside 16 top level directories, each with 256 subdirectories inside to hold the actual cache files. Play around if you’d like, but don’t go nuts right away. I’m also using threaded (aufs) cachefile access rather than not, as I like threads
- Add the http textures port to the list of safe http ports to use – probably not required because it is already covered in most default configutaion files, but worth making explicit. Add to the acl section:
1acl Safe_ports port12046# Second Life HTTP textures (vex) - If you want to be able to use the cache from any machine on your LAN, you’ll want to be sure that the following lines aren’t commented:
1acl localnet src192.168.0.0/16# my standard internal network (vex)2http_access allow localnet #allow access by anyone on my lan (vex) - Set up a transparent proxy service on port 3178 – this is the port we’ll tell the viewer to use:
1# (vex)2http_port3178transparent - Tell squid how to handle textures! Position is important here – I added this line just before the first refresh_pattern line in the file.
1#thisneeds to come before the ? and . SL Texture cache (vex)2refresh_pattern agni.lindenlab.com1008090%44640ignore-reload ignore-privateignore-no-cacheHere we say “any resources that point to agni.lindenlab.com (i.e. main grid textures) can be cached for at least a week (10080 minutes) and up to a month or 90% of their age, regardless of what the server says we should do” [Edit: removed ignore-no-store directive, left over from dancing with Squid 3.x].
- Viewers have a mechanism to get partial textures by requesting just the first N bytes. Thats great for the viewer, but we only want to cache the whole texture so we need to get the whole thing every time by setting range_offset_limit to -1:
1# (vex)2range_offset_limit -1 - Viewers have a mechanism to get partial textures by requesting just the first N bytes. Thats great for the viewer, but we only want to cache the whole texture so we need to get the whole thing every time by setting range_offset_limit to -1:
1# rewrite rulesforSL textures! (vex)2acl store_rewrite_list dstdomain .agni.lindenlab.com3storeurl_access allow store_rewrite_list4storeurl_access deny all5storeurl_rewrite_program /etc/squid/url_rewrite_textures.plThis says, invoke the store rewriter on urls that include .agni.lindenlab.com by calling the script in /etc/squid/url_rewrite_textures.pl.
- add (or change) the cache_dir line to specify a biggish cache. I promised 20G, so make sure you’ve got that much spare space and then do this:
- The “store rewriter” is the special sauce that makes it all worthwhile. As Tateru points out, the URLs that the viewer requests don’t lend themselves very well to caching. But with the above recipe (and Squid 2.7!), we can tell squid to rewrite those URLs just for storage purpose! This is an important point – we are not changing the URLs used to request or retrieve anything – what we are doing is telling under which name should content be cached. You can do any transformation you’d like here.
What I do below is tell it to store any texture resource under the name “http://texture.lindenlab.com.INTERNAL/(texturekey)” I created this as a perl script and put it in /etc/squid with the squid.conf file. Location and name isn’t critical, but it needs to be executable and match the name given at the end of the squid.conf modifications above. Without further ado, here’s my script for /etc/squid/url_rewrite_textures.pl :01#!/usr/bin/perl02$| =1;03while(<>) {04chomp;05if(m/http:\/\/.*lindenlab.com:12046\/cap.*\?texture_id=(.*)/) {06print"http://texture.lindenlab.com.INTERNAL/".$1."\n";07}else{08print $_ ."\n";09}10} - initialize the cache:
1$ sudo squid -zAll this does is set up your cache directory, mainly by creating all the appropriate directories and starter cache files.
- set the environment variable. For purposes of discussion, I’m going to assume you are using bash or similarly bourne-shellish syntax:
1$ export http_proxy=http://127.0.0.1:3178This, of course, is the incantation that tells libCurl to use 127.0.0.1 (also known as localhost) port 3178 as an http proxy. ANY application that uses libCurl that executes with that setting will use it. This might be a problem if Squid used libCurl, but we’re lucky there. Of course, if you happen to have set up your cache on another machine on your lan instead of your client, you can put your cache machine’s IP address in there. For instance, at home, I have a setup where my Windows 7 SL machine points at a squid cache that I’ve set up on a little linux box for this pupose:
1Computer properties ->2Advanced System Settings ->3(advanced tab) ->4Environment Variables ->5User Variables (new) ->6Variable=http_proxy, Value=http://192.168.1.99:3178 - test using the curl command:
1$ curl http://cnn.comdid it print the html of the cnn front page? The other thing to do is check the squid logs:
1$ sudo tail /var/log/squid/access.logNote the last entry – it should mention cnn, indicating that the request actually went went through our cache.
- test using SL! You are probably fine running like this, but you may always set the http_proxy value you in a shell script that runs your viewer (or a bat script if you are on windows). And of course when the various viewers introduce a working http proxy setting, you can stop using the environment variable and point the viewer at the squid you’ve just set up.
I like to do a “tail -f /var/log/squid/access.log” to watch the textures getting cached – any line with MISS is a texture getting grabbed from LL… any line with HIT is one that the cache found that didn’t have to go back to the Linden servers. Yay!
- Printer-friendly version
- Login or register to post comments
