libfilezilla
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
socket_layer Class Reference

A base class for socket layers. More...

#include <socket.hpp>

Inheritance diagram for socket_layer:
Inheritance graph
[legend]
Collaboration diagram for socket_layer:
Collaboration graph
[legend]

Public Member Functions

 socket_layer (event_handler *handler, socket_interface &next_layer, bool event_passthrough)
 
 socket_layer (socket_layer const &)=delete
 
socket_layeroperator= (socket_layer const &)=delete
 
virtual void set_event_handler (event_handler *handler, fz::socket_event_flag retrigger_block=fz::socket_event_flag{}) override
 The handler for any events generated (or forwarded) by this layer.
 
virtual native_string peer_host () const override
 
virtual int peer_port (int &error) const override
 
socket_interfacenext ()
 The next layer further down. Usually another layer or the actual socket.
 
virtual int shutdown_read () override
 Check that all layers further down also have reached EOF. More...
 
virtual int connect (native_string const &host, unsigned int port, address_type family=address_type::unknown) override
 
virtual int shutdown () override
 Signals peers that we want to close the connections. More...
 
virtual socket_state get_state () const override
 
- Public Member Functions inherited from socket_interface
 socket_interface (socket_interface const &)=delete
 
socket_interfaceoperator= (socket_interface const &)=delete
 
virtual int read (void *buffer, unsigned int size, int &error)=0
 
virtual int write (void const *buffer, unsigned int size, int &error)=0
 
template<typename T , std::enable_if_t< std::is_signed_v< T >, int > = 0>
int read (void *buffer, T size, int &error)
 
template<typename T , std::enable_if_t< std::is_unsigned_v< T > &&(sizeof(T) > sizeof(unsigned int)), int > = 0>
int read (void *buffer, T size, int &error)
 
template<typename T , std::enable_if_t< std::is_signed_v< T >, int > = 0>
int write (void const *buffer, T size, int &error)
 
template<typename T , std::enable_if_t< std::is_unsigned_v< T > &&(sizeof(T) > sizeof(unsigned int)), int > = 0>
int write (void const *buffer, T size, int &error)
 
- Public Member Functions inherited from socket_event_source
socket_event_sourceroot () const
 Gets the root source. More...
 

Protected Member Functions

void forward_socket_event (socket_event_source *source, socket_event_flag t, int error)
 
void forward_hostaddress_event (socket_event_source *source, std::string const &address)
 
void set_event_passthrough (socket_event_flag retrigger_block=socket_event_flag{})
 
- Protected Member Functions inherited from socket_interface
 socket_interface (socket_event_source *root)
 
- Protected Member Functions inherited from socket_event_source
 socket_event_source (socket_event_source *root)
 

Protected Attributes

event_handlerevent_handler_ {}
 
socket_interfacenext_layer_
 
bool event_passthrough_ {}
 
- Protected Attributes inherited from socket_event_source
socket_event_source *const root_ {}
 

Detailed Description

A base class for socket layers.

Can be used to implement layers, e.g. for TLS or rate-limiting.

Layers can in general be added on top of the next layer in any state, though individual layers may post restrictions on this.

Note instance lifetime, layers must be destroyed in reverse order.

For safe closing of a layer hierarchy, both the write and read side should be shut down first, otherwise pending data might get discarded. The shutdown and shutdown_read functions may return EAGAIN, in which case they must be called again after the next write/read event.

Member Function Documentation

◆ forward_hostaddress_event()

void forward_hostaddress_event ( socket_event_source source,
std::string const &  address 
)
protected

Call in a derived classes handler for fz::hostaddress_event. Results in a call to operator()(fz::event_base const&) on the event handler passed to socket_layer.

◆ forward_socket_event()

void forward_socket_event ( socket_event_source source,
socket_event_flag  t,
int  error 
)
protected

Call in a derived classes handler for fz::socket_event. Results in a call to operator()(fz::event_base const&) on the event handler passed to socket_layer.

◆ peer_host()

virtual native_string peer_host ( ) const
inlineoverridevirtual

Can be overridden to return something different, e.g. a proxy layer would return the hostname of the peer connected to through the proxy, whereas the next layer would return the address of the proxy itself.

Implements socket_interface.

◆ peer_port()

virtual int peer_port ( int &  error) const
inlineoverridevirtual

Can be overridden to return something different, e.g. a proxy layer would return the post of the peer connected to through the proxy, whereas the next layer would return the port of the proxy itself.

Implements socket_interface.

◆ set_event_passthrough()

void set_event_passthrough ( socket_event_flag  retrigger_block = socket_event_flag{})
protected

A pass-through layer does not handle events itself. Instead any events sent by the next layer get sent to the event handler passed to the layer.

◆ shutdown()

virtual int shutdown ( )
inlineoverridevirtual

Signals peers that we want to close the connections.

Only disallows further sends, does not affect reading from the socket.

Returns 0 on success, an error code otherwise. If it returns EGAIN, shutdown is not yet complete. Call shutdown again after the next write event.

Implements socket_interface.

Reimplemented in tls_layer, compound_rate_limited_layer, and ascii_layer.

◆ shutdown_read()

virtual int shutdown_read ( )
overridevirtual

Check that all layers further down also have reached EOF.

Can only be called after read has returned 0, calling it earlier is undefined. shutdown_read should be called after eof to ensure all layers have reached EOF.

Returns
0 on success
EAGAIN if the shutdown cannot be completed, wait for a read event and try again.
otherwise an error has occurred.

On an ordinary socket, this is a no-op. Some layers however may return an EOF before the next lower layer has reached its own EOF, such as the EOF of the secure channel from fz::tls_layer.

Closing the layer stack without all layers having reached EOF can lead to truncation on the write side: With a lower layer's EOF waiting in TCP's receive buffer and data pending in the send buffer, closing the socket is not graceful, it discards all pending data. Through shutdown_read you can assure that no pending data is left to receive, on this or any lower layer, so that closing the socket is done graceful ensuring delivery of all data in the send buffer (assuming there are no network errors).

Implements socket_interface.

Reimplemented in tls_layer.


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