Example #1
0
void SMTP::react( Event e )
{
    switch ( e ) {
    case Read:
        setTimeoutAfter( 1800 );
        parse();
        break;

    case Timeout:
        log( "Idle timeout" );
        enqueue( "421 Tempus fugit\r\n" );
        Connection::setState( Closing );
        break;

    case Connect:
    case Error:
    case Close:
        break;

    case Shutdown:
        enqueue( "421 Server shutdown\r\n" );
        break;
    }
    execute();
}
Example #2
0
POP::POP( int s )
    : SaslConnection( s, Connection::Pop3Server ),
      d( new PopData )
{
    d->challenge = randomChallenge();
    ok( "Archiveopteryx POP3 server ready " + d->challenge );
    setTimeoutAfter( 600 );
    EventLoop::global()->addConnection( this );
}
Example #3
0
void Connection::substitute( Connection * other, Event event )
{
    EventLoop::global()->removeConnection( this );
    setTimeoutAfter( 10 );
    d->type = other->d->type;
    d->l = other->d->l;
    other->d = d;
    other->d->pending = true;
    other->d->event = event;
    EventLoop::global()->addConnection( other );
}
Example #4
0
    void connect()
    {
        log( "Trying " + target.string(), Log::Debug );

        if ( Connection::connect( target ) < 0 ) {
            next( true );
            return;
        }

        setTimeoutAfter( 1 );
        EventLoop::global()->addConnection( this );
    }
Example #5
0
IMAP::IMAP( int s )
    : SaslConnection( s, Connection::ImapServer ), d( new IMAPData )
{
    if ( s < 0 )
        return;

    EString banner = "* OK [CAPABILITY " +
                    Capability::capabilities( this ) + "] " +
                    Configuration::hostname() +
                    " Archiveopteryx IMAP Server";
    if ( !Configuration::toggle( Configuration::Security ) )
        banner.append( " (security checking disabled)" );
    banner.append( "\r\n" );
    enqueue( banner );
    setTimeoutAfter( 120 );
    EventLoop::global()->addConnection( this );
}
Example #6
0
void IMAP::setUser( User * user, const EString & mechanism )
{
    log( "Authenticated as " + user->login().ascii() + " using " +
         mechanism, Log::Significant );
    SaslConnection::setUser( user, mechanism );
    setState( Authenticated );

    bool possiblyOutlook = true;
    List< Command >::Iterator i( d->commands );
    while ( i && possiblyOutlook ) {
        EString tag = i->tag();
        ++i;
        if ( tag.length() != 4 || tag.contains( '.' ) )
            possiblyOutlook = false;
    }
    if ( possiblyOutlook )
        setClientBug( Nat );
    setTimeoutAfter( 1860 );
}
Example #7
0
SMTP::SMTP( int s, Dialect dialect )
    : SaslConnection( s, Connection::SmtpServer ), d( new SMTPData )
{
    Scope x( log() );
    d->dialect = dialect;
    switch( dialect ) {
    case Smtp:
        enqueue( "220 ESMTP " );
        break;
    case Lmtp:
        enqueue( "220 LMTP " );
        break;
    case Submit:
        enqueue( "220 SMTP Submission " );
        break;
    }
    enqueue( Configuration::hostname() );
    enqueue( "\r\n" );
    setTimeoutAfter( 1800 );
    EventLoop::global()->addConnection( this );
}
Example #8
0
    void react( Event e )
    {
        // If we've succeeded in making a connection, we can kill all of
        // the other connectors and substitute ourselves for the parent
        // connection.

        if ( e == Connect ) {
            List<SerialConnector>::Iterator it( connectors );
            while ( it ) {
                SerialConnector * sc = it;
                if ( sc != this ) {
                    EventLoop::global()->removeConnection( sc );
                    sc->close();
                }
                ++it;
            }
            substitute( host, Connect );
            host->setState( Connecting );
        }

        // If there's an Error, we know we won't be able to connect, so
        // we remove ourselves from the List of connectors and connect()
        // the next one in line. If the initial 1-second timeout expires
        // we extend the timeout and yield without removing ourselves,
        // since the connection attempt may yet succeed.

        else if ( e == Error || e == Timeout ) {
            if ( e == Timeout ) {
                setTimeoutAfter( 10 );
                timeouts++;
            }

            next( e == Error || timeouts > 1 );
        }

        else {
            // XXX: If the EventLoop starts forwarding Read etc. to us,
            // we're deeply screwed.
        }
    }
Example #9
0
void POP::react( Event e )
{
    switch ( e ) {
    case Read:
        setTimeoutAfter( 600 );
        parse();
        break;

    case Timeout:
        // We may not send any response.
        log( "Idle timeout" );
        Connection::setState( Closing );
        break;

    case Connect:
        break;

    case Error:
        Connection::setState( Closing );
        break;

    case Close:
        break;

    case Shutdown:
        // RFC 1939 says that if the server times out, it should close
        // silently. It doesn't talk about server shutdown, so it
        // sounds sensible to do nothing in that case as well.
        break;
    }

    if ( d->state == Update )
        Connection::setState( Closing );
    if ( Connection::state() == Closing && session() )
        session()->end();
}
Example #10
0
void IMAP::react( Event e )
{
    d->bytesArrived += readBuffer()->size();
    switch ( e ) {
    case Read:
        parse();
        if ( d->bytesArrived > 32768 && state() == NotAuthenticated ) {
            log( ">32k received before login" );
            enqueue( "* BYE overlong login sequence\r\n" );
            Connection::setState( Closing );
            if ( d->reader ) {
                Scope s( d->reader->log() );
                d->reader->read();
            }
        }
        break;

    case Timeout:
        if ( state() != Logout ) {
            log( "Idle timeout" );
            enqueue( "* BYE Tempus fugit\r\n" );
        }
        Connection::setState( Closing );
        if ( d->reader ) {
            Scope s( d->reader->log() );
            d->reader->read();
        }
        setSession( 0 );
        break;

    case Connect:
        break;

    case Error:
    case Close:
        if ( session() ) {
            log( "Unexpected close by client" );
            setSession( 0 );
        }
        if ( !d->commands.isEmpty() ) {
            List<Command>::Iterator i( d->commands );
            while ( i ) {
                Command * c = i;
                ++i;
                if ( c->state() == Command::Unparsed ||
                     c->state() == Command::Blocked ||
                     c->state() == Command::Executing )
                    c->error( Command::No,
                              "Unexpected close by client" );
            }
        }
        break;

    case Shutdown:
        enqueue( "* BYE server shutdown\r\n" );
        if ( session() && d->commands.isEmpty() )
            setSession( 0 );
        break;
    }

    runCommands();

    d->bytesArrived -= readBuffer()->size();

    if ( timeout() == 0 ||
         ( e == Read && state() != NotAuthenticated ) ) {
        switch ( state() ) {
        case NotAuthenticated:
            setTimeoutAfter( 120 );
            break;
        case Authenticated:
        case Selected:
            if ( idle() )
                setTimeoutAfter( 3600 ); // one hour while IDLE
            else
                setTimeoutAfter( 1860 ); // a half-hour without
            break;
        case Logout:
            break;
        }

    }
}