Tuesday, September 25, 2007
Abstraction for its own sake
This is a rather small and unfocused rant on unnecessary abstractions. It may be related to this wiki page on abstraction not scaling; it may not be (told you this was unfocused).
I'm in the process of writing the Sendmail interface for the greylist daemon, and as far as that goes, it's very simple for this application—it just requires the writing of four functions, one that's given the IP address of the remote SMTP server, one that's given the sender email address, one that's given the recipient email address, and one to clean up any resources allocated from the other functions.
Like I said, pretty easy and straightforward.
The oddness comes in the first function's definition. It's:
sfsistat xxfi_connect(SMFICTX *ctx,char *hostname,_SOCK_ADDR *hostaddr);
The _SOCK_ADDR
variable contains the IP address of the remote SMTP server. What is it? I
dunno. What does it contain? I dunno. All I care about is the actual
IP address, and I presume it's
somewhere in this variable (most likely a structure of some kind). But
there's no further API for pulling any useful information out of this
_SOCK_ADDR
.
Well, let's dive into the header files:
#ifndef _SOCK_ADDR # define _SOCK_ADDR struct sockaddr #endif /* ! _SOCK_ADDR */
For some reason, the writers of Sendmail felt it prudent to hide the
definition of the IP address
behind another name. Presumably to make their code more portable to other
non-BSD-derived
network stacks that don't use struct sockaddr
to store IP addresses.
But that does my code no good. I don't care about the hostname, I care about the IP address, yet without further information, I don't know exactly what I have. Is it the binary form of the address? How big? (there's IPv4, in which each address is 32 bits long, and IPv6, in which each address is 128 bits long) I had to dive into the header files to find out what exactly I'm given.
And it's not like the above definition of _SOCK_ADDR
is
wrapped around other #ifdef
's checking for various operating
systems or network stacks. The above definition is it! That's all
there is.
So I really have to wonder why they felt this further abstraction for their code was necessary. It seems to be abstraction for abstraction's sake. Here's a hint: you aren't going to need it.