mirror of
https://github.com/sochix/TLSharp.git
synced 2025-12-06 08:02:00 +01:00
Core: avoid possible infinite loop if switching to same DC
People are reporting that under some circumstances, an infinite loop could happen when TLSharp tries to handle a reconnection to a different DC, if the DC instructed to be used is the same as the one that was used in the last connection. Not sure how could this happen (although the analysis present in this github issue [1] might help understand it), but this commit helps to make TLSharp fail fast (with an exception) instead of an infinite loop from now on, which will help avoiding people file issues such as [2] and [3] and instead maybe file a proper bug report easier to understand, to try to fix the underlying root cause. [1] https://github.com/sochix/TLSharp/issues/719 [2] https://github.com/sochix/TLSharp/issues/803 [3] https://github.com/sochix/TLSharp/issues/839
This commit is contained in:
parent
d04ddb1e0e
commit
60a3c62357
21
TLSharp.Core/DataCenter.cs
Normal file
21
TLSharp.Core/DataCenter.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
namespace TLSharp.Core
|
||||||
|
{
|
||||||
|
internal class DataCenter
|
||||||
|
{
|
||||||
|
internal DataCenter (int? dcId, string address, int port)
|
||||||
|
{
|
||||||
|
DataCenterId = dcId;
|
||||||
|
Address = address;
|
||||||
|
Port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DataCenter (string address, int port) : this (null, address, port)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int? DataCenterId { get; private set; }
|
||||||
|
internal string Address { get; private set; }
|
||||||
|
internal int Port { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,8 +59,7 @@ namespace TLSharp.Core
|
||||||
private const int defaultConnectionPort = 443;
|
private const int defaultConnectionPort = 443;
|
||||||
|
|
||||||
public string SessionUserId { get; set; }
|
public string SessionUserId { get; set; }
|
||||||
public string ServerAddress { get; set; }
|
internal DataCenter DataCenter { get; set; }
|
||||||
public int Port { get; set; }
|
|
||||||
public AuthKey AuthKey { get; set; }
|
public AuthKey AuthKey { get; set; }
|
||||||
public ulong Id { get; set; }
|
public ulong Id { get; set; }
|
||||||
public int Sequence { get; set; }
|
public int Sequence { get; set; }
|
||||||
|
|
@ -89,8 +88,8 @@ namespace TLSharp.Core
|
||||||
writer.Write(Salt);
|
writer.Write(Salt);
|
||||||
writer.Write(LastMessageId);
|
writer.Write(LastMessageId);
|
||||||
writer.Write(TimeOffset);
|
writer.Write(TimeOffset);
|
||||||
Serializers.String.write(writer, ServerAddress);
|
Serializers.String.write(writer, DataCenter.Address);
|
||||||
writer.Write(Port);
|
writer.Write(DataCenter.Port);
|
||||||
|
|
||||||
if (TLUser != null)
|
if (TLUser != null)
|
||||||
{
|
{
|
||||||
|
|
@ -132,6 +131,7 @@ namespace TLSharp.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
var authData = Serializers.Bytes.read(reader);
|
var authData = Serializers.Bytes.read(reader);
|
||||||
|
var defaultDataCenter = new DataCenter (serverAddress, port);
|
||||||
|
|
||||||
return new Session(store)
|
return new Session(store)
|
||||||
{
|
{
|
||||||
|
|
@ -144,8 +144,7 @@ namespace TLSharp.Core
|
||||||
SessionExpires = sessionExpires,
|
SessionExpires = sessionExpires,
|
||||||
TLUser = TLUser,
|
TLUser = TLUser,
|
||||||
SessionUserId = sessionUserId,
|
SessionUserId = sessionUserId,
|
||||||
ServerAddress = serverAddress,
|
DataCenter = defaultDataCenter,
|
||||||
Port = port
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,12 +156,13 @@ namespace TLSharp.Core
|
||||||
|
|
||||||
public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId)
|
public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId)
|
||||||
{
|
{
|
||||||
|
var defaultDataCenter = new DataCenter (defaultConnectionAddress, defaultConnectionPort);
|
||||||
|
|
||||||
return store.Load(sessionUserId) ?? new Session(store)
|
return store.Load(sessionUserId) ?? new Session(store)
|
||||||
{
|
{
|
||||||
Id = GenerateRandomUlong(),
|
Id = GenerateRandomUlong(),
|
||||||
SessionUserId = sessionUserId,
|
SessionUserId = sessionUserId,
|
||||||
ServerAddress = defaultConnectionAddress,
|
DataCenter = defaultDataCenter,
|
||||||
Port = defaultConnectionPort
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@
|
||||||
<Compile Include="Session.cs" />
|
<Compile Include="Session.cs" />
|
||||||
<Compile Include="TelegramClient.cs" />
|
<Compile Include="TelegramClient.cs" />
|
||||||
<Compile Include="Utils\Helpers.cs" />
|
<Compile Include="Utils\Helpers.cs" />
|
||||||
|
<Compile Include="DataCenter.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ namespace TLSharp.Core
|
||||||
_handler = handler;
|
_handler = handler;
|
||||||
|
|
||||||
_session = Session.TryLoadOrCreateNew(store, sessionUserId);
|
_session = Session.TryLoadOrCreateNew(store, sessionUserId);
|
||||||
_transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler);
|
_transport = new TcpTransport(_session.DataCenter.Address, _session.DataCenter.Port, _handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ConnectAsync(bool reconnect = false)
|
public async Task ConnectAsync(bool reconnect = false)
|
||||||
|
|
@ -90,10 +90,10 @@ namespace TLSharp.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
var dc = dcOptions.First(d => d.Id == dcId);
|
var dc = dcOptions.First(d => d.Id == dcId);
|
||||||
|
var dataCenter = new DataCenter (dcId, dc.IpAddress, dc.Port);
|
||||||
|
|
||||||
_transport = new TcpTransport(dc.IpAddress, dc.Port, _handler);
|
_transport = new TcpTransport(dc.IpAddress, dc.Port, _handler);
|
||||||
_session.ServerAddress = dc.IpAddress;
|
_session.DataCenter = dataCenter;
|
||||||
_session.Port = dc.Port;
|
|
||||||
|
|
||||||
await ConnectAsync(true);
|
await ConnectAsync(true);
|
||||||
|
|
||||||
|
|
@ -121,6 +121,12 @@ namespace TLSharp.Core
|
||||||
}
|
}
|
||||||
catch(DataCenterMigrationException e)
|
catch(DataCenterMigrationException e)
|
||||||
{
|
{
|
||||||
|
if (_session.DataCenter.DataCenterId.HasValue &&
|
||||||
|
_session.DataCenter.DataCenterId.Value == e.DC)
|
||||||
|
{
|
||||||
|
throw new Exception($"Telegram server replied requesting a migration to DataCenter {e.DC} when this connection was already using this DataCenter", e);
|
||||||
|
}
|
||||||
|
|
||||||
await ReconnectToDcAsync(e.DC);
|
await ReconnectToDcAsync(e.DC);
|
||||||
// prepare the request for another try
|
// prepare the request for another try
|
||||||
request.ConfirmReceived = false;
|
request.ConfirmReceived = false;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue