[Ilugc] The design of the SMTP Proxy

  • From: girishvenkatachalam@xxxxxxxxx (Girish Venkatachalam)
  • Date: Tue, 2 Apr 2013 20:08:42 +0530

Actually I am not sure if the heart of my product is actually a
 TCP proxy or an SMTP proxy.

I don't try to interpret SMTP commands beyond a point.

Actually it is an SMTP proxy. Yes.

It is so because I look at the 'DATA' command which
 actually sends out the headers and body of the mail and
 process it and then deliver it to the TCP pipe of the
 mail server or drop it sending an error 550 response code
 to the sending mail client.

A TCP proxy would only look at a TCP shutdown or so.

The design of my 3500 line C code is actually very very interesting.

It could be smaller since I have an auth socket which is actually
 not something I have implemented yet.

In these many lines of C code a lot of things happen.

It was not written easily or in a week or so.

It took I think around 2 months to write and to fix the most
critical bugs it took more than 4 months I think.

And it is only now that the code is production quality. So it
 has taken more than a year.

The larger aspects of the design which we in software parlance
 call as a 35,000 feet view itself is quite complicated and
 requires substantial technical knowledge.

Try discussing this with your manager in a big software company
and I can wager, nobody would be able to figure out what this means.

Anyway I will describe the parts:

*) Daemonize(chdir /, setsid, daemon(2) and so on)

*) fork() model for concurrent processing(hardest part)
 How to clean up and how not to crash your system

*) multiple sockets, UNIX domain, 3 TCP sockets, client and server

*) poll(2) based relaying in which you act as proxy, again hard

*) the real engine which reads, writes, creates temporary files
 using mkstemp() and does other munching, only the
 offset calculation when writing to a file is tough

*) the SMTP proxy part which does interpretation of SMTP commands
 like DATA, RECV FROM, HELO/EHLO

*) other features like passive OS fingerprint, invoking spam,virus check,
 SURBL analysis, SPF, DNS and so on

*) communication between multiple processes for keeping track of
 counters like mails rejected, total mail attempts, I used a UNIX
 domain socket, instead you could use shared memory. I think I
 first tried shared memory, but liked UNIX sockets better

*) Using linked lists to keep track of configuration parameters and
 iterate through lists of blocked mail IDs, doing network matching
  and blocked MIME types, attachments

*) Config file parsing at startup and reading it on SIGHUP signal

*) clearing the statistics counters everyday(using setinterval()
timer)

*) responding to statistics requests on a UNIX domain socket
 for the web interface

*) logging SMTP handshake using syslog

And so on.

Really easy eh?

-Girish
-- 
Gayatri Hitech
http://gayatri-hitech.com

Other related posts:

  • » [Ilugc] The design of the SMTP Proxy - Girish Venkatachalam