The random things that spew forth from my brain…

WTF

So. For a couple of weeks now, on and off, I’ve been trying to track down the source of my personal server being slow to log in via SSH. IT was slow… say… 98% of the time, and 2% of the time it was fast.

I thought maybe it was compromised somehow (and I did find some xmlrpc pingback reflection attacks being done using a site of mine… which I fixed) but it didn’t appear to be so.

Then I thought maybe it was some sort of network exhaustion. But my bandwidth, and my tcp connections as reported by netstat all looked very low.

I had some swap used, so I thought maybe there was something important in swap slowing the system down.

Turning to google and the various .*exchange(like)? site answers I tried setting usedns to no, and GSSAPIAuthentication to no. I cleared out some hosts.deny|allow entries, I even disabled some dynamic things in PAM for SSH, and finally turned PAM authentication off completely. disabled and configured the server not to use avahi

Nothing worked. Everything looked good… sshd loglevel was set to verbose and not giving me any signs… using ssh -v to connect didn’t show me anything out of the ordinary

Well that’s not true. It showed the problem but it wasn’t an “error”, so to speak, and so I didn’t immediately notice it.

It turns out that, since my server has an IPV6 address my ssh client was attempting to connect to it via IPV6 first. This is problematic because my internet connection has no such support.

If you’re ever in a situation where something is only happening intermittently, and only on a live server, and only while it’s under load… Lets say its not generating any error_log or stderr output, and you cant run it manually to reproduce… (we’ve all been in this situation) How do you get any debugging output at all?

When working with user provided images in PHP you run into a problem. Lets say that you want to generate thumbnails of uploaded JPEGs for users. This is a fairly common use case where you would employ PHP and GD (the most prevalent php image extension.) But when you generate the new, smaller, image what quality setting do you use? If your quality setting is too low then the image is distorted unacceptably. Likewise if your quality setting is too high then you produce a dimensionally smaller image with a larger size in bytes than the original. So what do you do when you want to satisfy all cases? Well the obvious answer is that you should use the same JPEG quality setting that the image had when it was uploading. Now… Using PHP and GD tell me how you accomplish this.

Go ahead

I’ll wait

You can’t, can you? If you’re really sneaky you might be thinking about just pulling the data out of the binary stream, and if you’re a linux nut you’re probably sitting there muttering “just use identify (a la imagemagick)”. Of course if you try that under heavy traffic you’ll soon discover that it kills your servers. Just for reference I’ll share that code with you (not everyone is serving 2g/sec in dynamic image traffic after all). We already have the binary data in ram in the $rval variable, in case you were curious.

So, since this consumes too much of our available resources (especially ram and cpu usage since identify fully decompresses and reads the image into a raw state for processing… hundreds of MB of ram, which you can limit but then it becomes unbearably slow…) that’s out. What now? If you’re really extra sneaky you’re thinking that you should be able to read the setting out of the binary data… there should be a header after all, right? Well… Yes there is a header but “quality” is not a “setting” its more a measure of how compressed the image is… which isn’t exactly recorded either… at least… not as an integer value. The compression matrix used to preform JPEGs lossy compression *IS* stored in a header.. and it turns out this is what the ImageMagick code uses to give us that quality setting. So I set out to reproduce this in PHP.

I know… I’m a masochist.

Thanks to some serious google-fu (and possibly a note in a php online doc manual relating to IPC, I don’t remember which of the two led me to the package first) I found that there’s already some code out there which deals with the nasty bits of reading raw JPEG headers (though not doing what I want with the header that I want) in the PHP JPEG Metadata Toolkit And the instructions for evaluating the header we can then pull is in the ImageMagick source code (coders/jpeg.c)

When we put the two together and modify it a bit to suite our needs (i.e. reading from the in-memory buffer, pulling just the right header from the jpeg file, etc) we get this code… and finally the ability to call $quality = get_jpeg_quality( $rval ); In my test (yea just one or two… very scientific like), this over 100 times faster than using the proc_open and executable method, uses less ram (a lot lot lot lot lot less ram) and generally just doesn’t suck as much.

Right… serious suckage. Which is why I’m sharing it here so that you don’t have to go through all that trouble. You can just steal my stolen code. Aren’t GPL compatible licenses fun?

Ok, finally, you… in the back… stop jumping up and down screaming about the Imagick PECL extension… In my testing getCompressionQuality() didnt work and getImageCompression() was unavailable (though I hear there is a newer version of the extension now… YMMV)

God I’m so tired of these commercials. What Kind of an idiot falls for this crap? OF COURSE DRIVERS WHO SWITCHED SAVED MONEY… If they didn’t save any money THEY WOULDN’T HAVE SWITCHED… Either of them… Plea to insurance agencies: Stop advertising to me like I’m the village idiot.