diff options
author | warwickmm <warwickmm@users.noreply.github.com> | 2020-11-13 03:25:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-13 03:25:09 +0300 |
commit | 7d1d2563150bd2ff47e93a28a985bd9b8736444c (patch) | |
tree | fa48943712200eb2c10c7ba70bd20c992d01ffc3 | |
parent | c7f9f8f5566b99d3189d9d32f24a888a8cdde231 (diff) | |
parent | 0f138a1cfb612e3f4732a7d84e54ca5ba6f8e873 (diff) |
Merge pull request #4360 from martikyan/telegram-double-account-fix
Fix issue with Telegram backend and multiple accounts.
-rw-r--r-- | Duplicati/Library/Backend/Telegram/Extensions/TelegramClientExtensions.cs | 103 | ||||
-rw-r--r-- | Duplicati/Library/Backend/Telegram/TelegramBackend.cs | 27 |
2 files changed, 102 insertions, 28 deletions
diff --git a/Duplicati/Library/Backend/Telegram/Extensions/TelegramClientExtensions.cs b/Duplicati/Library/Backend/Telegram/Extensions/TelegramClientExtensions.cs index 7b1fd82ec..d99e16339 100644 --- a/Duplicati/Library/Backend/Telegram/Extensions/TelegramClientExtensions.cs +++ b/Duplicati/Library/Backend/Telegram/Extensions/TelegramClientExtensions.cs @@ -1,7 +1,9 @@ using System; -using System.IO; +using System.Net; using System.Net.Sockets; using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using TLSharp.Core; using TLSharp.Core.Network; @@ -9,7 +11,32 @@ namespace Duplicati.Library.Backend.Extensions { public static class TelegramClientExtensions { - private static BindingFlags _bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Default; + private static readonly BindingFlags _bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Default; + + public static async Task WrapperConnectAsync(this TelegramClient client, CancellationToken cancelToken = default(CancellationToken)) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + var oldTransportField = client.GetTcpTransport(); + var tcpClient = oldTransportField.GetTcpClient(); + var handler = client.GetTcpClientConnectionHandler(); + + var remoteEndpoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint; + var newTransport = new TcpTransport(remoteEndpoint.Address.ToString(), remoteEndpoint.Port, handler); + + client.GetTcpTransportFieldInfo().SetValue(client, newTransport); + + cancelToken.ThrowIfCancellationRequested(); + + await client.ConnectAsync(false, cancelToken); + + cancelToken.ThrowIfCancellationRequested(); + + oldTransportField.Dispose(); + } public static bool IsReallyConnected(this TelegramClient client) { @@ -18,31 +45,87 @@ namespace Duplicati.Library.Backend.Extensions return false; } - var senderFieldInfo = typeof(TelegramClient).GetField("sender", _bindingFlags); - var sender = (MtProtoSender)senderFieldInfo.GetValue(client); + var sender = GetMtProtoSender(client); if (sender == null) { return false; } - var transportFieldInfo = typeof(TelegramClient).GetField("transport", _bindingFlags); - var transportField = (TcpTransport)transportFieldInfo.GetValue(client); + var tcpTransport = client.GetTcpTransport(); - if (transportField == null || transportField.IsConnected == false) + if (tcpTransport == null || tcpTransport.IsConnected == false) { return false; } - var tcpClientFieldInfo = typeof(TcpTransport).GetField("tcpClient", _bindingFlags); - var tcpClient = (TcpClient)tcpClientFieldInfo.GetValue(transportField); + var tcpClient = tcpTransport.GetTcpClient(); if (tcpClient == null || tcpClient.Connected == false) { return false; } - + return true; } + + private static TcpClientConnectionHandler GetTcpClientConnectionHandler(this TelegramClient client) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + var handlerFieldInfo = typeof(TelegramClient).GetField("handler", _bindingFlags); + var handler = (TcpClientConnectionHandler)handlerFieldInfo.GetValue(client); + + return handler; + } + + private static TcpClient GetTcpClient(this TcpTransport tcpTransport) + { + if (tcpTransport == null) + { + throw new ArgumentNullException(nameof(tcpTransport)); + } + + var tcpClientFieldInfo = typeof(TcpTransport).GetField("tcpClient", _bindingFlags); + var tcpClient = (TcpClient)tcpClientFieldInfo.GetValue(tcpTransport); + + return tcpClient; + } + + private static FieldInfo GetTcpTransportFieldInfo(this TelegramClient client) + { + var transportFieldInfo = typeof(TelegramClient).GetField("transport", _bindingFlags); + + return transportFieldInfo; + } + + private static TcpTransport GetTcpTransport(this TelegramClient client) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + var transportFieldInfo = client.GetTcpTransportFieldInfo(); + var oldTransportField = (TcpTransport)transportFieldInfo.GetValue(client); + + return oldTransportField; + } + + private static MtProtoSender GetMtProtoSender(this TelegramClient client) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + var senderFieldInfo = typeof(TelegramClient).GetField("sender", _bindingFlags); + var sender = (MtProtoSender)senderFieldInfo.GetValue(client); + + return sender; + } } }
\ No newline at end of file diff --git a/Duplicati/Library/Backend/Telegram/TelegramBackend.cs b/Duplicati/Library/Backend/Telegram/TelegramBackend.cs index 373809659..ed6cb25ce 100644 --- a/Duplicati/Library/Backend/Telegram/TelegramBackend.cs +++ b/Duplicati/Library/Backend/Telegram/TelegramBackend.cs @@ -21,7 +21,7 @@ namespace Duplicati.Library.Backend { public class Telegram : IStreamingBackend { - private static TelegramClient m_telegramClient; + private readonly TelegramClient m_telegramClient; private readonly EncryptedFileSessionStore m_encSessionStore; private static readonly object m_lockObj = new object(); @@ -94,19 +94,12 @@ namespace Duplicati.Library.Backend } m_encSessionStore = new EncryptedFileSessionStore($"{m_apiHash}_{m_apiId}"); - InitializeTelegramClient(); - } - - private void InitializeTelegramClient() - { - m_telegramClient = m_telegramClient ?? new TelegramClient(m_apiId, m_apiHash, m_encSessionStore, m_phoneNumber); + m_telegramClient = new TelegramClient(m_apiId, m_apiHash, m_encSessionStore, m_phoneNumber); } public void Dispose() { - // Do not dispose m_telegramClient. - // There are bugs connected with reusing - // the old sockets + m_telegramClient?.Dispose(); } public string DisplayName { get; } = Strings.DisplayName; @@ -146,7 +139,7 @@ namespace Duplicati.Library.Backend cancelToken.ThrowIfCancellationRequested(); var file = m_telegramClient.UploadFile(remotename, sr, cancelToken).GetAwaiter().GetResult(); - + cancelToken.ThrowIfCancellationRequested(); var inputPeerChannel = new TLInputPeerChannel {ChannelId = channel.Id, AccessHash = (long)channel.AccessHash}; var fileNameAttribute = new TLDocumentAttributeFilename @@ -173,7 +166,6 @@ namespace Duplicati.Library.Backend var limit = BYTES_IN_MEBIBYTE; var currentOffset = 0; - while (currentOffset < fileInfo.Size) { try @@ -433,20 +425,19 @@ namespace Duplicati.Library.Backend m_telegramClient.Session.Save(); } - private void EnsureConnected(CancellationToken cancelToken = default(CancellationToken)) { if (m_telegramClient.IsReallyConnected()) { return; } - + cancelToken.ThrowIfCancellationRequested(); - - m_telegramClient.ConnectAsync(false, cancelToken).GetAwaiter().GetResult(); - + + m_telegramClient.WrapperConnectAsync(cancelToken).GetAwaiter().GetResult(); + cancelToken.ThrowIfCancellationRequested(); - + if (m_telegramClient.IsReallyConnected() == false) { throw new WebException("Unable to connect to telegram"); |