File indexing completed on 2024-05-12 04:58:51
0001 /** 0002 * SPDX-FileCopyrightText: 2013 Albert Vaca <albertvaka@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "landevicelink.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include "backends/linkprovider.h" 0012 #include "core_debug.h" 0013 #include "kdeconnectconfig.h" 0014 #include "lanlinkprovider.h" 0015 #include "plugins/share/shareplugin.h" 0016 0017 LanDeviceLink::LanDeviceLink(const DeviceInfo &deviceInfo, LanLinkProvider *parent, QSslSocket *socket) 0018 : DeviceLink(deviceInfo.id, parent) 0019 , m_socket(nullptr) 0020 , m_deviceInfo(deviceInfo) 0021 { 0022 reset(socket); 0023 } 0024 0025 void LanDeviceLink::reset(QSslSocket *socket) 0026 { 0027 if (m_socket) { 0028 disconnect(m_socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); 0029 delete m_socket; 0030 } 0031 0032 m_socket = socket; 0033 socket->setParent(this); 0034 0035 connect(socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); 0036 connect(socket, &QAbstractSocket::readyRead, this, &LanDeviceLink::dataReceived); 0037 } 0038 0039 QHostAddress LanDeviceLink::hostAddress() const 0040 { 0041 if (!m_socket) { 0042 return QHostAddress::Null; 0043 } 0044 QHostAddress addr = m_socket->peerAddress(); 0045 if (addr.protocol() == QAbstractSocket::IPv6Protocol) { 0046 bool success; 0047 QHostAddress convertedAddr = QHostAddress(addr.toIPv4Address(&success)); 0048 if (success) { 0049 qCDebug(KDECONNECT_CORE) << "Converting IPv6" << addr << "to IPv4" << convertedAddr; 0050 addr = convertedAddr; 0051 } 0052 } 0053 return addr; 0054 } 0055 0056 bool LanDeviceLink::sendPacket(NetworkPacket &np) 0057 { 0058 if (np.payload()) { 0059 if (np.type() == PACKET_TYPE_SHARE_REQUEST && np.payloadSize() >= 0) { 0060 if (!m_compositeUploadJob || !m_compositeUploadJob->isRunning()) { 0061 m_compositeUploadJob = new CompositeUploadJob(deviceId(), true); 0062 } 0063 0064 m_compositeUploadJob->addSubjob(new UploadJob(np)); 0065 0066 if (!m_compositeUploadJob->isRunning()) { 0067 m_compositeUploadJob->start(); 0068 } 0069 } else { // Infinite stream 0070 CompositeUploadJob *fireAndForgetJob = new CompositeUploadJob(deviceId(), false); 0071 fireAndForgetJob->addSubjob(new UploadJob(np)); 0072 fireAndForgetJob->start(); 0073 } 0074 0075 return true; 0076 } else { 0077 int written = m_socket->write(np.serialize()); 0078 0079 // Actually we can't detect if a packet is received or not. We keep TCP 0080 //"ESTABLISHED" connections that look legit (return true when we use them), 0081 // but that are actually broken (until keepalive detects that they are down). 0082 return (written != -1); 0083 } 0084 } 0085 0086 void LanDeviceLink::dataReceived() 0087 { 0088 while (m_socket->canReadLine()) { 0089 const QByteArray serializedPacket = m_socket->readLine(); 0090 NetworkPacket packet; 0091 NetworkPacket::unserialize(serializedPacket, &packet); 0092 0093 // qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << serializedPacket; 0094 0095 if (packet.hasPayloadTransferInfo()) { 0096 // qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo"; 0097 const QVariantMap transferInfo = packet.payloadTransferInfo(); 0098 0099 QSharedPointer<QSslSocket> socket(new QSslSocket); 0100 0101 LanLinkProvider::configureSslSocket(socket.data(), deviceId(), true); 0102 0103 // emit readChannelFinished when the socket gets disconnected. This seems to be a bug in upstream QSslSocket. 0104 // Needs investigation and upstreaming of the fix. QTBUG-62257 0105 connect(socket.data(), &QAbstractSocket::disconnected, socket.data(), &QAbstractSocket::readChannelFinished); 0106 0107 const QString address = m_socket->peerAddress().toString(); 0108 const quint16 port = transferInfo[QStringLiteral("port")].toInt(); 0109 socket->connectToHostEncrypted(address, port, QIODevice::ReadWrite); 0110 packet.setPayload(socket, packet.payloadSize()); 0111 } 0112 0113 Q_EMIT receivedPacket(packet); 0114 } 0115 } 0116 0117 #include "moc_landevicelink.cpp"