Home · Modules · All Classes · All Namespaces
Classes | Signals | Public Member Functions | Static Public Member Functions | List of all members
Tp::StreamTubeServer Class Reference

The StreamTubeServer class is a Handler implementation for outgoing Stream Tube channels, allowing an application to easily export a TCP network server over Telepathy Tubes without worrying about the channel dispatching details. More...

#include <TelepathyQt/StreamTubeServer>

Inherits QObject, and Tp::RefCounted.

Classes

class  ParametersGenerator
 The StreamTubeServer::ParametersGenerator abstract interface allows sending a different set of parameters with each tube offer. More...
 
class  RemoteContact
 The StreamTubeServer::RemoteContact class represents a contact from which a socket connection to our exported socket originates. More...
 
class  Tube
 The StreamTubeServer::Tube class represents a tube being handled by the server. More...
 

Signals

void tubeRequested (const Tp::AccountPtr &account, const Tp::OutgoingStreamTubeChannelPtr &tube, const QDateTime &userActionTime, const Tp::ChannelRequestHints &hints)
 
void tubeClosed (const Tp::AccountPtr &account, const Tp::OutgoingStreamTubeChannelPtr &tube, const QString &error, const QString &message)
 
void newTcpConnection (const QHostAddress &sourceAddress, quint16 sourcePort, const Tp::AccountPtr &account, const Tp::ContactPtr &contact, const Tp::OutgoingStreamTubeChannelPtr &tube)
 
void tcpConnectionClosed (const QHostAddress &sourceAddress, quint16 sourcePort, const Tp::AccountPtr &account, const Tp::ContactPtr &contact, const QString &error, const QString &message, const Tp::OutgoingStreamTubeChannelPtr &tube)
 

Public Member Functions

virtual ~StreamTubeServer ()
 
ClientRegistrarPtr registrar () const
 
QString clientName () const
 
bool isRegistered () const
 
bool monitorsConnections () const
 
QPair< QHostAddress, quint16 > exportedTcpSocketAddress () const
 
QVariantMap exportedParameters () const
 
void exportTcpSocket (const QHostAddress &address, quint16 port, const QVariantMap &parameters=QVariantMap())
 
void exportTcpSocket (const QTcpServer *server, const QVariantMap &parameters=QVariantMap())
 
void exportTcpSocket (const QHostAddress &address, quint16 port, ParametersGenerator *generator)
 
void exportTcpSocket (const QTcpServer *server, ParametersGenerator *generator)
 
QList< Tubetubes () const
 
QHash< QPair< QHostAddress, quint16 >, RemoteContacttcpConnections () const
 
- Public Member Functions inherited from Tp::RefCounted
 RefCounted ()
 
virtual ~RefCounted ()
 

Static Public Member Functions

static StreamTubeServerPtr create (const QStringList &p2pServices, const QStringList &roomServices=QStringList(), const QString &clientName=QString(), bool monitorConnections=false, const AccountFactoryConstPtr &accountFactory=AccountFactory::create(QDBusConnection::sessionBus()), const ConnectionFactoryConstPtr &connectionFactory=ConnectionFactory::create(QDBusConnection::sessionBus()), const ChannelFactoryConstPtr &channelFactory=ChannelFactory::create(QDBusConnection::sessionBus()), const ContactFactoryConstPtr &contactFactory=ContactFactory::create())
 
static StreamTubeServerPtr create (const QDBusConnection &bus, const AccountFactoryConstPtr &accountFactory, const ConnectionFactoryConstPtr &connectionFactory, const ChannelFactoryConstPtr &channelFactory, const ContactFactoryConstPtr &contactFactory, const QStringList &p2pServices, const QStringList &roomServices=QStringList(), const QString &clientName=QString(), bool monitorConnections=false)
 
static StreamTubeServerPtr create (const AccountManagerPtr &accountManager, const QStringList &p2pServices, const QStringList &roomServices=QStringList(), const QString &clientName=QString(), bool monitorConnections=false)
 
static StreamTubeServerPtr create (const ClientRegistrarPtr &registrar, const QStringList &p2pServices, const QStringList &roomServices=QStringList(), const QString &clientName=QString(), bool monitorConnections=false)
 

Detailed Description

The StreamTubeServer class is a Handler implementation for outgoing Stream Tube channels, allowing an application to easily export a TCP network server over Telepathy Tubes without worrying about the channel dispatching details.

Telepathy Tubes is a technology for connecting arbitrary applications together through the IM network (and sometimes with direct peer-to-peer connections), such that issues like firewall/NAT traversal are automatically handled. Stream Tubes in particular offer properties similar to SOCK_STREAM sockets. The StreamTubeServer class exports such a bytestream socket server over the tubes it handles as a Telepathy Handler Client; the StreamTubeClient class is the counterpart, enabling TCP/UNIX socket clients to connect to services from such exported servers offered to them via tubes.

Both peer-to-peer (TargetHandleType == HandleTypeContact) and group (TargetHandleType == HandleTypeRoom) channels are supported, and it's possible to specify the tube services to handle for each separately. It is also possible to not advertise handling capability for ANY tube service; instead just using the StreamTubeServer to handle tubes on an one-off basis by passing its corresponding Client service name as the preferredHandler when requesting tubes via the Account::createStreamTube() methods (or equivalent).

Connection monitoring allows associating incoming connections on the exported server socket with the corresponding remote contacts. This allows an application to show the details of and/or initiate further communication with the remote contacts, without considering the actual tube channels the connections are being made through at all (in particular, their Channel::targetContact() accessor for peer-to-peer and the OutgoingStreamTubeChannel::connectionsForSourceAddresses() accessor for group tubes).

Enabling connection monitoring adds a small overhead and latency to handling each incoming tube and signaling each new incoming connection over them, though, so use it only when needed. Additionally, some protocol backends or environments they're running in might not support the SocketAccessControlPort mechanism, in which case the source address won't be reported for connections through them. Even in this case, the remote contacts can be associated by accepting one incoming socket connection at a time, and waiting for the corresponding contact to be signaled (although its source address will be invalid, it's the only possibility given its the only accepted connection). However, it's not necessary to do this e.g. with the Gabble XMPP backend, because it fully supports the required mechanism.

A service activated Handler can be implemented using StreamTubeServer by passing a predefined clientName manually to the chosen create() method, and installing Telepathy .client and D-Bus .service files declaring the implemented tube services as channel classes and a path to the executable. If this is not needed, the clientName can be omitted, in which case a random unique client name is generated and used instead.

StreamTubeServer shares Account, Connection and Channel proxies and Contact objects with the rest of the application as long as a reference to the AccountManager, ClientRegistrar, or the factories used elsewhere is passed to the create() method. A stand-alone tube service Handler can get away without passing these however, or just passing select factories to make the desired features prepared and subclasses employed for these objects for their own convenience.

Whichever method is used, the ChannelFactory (perhaps indirectly) given must construct OutgoingStreamTubeChannel instances or subclasses thereof for all channel classes corresponding to the tube services to handle. This is the default; overriding it without obeying these constraints using ChannelFactory::setSubclassForOutgoingStreamTubes() or the related methods for room tubes prevents StreamTubeServer from operating correctly.

Todo:

Coin up a small Python script or alike to easily generate the .client and .service files. (fd.o #41614)

Support exporting Unix sockets as well. (fd.o #41615)

Constructor & Destructor Documentation

◆ ~StreamTubeServer()

Tp::StreamTubeServer::~StreamTubeServer ( )
virtual

Class destructor.

Member Function Documentation

◆ create() [1/4]

StreamTubeServerPtr Tp::StreamTubeServer::create ( const QStringList &  p2pServices,
const QStringList &  roomServices = QStringList(),
const QString &  clientName = QString(),
bool  monitorConnections = false,
const AccountFactoryConstPtr &  accountFactory = AccountFactory::create(QDBusConnection::sessionBus()),
const ConnectionFactoryConstPtr &  connectionFactory = ConnectionFactory::create(QDBusConnection::sessionBus()),
const ChannelFactoryConstPtr &  channelFactory = ChannelFactory::create(QDBusConnection::sessionBus()),
const ContactFactoryConstPtr &  contactFactory = ContactFactory::create() 
)
static

Create a new StreamTubeServer, which will register itself on the session bus using an internal ClientRegistrar and use the given factories.

Parameters
p2pServicesNames of the tube services to handle on peer-to-peer tube channels.
roomServicesNames of the tube services to handle on room/group tube channels.
clientNameThe client name (without the org.freedesktop.Telepathy.Client. prefix).
monitorConnectionsWhether to enable connection monitoring or not.
accountFactoryThe account factory to use.
connectionFactoryThe connection factory to use.
channelFactoryThe channel factory to use.
contactFactoryThe contact factory to use.

◆ create() [2/4]

StreamTubeServerPtr Tp::StreamTubeServer::create ( const QDBusConnection &  bus,
const AccountFactoryConstPtr &  accountFactory,
const ConnectionFactoryConstPtr &  connectionFactory,
const ChannelFactoryConstPtr &  channelFactory,
const ContactFactoryConstPtr &  contactFactory,
const QStringList &  p2pServices,
const QStringList &  roomServices = QStringList(),
const QString &  clientName = QString(),
bool  monitorConnections = false 
)
static

Create a new StreamTubeServer, which will register itself on the given bus using an internal ClientRegistrar and use the given factories.

The factories must all be created for the given bus.

Parameters
busConnection to the bus to register on.
accountFactoryThe account factory to use.
connectionFactoryThe connection factory to use.
channelFactoryThe channel factory to use.
contactFactoryThe contact factory to use.
p2pServicesNames of the tube services to handle on peer-to-peer tube channels.
roomServicesNames of the tube services to handle on room/group tube channels.
clientNameThe client name (without the org.freedesktop.Telepathy.Client. prefix).
monitorConnectionsWhether to enable connection monitoring or not.

◆ create() [3/4]

StreamTubeServerPtr Tp::StreamTubeServer::create ( const AccountManagerPtr &  accountManager,
const QStringList &  p2pServices,
const QStringList &  roomServices = QStringList(),
const QString &  clientName = QString(),
bool  monitorConnections = false 
)
static

Create a new StreamTubeServer, which will register itself on the bus of and share objects with the given accountManager, creating an internal ClientRegistrar.

Parameters
accountManagerA pointer to the account manager to link up with.
p2pServicesNames of the tube services to handle on peer-to-peer tube channels.
roomServicesNames of the tube services to handle on room/group tube channels.
clientNameThe client name (without the org.freedesktop.Telepathy.Client. prefix).
monitorConnectionsWhether to enable connection monitoring or not.

◆ create() [4/4]

StreamTubeServerPtr Tp::StreamTubeServer::create ( const ClientRegistrarPtr &  registrar,
const QStringList &  p2pServices,
const QStringList &  roomServices = QStringList(),
const QString &  clientName = QString(),
bool  monitorConnections = false 
)
static

Create a new StreamTubeServer, which will register itself on the bus of and using the given client registrar, and share objects with it.

Parameters
registrarThe client registrar to use.
p2pServicesNames of the tube services to handle on peer-to-peer tube channels.
roomServicesNames of the tube services to handle on room/group tube channels.
clientNameThe client name (without the org.freedesktop.Telepathy.Client. prefix).
monitorConnectionsWhether to enable connection monitoring or not.

◆ registrar()

ClientRegistrarPtr Tp::StreamTubeServer::registrar ( ) const

Return the client registrar used by the server to register itself as a Handler client.

This is the registrar originally passed to create(const ClientRegistrarPtr &, const QStringList &, const QStringList &, const QString &, bool) if that was used, and an internally constructed one otherwise. In any case, it can be used to e.g. register further clients like any other ClientRegistrar.

Returns
A pointer to the registrar.

◆ clientName()

QString Tp::StreamTubeServer::clientName ( ) const

Return the Telepathy Client name of the server.

Returns
The name, without the org.freedesktop.Telepathy.Client. prefix of the full D-Bus service name.

◆ isRegistered()

bool Tp::StreamTubeServer::isRegistered ( ) const

Return whether the server has been successfully registered or not.

Registration is attempted, at the latest, when a socket is first exported using exportTcpSocket(). It can fail e.g. because the connection to the bus has failed, or a predefined clientName has been passed to create(), and a Client with the same name is already registered. Typically, failure registering would be a fatal error for a stand-alone tube handler, but only a warning event for an application serving other purposes. In any case, a high-quality user of the API will check the return value of this accessor after exporting their socket.

Returns
true if the server has been successfully registered, false if not.

◆ monitorsConnections()

bool Tp::StreamTubeServer::monitorsConnections ( ) const

Return whether connection monitoring is enabled on this server.

For technical reasons, connection monitoring can't be enabled when the server is already running, so there is no corresponding setter method. It has to be enabled by passing true as the monitorConnections parameter to the create() method.

If connection monitoring isn't enabled, newTcpConnection() and tcpConnectionClosed() won't be emitted and tcpConnections() won't be populated.

Returns
true if monitoring is enabled, false if not.

◆ exportedTcpSocketAddress()

QPair< QHostAddress, quint16 > Tp::StreamTubeServer::exportedTcpSocketAddress ( ) const

Return the host address and port of the currently exported TCP socket, if any.

QHostAddress::Null is reported as the address and 0 as the port if no TCP socket has yet been successfully exported.

Returns
The host address and port values in a pair structure.

◆ exportedParameters()

QVariantMap Tp::StreamTubeServer::exportedParameters ( ) const

Return the fixed parameters, if any, which are sent along when offering the exported socket on all handled tubes.

To prevent accidentally leaving the current parameters to be sent when offering a different socket, or vice versa, the parameters can only be set together with the socket using exportTcpSocket(). Parameters often contain sensitive information such as session identifiers or authentication credentials, which could then be used to maliciously access the service listening on the other socket.

If a custom dynamic ParametersGenerator was passed to exportTcpSocket() instead of a set of fixed parameters, an empty set of parameters is returned.

Returns
The parameters in a string-variant map.

◆ exportTcpSocket() [1/4]

void Tp::StreamTubeServer::exportTcpSocket ( const QHostAddress &  address,
quint16  port,
const QVariantMap &  parameters = QVariantMap() 
)

Set the server to offer the socket listening at the given (address, port) combination as the local endpoint of tubes handled in the future.

A fixed set of protocol bootstrapping parameters can optionally be set to be sent along with all tube offers until the next call to exportTcpSocket(). See the ParametersGenerator documentation for an in-depth description of the parameter transfer mechanism, and a more flexible way to vary the parameters between each handled tube.

The handler is registered on the bus at the latest when this method or another exportTcpSocket() overload is called for the first time, so one should check the return value of isRegistered() at that point to verify that was successful.

Parameters
addressThe listen address of the socket.
portThe port of the socket.
parametersThe bootstrapping parameters in a string-value map.

◆ exportTcpSocket() [2/4]

void Tp::StreamTubeServer::exportTcpSocket ( const QTcpServer *  server,
const QVariantMap &  parameters = QVariantMap() 
)

Set the StreamTubeServer to offer the already listening TCP server as the local endpoint of tubes handled in the future.

This is just a convenience wrapper around exportTcpSocket(const QHostAddress &, quint16, const QVariantMap &) to be used when the TCP server code is implemented using the QtNetwork facilities.

A fixed set of protocol bootstrapping parameters can optionally be set to be sent along with all tube offers until the next call to exportTcpSocket(). See the ParametersGenerator documentation for an in-depth description of the parameter transfer mechanism, and a more flexible way to vary the parameters between each handled tube.

Parameters
serverA pointer to the TCP server.
parametersThe bootstrapping parameters in a string-value map.

◆ exportTcpSocket() [3/4]

void Tp::StreamTubeServer::exportTcpSocket ( const QHostAddress &  address,
quint16  port,
ParametersGenerator generator 
)

Set the server to offer the socket listening at the given address - port combination as the local endpoint of tubes handled in the future, sending the parameters from the given generator along with the offers.

The handler is registered on the bus at the latest when this method or another exportTcpSocket() overload is called for the first time, so one should check the return value of isRegistered() at that point to verify that was successful.

Parameters
addressThe listen address of the socket.
portThe port of the socket.
generatorA pointer to the bootstrapping parameters generator.

◆ exportTcpSocket() [4/4]

void Tp::StreamTubeServer::exportTcpSocket ( const QTcpServer *  server,
ParametersGenerator generator 
)

Set the server to offer the already listening TCP server as the local endpoint of tubes handled in the future, sending the parameters from the given generator along with the offers.

This is just a convenience wrapper around exportTcpSocket(const QHostAddress &, quint16, ParametersGenerator *) to be used when the TCP server code is implemented using the QtNetwork facilities.

Parameters
serverA pointer to the TCP server.
generatorA pointer to the bootstrapping parameters generator.

◆ tubes()

QList< StreamTubeServer::Tube > Tp::StreamTubeServer::tubes ( ) const

Return the tubes currently handled by the server.

Returns
A list of Tube structures containing pointers to the account and tube channel for each tube.

◆ tcpConnections()

QHash< QPair< QHostAddress, quint16 >, StreamTubeServer::RemoteContact > Tp::StreamTubeServer::tcpConnections ( ) const

Return the ongoing TCP connections over tubes handled by this server.

The returned mapping has the connection source addresses as keys and the contacts along with the accounts which can be used to reach them as values. Connections through protocol backends which don't support SocketAccessControlPort will be included as the potentially many values for the null source address key, the pair (QHostAddress::Null, 0).

This is effectively a state recovery accessor corresponding to the change notification signals newTcpConnection() and tcpConnectionClosed().

The mapping is only populated if connection monitoring was requested when creating the server (so monitorsConnections() returns true).

Returns
The connections in a mapping with pairs of their source host addresses and ports as keys and structures containing pointers to the account and remote contacts they're from as values.

◆ tubeRequested

void Tp::StreamTubeServer::tubeRequested ( const Tp::AccountPtr &  account,
const Tp::OutgoingStreamTubeChannelPtr &  tube,
const QDateTime &  userActionTime,
const Tp::ChannelRequestHints hints 
)
signal

Emitted when a tube has been requested for one of our services, and we've began handling it.

This is emitted before invoking the ParametersGenerator, if any, for the tube.

Parameters
accountA pointer to the account from which the tube was requested from.
tubeA pointer to the actual tube channel.
userActionTimeThe time the request occurred at, if it was an user action. Should be used for focus stealing prevention.
hintsThe hints passed to the request, if any.

◆ tubeClosed

void Tp::StreamTubeServer::tubeClosed ( const Tp::AccountPtr &  account,
const Tp::OutgoingStreamTubeChannelPtr &  tube,
const QString &  error,
const QString &  message 
)
signal

Emitted when a tube we've been handling (previously announced with tubeRequested()) has encountered an error or has otherwise been closed from further communication.

Parameters
accountA pointer to the account from which the tube was requested from.
tubeA pointer to the actual tube channel.
errorThe D-Bus error name corresponding to the reason for the closure.
messageA freeform debug message associated with the error.

◆ newTcpConnection

void Tp::StreamTubeServer::newTcpConnection ( const QHostAddress &  sourceAddress,
quint16  sourcePort,
const Tp::AccountPtr &  account,
const Tp::ContactPtr &  contact,
const Tp::OutgoingStreamTubeChannelPtr &  tube 
)
signal

Emitted when we have picked up a new TCP connection to the (current or previous) exported server socket. This can be used to associate connections the protocol backend relays to the exported socket with the remote contact who originally initiated them in the other end of the tube.

This is only emitted if connection monitoring was enabled when creating the StreamTubeServer. Additionally, if the protocol backend the connection is from doesn't support the SocketAccessControlPort mechanism, the source address and port will always be invalid.

Parameters
sourceAddressThe source address of the connection, or QHostAddress::Null if it can't be resolved.
sourcePortThe source port of the connection, or 0 if it can't be resolved.
accountA pointer to the account through which the remote contact can be reached.
contactA pointer to the remote contact object.
tubeA pointer to the tube channel through which the connection has been made.

◆ tcpConnectionClosed

void Tp::StreamTubeServer::tcpConnectionClosed ( const QHostAddress &  sourceAddress,
quint16  sourcePort,
const Tp::AccountPtr &  account,
const Tp::ContactPtr &  contact,
const QString &  error,
const QString &  message,
const Tp::OutgoingStreamTubeChannelPtr &  tube 
)
signal

Emitted when a TCP connection (previously announced with newTcpConnection()) through one of our handled tubes has been closed due to an error or by a graceful disconnect (in which case the error is TP_QT_ERROR_DISCONNECTED).

This is only emitted if connection monitoring was enabled when creating the StreamTubeServer. Additionally, if the protocol backend the connection is from doesn't support the SocketAccessControlPort mechanism, the source address and port will always be invalid.

Parameters
sourceAddressThe source address of the connection, or QHostAddress::Null if it couldn't be resolved.
sourcePortThe source port of the connection, or 0 if it couldn't be resolved.
accountA pointer to the account through which the remote contact can be reached.
contactA pointer to the remote contact object.
errorThe D-Bus error name corresponding to the reason for the closure.
messageA freeform debug message associated with the error.
tubeA pointer to the tube channel through which the connection has been made.