Class Connection.

Inherits Garbage. Inherited by Database, EntropyProvider, GraphDumper, LdapRelay, LogServer, SaslConnection and SmtpClient.

Represents a single TCP connection (or other socket).

This class contains code that is shared between different types of connections, including the Listener (which accepts connections and creates new Connection objects) and the IMAP server class.

A connection knows about its state(), type(), socket fd(), next timeout(), and its self() and peer() endpoints (if applicable). It also has a readBuffer() and a writeBuffer(). There is a description() that returns a text string describing the connection.

The react() function is the main interface between the Loop and each Connection object. It must be implemented by subclasses, and is used to tell the object about Connection::Events that have occurred (Read, Timeout, etc.).

Connection::Connection( int fd, Type type )

Creates an Inactive type connection using fd.

Connection::Connection()

Creates an Invalid connection with no associated FD.

Reimplements Garbage::Garbage().

int Connection::accept()

Accepts a queued connection from a listening socket, and returns the newly created FD, or -1 on error. Should only be called on Listening connections.

bool Connection::accessPermitted() const

Returns true if this Connection can access mail, and false if not. Bases its decision on the allow-plaintext-access configuration variable.

bool Connection::active() const

Returns true if this connection is in active use, and false if it is not.

static bool Connection::any6ListensTo4()

Returns what setAny6ListensTo4() set, or false initially.

bool Connection::canWrite()

Returns true if we have any data to send.

void Connection::close()

Closes this connection.

int Connection::connect( const EString & address, uint port )

This form of connect() takes an address (e.g. "localhost") and port instead of an Endpoint. It tries to resolve that address to a list of connection targets; and tries to connect to each of those in turn. The first successful connection is used, and the caller is notified by the EventLoop as usual. It can use peer() to find out which address we actually connected to.

If address resolves to only one thing (e.g. it is an IP address already, or a Unix-domain socket, or a hostname that maps to only one address), this function just calls the usual form of connect() on the result.

Returns -1 on failure (i.e. the name could not be resolved to any valid connection targets), and 0 on (temporary) success.

This function disregards RFC 3484 completely, and instead issues many (partially concurrent) TCP connections. We think many concurrent connections is better than serial ordered approach 3484 prescribes, but combining the two approaches would be even better (ie. order as 3484 says, but issue connection as we do).

int Connection::connect( const Endpoint & e )

Connects to the specified endpoint e. If the operation succeeds, the connection enters one of the Connected or Connecting states (in the latter case, the connection should expect one of the Connect or Error events). Returns -1 on error.

If the connection is not valid, a socket is created and associated with it first.

EString Connection::description() const

Returns a single-line text string describing this connection. The string is intended for debugging.

Subclasses may reimplement this if this implementation is insufficient.

void Connection::enqueue( const EString & s )

Appends s to this Connection's writeBuffer().

void Connection::extendTimeout( uint n )

Extends the existing timeout() by n seconds. Does nothing if no timeout is set.

int Connection::fd() const

Returns the FD associated with a connection, or a negative number if the connection is invalid.

bool Connection::hasProperty( Property p ) const

Returns true if this Connection has p. The return value based on type() and self().

bool Connection::hasTls() const

Returns true if TLS has been or is being negotiated for this connection, and false if not.

void Connection::init( int fd )

This private function associates a Connection with an fd and sets its state to Inactive. It does nothing if the connection is already valid, or if fd is negative.

bool Connection::isPending( Event e )

Returns true only if the Event e is pending on this Connection.

int Connection::listen( const Endpoint & e, bool silent )

Listens to the specified endpoint e. If the operation succeeds, the connection enters the Listening state. If not, -1 is returned, and the connection state is unchanged.

If the connection is not valid, a socket is created and associated with it first.

Logs errors only if silent is false.

(Why does this return an int instead of a bool?)

void Connection::log( const EString & m, Log::Severity s )

Logs the message m with severity s using this Connection's Log object.

Log * Connection::log() const

Returns the Log used by this Connection. This is never a null pointer.

Endpoint Connection::peer() const

Returns an Endpoint representing the remote end of the connection, an invalid Endpoint if something goes wrong (for example, if the connection is inactive).

void Connection::react( Event event )

Subclasses are required to define this method to react appropriately to event notifications from the main loop.

void Connection::read()

Reads waiting input from the connected socket. Does nothing in case the Connection isn't valid().

Buffer * Connection::readBuffer() const

Returns a pointer to the connection's read buffer.

Endpoint Connection::self() const

Returns an Endpoint representing the local end of the connection, or an invalid Endpoint if something goes wrong (for example, if the connection is inactive).

static void Connection::setAny6ListensTo4( bool e )

Records whether listening to :: ("any ipv6 address") also listens to 0.0.0.0 ("any ipv4 address"). Listener calls it with e true if that is the case, and stops trying.

void Connection::setBlocking( bool block )

Makes the connection non-blocking if block is false, or blocking if it is true.

void Connection::setState( Connection::State st )

Sets the connection state to st, which must be one of the following states:

Invalid: No valid FD (just created or closed).

Inactive: Valid, but unused FD.

Listening: Valid FD in SYN_RECV.

Connecting: Valid FD in SYN_SENT.

Connected: Connected FD.

Closing: Connected FD, but will be closed (and revert to Invalid) once the write buffers have been flushed.

void Connection::setTimeout( uint tm )

Sets the connection timeout to tm seconds from the epoch.

void Connection::setTimeoutAfter( uint n )

Sets the connection timeout to n seconds from the current time.

void Connection::setType( Type type )

Notifies this Connection that it really is of type, contrary to whatever it may earlier have believed. It also correctly sets the Log facility used by this connection.

This function is for use by classes (e.g. Listener, Database) that use the default Connection constructor, but don't want its default connection type of "Client".

static int Connection::socket( Endpoint::Protocol p )

Returns a new TCP socket for the protocol p, or -1 on error.

void Connection::startTls( TlsServer * s )

Starts TLS negotiation using s on this connection.

State Connection::state() const

Returns the current state of the connection.

void Connection::substitute( Connection * other, Event event )

This very evil function exists to help a SerialConnector (above) to substitute itself for another connection other, which called the two-argument form of connect(). This function should not be called by anyone else, and nobody should wonder what event is.

uint Connection::timeout() const

Returns the time (in seconds since the epoch) at or after which this connection expects to receive a Timeout event. The default value of 0 means that the connection does not want Timeout events.

Type Connection::type() const

Returns the Type of this Connection, as set using the constructor.

bool Connection::valid() const

Returns true if this Connection object is valid and usable, and false if not. In practice, false means that its socket is bad. Short for state() != Connection::Invalid.

void Connection::write()

Writes pending output to the connected socket. Does nothing in case the Connection isn't valid().

Buffer * Connection::writeBuffer() const

Returns a pointer to the connection's write buffer.

Connection::~Connection()

Closes this connection. The object remains mostly valid, as GC is expected to do the memory deallocation.

This web page based on source code belonging to The Archiveopteryx Developers. All rights reserved.