Chapter 5. Some Hairy Design Details

FAILURE/RETRY info

The best place to store failure information is in the object CAUSING the problem. Like in the UnavailableHostCache, not in the message itself. The next time routingRun() is run, all Mits waiting for that host will go.

SMTPCaching
  • Keeps per-host status info. It needs to be shared among all Internet Routers.

  • Operation: update(domain,ip) Update SMTPCache records for host and/or domain. Call

SMTP RECEPTION
    MAIL FROM:
        mit = Director.createMit();
        mit.state = STATE_INCIPIENT;
        try {
            Director.headPipe.route(mit, true, null);
        } catch (Exception e) {
            Send error status to client.
            mit = null;
            return;
        }
    for each (RCPT TO:) {
        try {
            Director.headPipe.route(mit, true, null);
        } catch (Exception e) {
            Tell client that this recipient not allowed.
        }
    }
    DATA: (? skip this ?)
        try {
            Director.headPipe.route(mit, true, null);
        } catch (Exception e) {
            Send error status to client.
            mit = null;
            return;
        }
    mit.state = Mit.STATE_ROUTENOW
    mit.persist(false);
    // MIT will send it as soon as it can.  Don't want to make the
    // client wait for us after we have persisted it.
    SMTP
    • BULK TRANSMITS done by 1-level recursion, not by multithreading. (I think no need to check for recurse since there is no way to recurse other than 1 level in our recursion one case.

    • This incurs no multi-threading, although we have to deal with the existing multithreading in SMTPSession).

    OUTGOING SMTPConsumer
    • Always SMTPCaching.update(domain,ip) after every successful or failed conn.

    • Don't use the Incoming server for outgoing unless client ran ETRN.

    • It would be nice to use JavaMail, but I don't know if that supports bulk xmits. If not, could still use JavaMail for prototyping the SMTPSharedConsumer.

    • After first successful xmit to this domain, run

          Director.routingRun("nextPipe == " + mypipe
           + "destdomain == '" + destdomain + "'");
          If there are more Mits for this target ipaddr, then this
               router() method will be called recursively.
           ++recursecount;
           try {
              if (recursecount > 1) {
                  if (state != STATE.GREETED) throw... // assertion
                  piggyback(mit);
                  return;
              }
          } finally { --recursecount; }
          piggyback(mit) {
              out.println(mit.this...
              flush();
              return;
          }
    INCOMING SMTPServer
      • Always SMTPCaching.update(domain,ip) after every successful or failed conn.

      • Need to maintain a ETRN mode HashMap of currentThread X session.

      • When a SMTPSession gets an ETRN, it can run

                Director.routingRun("nextPipe == " + myPipe
                 + ip == '" + ipaddr + "'");
            SMTPServer.route(Mit mit, boolean ping) {
                if (ping == true) return;
                session = (SMTPSession) etrnSessions.get(Thread.currentThread());
                session.piggyback(mit);  // Same as in SMTPSession
                return;
            }