E-MailRelay
Classes | Public Member Functions | List of all members
GSmtp::ServerBufferIn Class Reference

A helper class for GSmtp::ServerProtocol that does buffering of data received from the remote peer and apply()s it to the server protocol. More...

#include <gsmtpserverbufferin.h>

Classes

struct  Config
 A configuration structure for GSmtp::ServerBufferIn. More...
 

Public Member Functions

 ServerBufferIn (GNet::EventState, ServerProtocol &, const Config &)
 Constructor. More...
 
 ~ServerBufferIn ()
 Destructor. More...
 
void apply (const char *, std::size_t)
 Called when raw data is received from the peer. More...
 
void expect (std::size_t)
 Forwards to GNet::LineBuffer::expect(). More...
 
std::string head () const
 Returns GNet::LineBufferState::head(). More...
 
G::Slot::Signal< bool > & flowSignal () noexcept
 Returns a signal that should be connected to a function that controls network flow control, typically by adding and removing the socket file descriptor from the event loop. More...
 
 ServerBufferIn (const ServerBufferIn &)=delete
 
 ServerBufferIn (ServerBufferIn &&)=delete
 
ServerBufferInoperator= (const ServerBufferIn &)=delete
 
ServerBufferInoperator= (ServerBufferIn &&)=delete
 

Detailed Description

A helper class for GSmtp::ServerProtocol that does buffering of data received from the remote peer and apply()s it to the server protocol.

The original SMTP protocol has a simple request/response setup phase followed by a streaming data transfer phase, so a GNet::LineBuffer can be used with no risk of overflow. The RFC-2920 PIPELINING extension develops this by defining request/response batches with a well-defined batch boundary before the data transfer phase.

RFC-2920 PIPELINING tries to define a size limit for an input batch, but only in terms of the network layer PDU size – which is useless in practice.

Unfortunately the RFC-3030 CHUNKING ("BDAT") extension is underspecified so there is no batch boundary prior to the data transfer phase. That means that in the worst case the remote client can start the data transfer before the setup commands have been fully processed and blow up the input buffer with megabytes of message body data. Therefore we have to use network flow control to limit the amount of buffering:

Server::Server() : m_buffer(...)
{
m_buffer.flowSignal().connect( slot(*this,&Server::onFlow) ) ;
}
void Server::onData( p , n )
{
m_buffer.apply(p,n) ;
}
void Server::onFlow( bool on )
{
on ? addReadHandler(m_fd) : dropReadHandler(m_fd) ;
}
Server(GNet::EventState es, GStore::MessageStore &, FilterFactoryBase &, VerifierFactoryBase &, const GAuth::SaslClientSecrets &, const GAuth::SaslServerSecrets &, const Config &server_config, const std::string &forward_to, int forward_to_family, const GSmtp::Client::Config &client_config)
Constructor.
Slot< Args... > slot(TSink &sink, void(TSink::*method)(Args...))
A factory function for Slot objects.
Definition: gslot.h:240

Definition at line 73 of file gsmtpserverbufferin.h.

Constructor & Destructor Documentation

◆ ServerBufferIn()

GSmtp::ServerBufferIn::ServerBufferIn ( GNet::EventState  es,
ServerProtocol protocol,
const Config config 
)

Constructor.

Definition at line 26 of file gsmtpserverbufferin.cpp.

◆ ~ServerBufferIn()

GSmtp::ServerBufferIn::~ServerBufferIn ( )

Destructor.

Definition at line 36 of file gsmtpserverbufferin.cpp.

Member Function Documentation

◆ apply()

void GSmtp::ServerBufferIn::apply ( const char *  data,
std::size_t  size 
)

Called when raw data is received from the peer.

Line buffering is performed and complete lines are apply()ed to the ServerProtocol. If the ServerProtocol cannot accept everything then the residue is queued and re-apply()d transparently.

Throws Done at the end of the protocol.

Definition at line 41 of file gsmtpserverbufferin.cpp.

◆ expect()

void GSmtp::ServerBufferIn::expect ( std::size_t  n)

Forwards to GNet::LineBuffer::expect().

Definition at line 112 of file gsmtpserverbufferin.cpp.

◆ flowSignal()

G::Slot::Signal< bool > & GSmtp::ServerBufferIn::flowSignal ( )
noexcept

Returns a signal that should be connected to a function that controls network flow control, typically by adding and removing the socket file descriptor from the event loop.

Definition at line 122 of file gsmtpserverbufferin.cpp.

◆ head()

std::string GSmtp::ServerBufferIn::head ( ) const

Returns GNet::LineBufferState::head().

Definition at line 117 of file gsmtpserverbufferin.cpp.


The documentation for this class was generated from the following files: