cancel
Showing results for 
Search instead for 
Did you mean: 

Problem this snippet solves:

This is basic iRule which acts as a standalone SMTP server. I needed this when we shut down one of our old servers and wanted to give users some indication that server is gone and they should start to use another servers. Another use might some sort of maintenance break which is on the code example since the response code of course differs if situation is permanent. Because in my case situation is permanent I use reply code 554 5.7.1 on my own server. I have tested this with Postfix and Thunderbird.

The address for our server is public so you can test how it responses. Address is smtp.inet.fi on port 25. I can't promise that it will be there forever.

This example is based on SMTPProxy.

There is also this thread on the forums http://devcentral.f5.com/Forums/tabid/53/aft/57250/afv/topic/Default.aspx which has same kind of solution too. I think that I have loaned some of the code from there too, comments looks quite familiar.

RFC 2821 http://www.ietf.org/rfc/rfc2821.txt RFC 3463 http://www.ietf.org/rfc/rfc3463.txt

Code :

when RULE_INIT {
    set ::HANDLING "220 mail.example.com ESMTP\r\n"
    set ::HANDLING2 "250 mail.example.com\r\n"
    set ::FAILURECODE "421 4.3.0"
    set ::FAILURERESPONSE "MAIL.EXAMPLE.COM is going through maintenance, try again later. \r\n"
}

when CLIENT_ACCEPTED  {
    TCP::respond "$::HANDLING"
    TCP::collect
    set data 0
}

when CLIENT_DATA {
      if { $data } {
            # loop to swallow data
            if { [TCP::payload] starts_with "\r\n.\r\n" } {
                  #found end of message
                  set respond "250 OK\r\n"
                  set data 0
            } else { 
                  set respond ""
            }
      } else {
            switch -glob [string toupper [TCP::payload]] {
                  DATA* {
                        set respond "354 Start mail input; end with .\r\n" 
                        set data 1 
                        }
                  QUIT* {
                        TCP::payload replace 0 [TCP::payload length] ""
                        TCP::respond "221 Bye\r\n"
                        TCP::close
                        return
                        }
                  RCPT* {
                        set respond "$::FAILURECODE $::FAILURERESPONSE"
                        }
                  EHLO* {
 set respond $::HANDLING2
                        }
                  HELO* {
 set respond $::HANDLING2
                        }
                  default {
 set respond "250 Ok\r\n"
                        }
            }
      }

      TCP::payload replace 0 [TCP::payload length] ""
      if { $respond ne "" } { TCP::respond $respond }
      TCP::collect
}
Version history
Last update:
‎17-Mar-2015 13:07
Updated by:
Contributors