mumble/src/Connection.h
Robert Adam 1d45d991aa CHANGE: Use Protobuf for UDP messages
Previously Mumble was using a custom binary format for transmitting data
via UDP (mainly audio). This has worked for a long time but besides
being inconvenient for 3rdParty implementors (they had to manually
re-implement encoding and decoding support for this format) this format
was not very flexible and changes to the data format were very hard.

In order to improve on this situation, this commit introduces changes
that allow to use Protobuf for the UDP messages as well (it's already
used for TCP). With that it should be relatively easy to extend/change
the UDP packet formats in the future and 3rdParty implementors can now
simply use Protobuf to handle decoding/encoding packets for them (much
less work and much less prone to errors).

Since the new Protobuf format is incompatible with the old UDP format,
this commit also includes support for dealing with older clients or
servers that don't recognize the new protocol yet. That way the new
protocol format is only used if both the client and the server are
recent enough to have it implemented (assumed to be the case >=1.5.0).

Note also that the server will make sure that clients using the old and
the new format can seamlessly communicate with one another.

Therefore, on the surface it should not be noticeable to the user which
protocol is currently used.

Note also that the new protocol format only supports Opus as an audio
codec. If one of the legacy codecs is to be used, the legacy packet
format has to be used as well. However, all codecs except for Opus will
be removed from Mumble in the future anyway.

Fixes #4350
2022-03-27 09:49:58 +02:00

102 lines
2.7 KiB
C++

// Copyright 2007-2022 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_CONNECTION_H_
#define MUMBLE_CONNECTION_H_
#include "MumbleProtocol.h"
#include <QtCore/QtGlobal>
#ifdef Q_OS_WIN
# include "win.h"
#endif
#include "crypto/CryptState.h"
#include "crypto/CryptStateOCB2.h"
#include <QtCore/QElapsedTimer>
#include <QtCore/QList>
#include <QtCore/QMutex>
#include <QtCore/QObject>
#include <QtNetwork/QSslSocket>
#include <memory>
#ifdef Q_OS_WIN
# include <ws2tcpip.h>
#endif
namespace google {
namespace protobuf {
class Message;
}
} // namespace google
class Connection : public QObject {
private:
Q_OBJECT
Q_DISABLE_COPY(Connection)
protected:
QSslSocket *qtsSocket;
QElapsedTimer qtLastPacket;
Mumble::Protocol::TCPMessageType m_type;
int iPacketLength;
#ifdef Q_OS_WIN
static HANDLE hQoS;
DWORD dwFlow;
#endif
protected slots:
void socketRead();
void socketError(QAbstractSocket::SocketError);
void socketDisconnected();
void socketSslErrors(const QList< QSslError > &errors);
public slots:
void proceedAnyway();
signals:
void encrypted();
void connectionClosed(QAbstractSocket::SocketError, const QString &reason);
void message(Mumble::Protocol::TCPMessageType type, const QByteArray &);
void handleSslErrors(const QList< QSslError > &);
public:
Connection(QObject *parent, QSslSocket *qtsSocket);
~Connection();
static void messageToNetwork(const ::google::protobuf::Message &msg, Mumble::Protocol::TCPMessageType msgType,
QByteArray &cache);
void sendMessage(const ::google::protobuf::Message &msg, Mumble::Protocol::TCPMessageType msgType,
QByteArray &cache);
void sendMessage(const QByteArray &qbaMsg);
void disconnectSocket(bool force = false);
void forceFlush();
qint64 activityTime() const;
void resetActivityTime();
#ifdef MURMUR
/// qmCrypt locks access to csCrypt.
QMutex qmCrypt;
#endif
std::unique_ptr< CryptState > csCrypt;
/// Returns the peer's chain of digital certificates, starting with the peer's immediate certificate
/// and ending with the CA's certificate.
QList< QSslCertificate > peerCertificateChain() const;
QSslCipher sessionCipher() const;
QSsl::SslProtocol sessionProtocol() const;
QString sessionProtocolString() const;
QHostAddress peerAddress() const;
quint16 peerPort() const;
/// Look up the local address of this Connection.
QHostAddress localAddress() const;
/// Look up the local port of this Connection.
quint16 localPort() const;
bool bDisconnectedEmitted;
void setToS();
#ifdef Q_OS_WIN
static void setQoS(HANDLE hParentQoS);
#endif
};
#endif