Thursday, July 22, 2010
An update to a quick note on embedding languages within languages
In making this comment I came across this old post of mine from 2007 where I lament the amount of code required to query SNMP values in C. I took one look at the code I wanted:
OID sys = SNMPv2-MIB::sysObjectID.0; if (sys == SNMPv2-SMI::enterprises.5567.1.1) /* riverstone */ { IpAddress destination[] = IP-MIB::ip.24.4.1.1; IpAddress mask[] = IP-MIB::ip.24.4.1.2; IpAddress nexthop[] = IP-MIB::ip.24.4.1.4; int protocol[] = IP-MIB::ip.24.4.1.7; int age[] = IP-MIB::ip.24.4.1.8; int metric[] = IP-MIB::ip.24.4.1.11; int type[] = IP-MIB::ip.24.4.1.6; } else if (sys == SNMPv2-SMI::enterprises.9.1) /* cisco */ { IpAddress destination[] = RFC1213-MIB::ipRouteDest; IpAddress mask[] = RFC1213-MIB::ipRouteMask; IpAddress nexthop[] = RFC1213-MIB::ipRouteNextHop; int protocol[] = RFC1213-MIB::ipRouteProto; int age[] = RFC1213-MIB::ipRouteAge; int metric[] = RFC1213-MIB::ipRouteMetric1; int type[] = RFC1213-MIB::ipRouteType; } for (i = 0 ; i < destination.length; i++) { print( destination[i], mask[i], nexthop[i], snmp.protocol(protocol[i]), metric[i], age[i] ); }
and remembered—I did that!
Yup. Back in September of 2009 when I first started playing around with Lua. I installed the SNMP bindings for Lua and wrote the following:
#!/usr/local/bin/lua -- http://luasnmp.luaforge.net/snmp.html snmp = require "snmp" OID = snmp.mib.oid routeprotos = { "other ", "local ", "netmgmt ", "redirect ", "egp ", "ggp ", "hello ", "rip ", "is-is ", "es-is ", "igrp ", "bbnspf ", "ospf ", "bgp " } print(" Dest Mask NextHop Proto Metric Age") print("-------------------------------------------------------------------------------") router = assert(snmp.open{ peer = arg[1] or "XXXXXXXXXXXXXXXXXXXXXXXXX" , community = arg[2] or "XXXXXXXXX" }) cisco = OID "SNMPv2-SMI::enterprises.9.1" riverstone = OID "SNMPv2-SMI::enterprises.5567.1.1" sysid = router["SNMPv2-MIB::sysObjectID.0"] if string.find(sysid,cisco,1,true) then shouldbe = OID "RFC1213-MIB::ipRouteDest" result = { { oid = "RFC1213-MIB::ipRouteDest" } , { oid = "RFC1213-MIB::ipRouteMask" } , { oid = "RFC1213-MIB::ipRouteNextHop" } , { oid = "RFC1213-MIB::ipRouteProto" } , { oid = "RFC1213-MIB::ipRouteMetric1" } , { oid = "RFC1213-MIB::ipRouteAge" } , } elseif string.find(sysid,riverstone,1,true) then shouldbe = OID "IP-MIB::ip.24.4.1.1" result = { { oid = "IP-MIB::ip.24.4.1.1" } , { oid = "IP-MIB::ip.24.4.1.2" } , { oid = "IP-MIB::ip.24.4.1.4" } , { oid = "IP-MIB::ip.24.4.1.7" } , { oid = "IP-MIB::ip.24.4.1.11" } , { oid = "IP-MIB::ip.24.4.1.8" } , } end repeat result,err = snmp.getnext(router,result); if result ~= nil then if string.find(result[1].oid,shouldbe,1,true) == nil then break end print(string.format("%-16s",result[1].value) .. string.format("%-16s",result[2].value) .. string.format("%-16s",result[3].value) .. routeprotos[result[4].value] .. string.format("%-6d",result[5].value) .. string.format("%-6d",result[6].value) ) end until false os.exit(0)
Those email server blues
I'm concerned that eventually it will no longer be possible to run a private email server and that everyone will end up using Gmail, Yahoo or MySpaceFaceBook because that's the only way we will be able to get email.
Occasionally Dad will call asking why his email to me is bouncing, and every time I check, it's because AOL is taking the forced transitory failure (as generated by my greylist daemon) as “I can't deliver this in one shot, so of course that email address is bogus.” So I've had to whitelist all of AOL.
I had a similar problem with MyFaceSpaceBook. One or two transitory failures and my email address is considered bogus. Another whole swath of IP addresses whitelisted.
Then Corsair writes in about his emails to be being bounced.
Sigh.
Corsair's case I can't really figure out. From the logs:
Jul 18 04:28:36 brevard gld: [98587] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 18 08:28:36 brevard gld: [98799] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 18 12:28:37 brevard gld: [99052] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 18 16:28:37 brevard gld: [99309] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 18 20:28:38 brevard gld: [99491] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 00:28:38 brevard gld: [99675] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 04:28:39 brevard gld: [99944] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 08:28:39 brevard gld: [100234] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 12:28:40 brevard gld: [100509] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:00:38 brevard gld: [100595] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:01:09 brevard gld: [100596] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:05:38 brevard gld: [100604] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:06:09 brevard gld: [100605] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:13:09 brevard gld: [100610] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:13:40 brevard gld: [100613] tuple: [XXXXXXXX.194 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:24:24 brevard gld: [100629] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 14:41:18 brevard gld: [100641] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] GRAYLIST GREYLIST Jul 19 15:06:38 brevard gld: [100678] tuple: [XXXXXXXX.195 , XXXXXXXXXXXXXXXXXXXXXXX , sean@conman.org] ACCEPT WHITELIST
His email should have gone through on the second attempt, as it was only four hours, which is less than the six hours it takes to purge unreferenced tuples. Others I can explain; the third becuase it's from a different IP address, and the fourth becuse it definitely is past the six hour lifetime of an unreferenced tuple. Same for the fifth, but again, I can't explain why it wasn't accepted by the sixth attempt.
My initial thought was that it had something to do with searching the tuple list. I recently rewrote the binary search code so it was not only half the size, but much clearer, but maybe it doesn't work. Maybe I missed some subtle boundary condition.
50,000,000 tests later (no, really!), and no, both the old binary search routine and the new binary search routine return identical results. If there is a corner case, 50,000,000 random tests was not enough to reveal it. So I doubt it's that code.
About the only thing I can think of (and I haven't tested this) is that the timeout for old tuples is not what I think it is, but when I query my greylist daemon it returns a value of six hours for the lifetime of a greylisted tuple.
In any case, I whitelisted Corsair's email address. And I'm pondering why I even run my own email server any more …
How not to design a PHP web site
I don't even know where to begin.
One of the tasks our team is currently working on for “Project: SocialSpace2.0” is to separate the user uploaded content (images, videos, etc) to its own webserver (what we're calling “the static content”) to make it easier to scale out the site.
My task is to figure out how the content is uploaded to the site. This
is not an easy task. The proprietary PHP framework (where have I heard that tale before?) consists of
over 400,000 lines of undocumented code (but of course!) spread across 3,000
files (really!) that is a prime example of why object oriented programming
can be a Bad Thing™ (early on in the project, I was curious as to how
far down the rabbit hole this code went, so I spent some time starting with
the topmost PHP file and replacing each require_once()
function
call with the code it referenced; I stopped after including over 15,000
lines of code and that's before anything is executed).
The automagical code is amazing. Even though I changed
$EO->set_setting('FS_IMAGE_UPLOAD_PATH','uploads/images/ );
which is relative to the DOCUMENT_ROOT
and thus, hard to
move to its own domain, to
$EO->set_setting('FS_IMAGE_UPLOAD_PATH','/home/spc/tmp/images/');
the content is still save to the old location, thus making it harder to move the content to its own domain.
Going further—the actual upload control on the webpage is a Flash program (lovely), which apparently is controled by some Javascript (oh it's getting better) that is generated on the fly (can you feel the love) and yet still manages to hardcode the destination directory.
Wow! I'm seriously impressed by the previous team's work.
This is going to be painful, I can tell.