Skip to content

Commit c036eeb

Browse files
committed
Core,TL,Gen: Transport layer rewrite and bugfixes
This commit consists of the following changes: - Fixes the typo in generator that caused all ComputeFlags() functions to be empty. - Adds the missing call to ComputeFlags() inside the serialize function - Uses obfuscated websocket transport instead of TCP - Adds asynchronous response handling
1 parent 53302ac commit c036eeb

1,151 files changed

Lines changed: 3888 additions & 1832 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,61 @@
1+
using System;
12
using System.Threading;
23
using System.Threading.Tasks;
34
using TgSharp.Core.Network;
45

56
namespace TgSharp.Core.Auth
67
{
7-
public static class Authenticator
8+
public class Authenticator
89
{
9-
public static async Task<Step3_Response> DoAuthentication(TcpTransport transport, CancellationToken token = default(CancellationToken))
10+
private readonly MtProtoPlainSender sender;
11+
private TaskCompletionSource<Step3_Response> completionSource;
12+
public Authenticator(WssTransport transport)
1013
{
11-
token.ThrowIfCancellationRequested();
14+
sender = new MtProtoPlainSender(transport);
15+
completionSource = new TaskCompletionSource<Step3_Response>();
16+
}
1217

13-
var sender = new MtProtoPlainSender(transport);
18+
public Task<Step3_Response> DoAuthentication()
19+
{
1420
var step1 = new Step1_PQRequest();
1521

16-
await sender.Send(step1.ToBytes(), token).ConfigureAwait(false);
17-
var step1Response = step1.FromBytes(await sender.Receive(token)
18-
.ConfigureAwait(false));
22+
//race condition ? move randomization in consturctor
23+
sender.OnResponseReceived = (step1Message) => Sender_OnStep1ResponseReceived(step1, step1Message);
24+
sender.Send(step1.ToBytes());
25+
26+
return completionSource.Task;
27+
}
28+
29+
private void Sender_OnStep1ResponseReceived(Step1_PQRequest step1, byte[] step1Message)
30+
{
31+
var step1Response = step1.FromBytes(step1Message);
1932

2033
var step2 = new Step2_DHExchange();
21-
await sender.Send(step2.ToBytes(
34+
sender.OnResponseReceived = (step2message) => Sender_OnStep2ResponseReceived(step2, step2message);
35+
sender.Send(step2.ToBytes(
2236
step1Response.Nonce,
2337
step1Response.ServerNonce,
2438
step1Response.Fingerprints,
25-
step1Response.Pq), token)
26-
.ConfigureAwait(false);
39+
step1Response.Pq));
40+
}
41+
42+
private void Sender_OnStep2ResponseReceived(Step2_DHExchange step2, byte[] step2message)
43+
{
44+
var step2Response = step2.FromBytes(step2message);
2745

28-
var step2Response = step2.FromBytes(await sender.Receive(token)
29-
.ConfigureAwait(false));
3046

3147
var step3 = new Step3_CompleteDHExchange();
32-
await sender.Send(step3.ToBytes(
48+
sender.OnResponseReceived = (step3Message) => Sender_OnStep3ResponseReceived(step3, step3Message);
49+
sender.Send(step3.ToBytes(
3350
step2Response.Nonce,
3451
step2Response.ServerNonce,
3552
step2Response.NewNonce,
36-
step2Response.EncryptedAnswer), token)
37-
.ConfigureAwait(false);
38-
39-
var step3Response = step3.FromBytes(await sender.Receive(token)
40-
.ConfigureAwait(false));
53+
step2Response.EncryptedAnswer));
54+
}
4155

42-
return step3Response;
56+
private void Sender_OnStep3ResponseReceived(Step3_CompleteDHExchange step3, byte[] response)
57+
{
58+
completionSource.SetResult(step3.FromBytes(response));
4359
}
4460
}
4561
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using System.Threading.Tasks;
5+
6+
namespace TgSharp.Core.Network
7+
{
8+
public abstract class ITransport : IDisposable
9+
{
10+
public delegate void MessageHandler(TgMessage message);
11+
public MessageHandler OnEncryptedMessage, OnUnencryptedMessage;
12+
13+
public abstract Task ConnectAsync();
14+
public abstract void Send(byte[] packet);
15+
public abstract bool IsConnected();
16+
public abstract void Dispose();
17+
}
18+
}

src/TgSharp.Core/Network/MtProtoPlainSender.cs

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,38 @@ namespace TgSharp.Core.Network
77
{
88
public class MtProtoPlainSender
99
{
10+
public delegate void ResponseHandler(byte[] response);
11+
public ResponseHandler OnResponseReceived;
12+
1013
private int timeOffset;
1114
private long lastMessageId;
1215
private Random random;
13-
private TcpTransport transport;
16+
private WssTransport transport;
1417

15-
public MtProtoPlainSender(TcpTransport transport)
18+
public MtProtoPlainSender(WssTransport transport)
1619
{
1720
this.transport = transport;
21+
transport.OnUnencryptedMessage += Transport_OnUnencryptedMessage;
1822
random = new Random();
1923
}
2024

21-
public async Task Send(byte[] data, CancellationToken token = default(CancellationToken))
25+
private void Transport_OnUnencryptedMessage(TgMessage message)
2226
{
23-
token.ThrowIfCancellationRequested();
27+
using (MemoryStream memoryStream = new MemoryStream(message.Body))
28+
using (BinaryReader binaryReader = new BinaryReader(memoryStream))
29+
{
30+
long authKeyid = binaryReader.ReadInt64();
31+
long messageId = binaryReader.ReadInt64();
32+
int messageLength = binaryReader.ReadInt32();
33+
34+
byte[] response = binaryReader.ReadBytes(messageLength);
2435

36+
OnResponseReceived?.Invoke(response);
37+
}
38+
}
39+
40+
public void Send(byte[] data)
41+
{
2542
using (var memoryStream = new MemoryStream())
2643
{
2744
using (var binaryWriter = new BinaryWriter(memoryStream))
@@ -33,28 +50,7 @@ public MtProtoPlainSender(TcpTransport transport)
3350

3451
byte[] packet = memoryStream.ToArray();
3552

36-
await transport.Send(packet, token).ConfigureAwait(false);
37-
}
38-
}
39-
}
40-
41-
public async Task<byte[]> Receive(CancellationToken token = default(CancellationToken))
42-
{
43-
token.ThrowIfCancellationRequested();
44-
45-
var result = await transport.Receive(token).ConfigureAwait(false);
46-
47-
using (var memoryStream = new MemoryStream(result.Body))
48-
{
49-
using (BinaryReader binaryReader = new BinaryReader(memoryStream))
50-
{
51-
long authKeyid = binaryReader.ReadInt64();
52-
long messageId = binaryReader.ReadInt64();
53-
int messageLength = binaryReader.ReadInt32();
54-
55-
byte[] response = binaryReader.ReadBytes(messageLength);
56-
57-
return response;
53+
transport.Send(packet);
5854
}
5955
}
6056
}

0 commit comments

Comments
 (0)