Skip to content

Commit

Permalink
updated mtproto proxy protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
vvaltman committed Jul 9, 2018
1 parent 20824f5 commit cf26efc
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
43 changes: 35 additions & 8 deletions mtproto/mtproto-proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,11 +789,38 @@ static int _notify_remote_closed (JOB_REF_ARG(C), long long out_conn_id) {
}

void push_rpc_confirmation (JOB_REF_ARG (C), int confirm) {
struct raw_message *msg = malloc (sizeof (struct raw_message));
rwm_create (msg, "\xdd", 1);
rwm_push_data (msg, &confirm, 4);
mpq_push_w (CONN_INFO(C)->out_queue, msg, 0);
job_signal (JOB_REF_PASS (C), JS_RUN);

if ((lrand48_j() & 1) || !(TCP_RPC_DATA(C)->flags & RPC_F_PAD)) {
struct raw_message *msg = malloc (sizeof (struct raw_message));
rwm_create (msg, "\xdd", 1);
rwm_push_data (msg, &confirm, 4);
mpq_push_w (CONN_INFO(C)->out_queue, msg, 0);
job_signal (JOB_REF_PASS (C), JS_RUN);
} else {
int x = -1;
struct raw_message m;
assert (rwm_create (&m, &x, 4) == 4);
assert (rwm_push_data (&m, &confirm, 4) == 4);

int z = lrand48_j() & 1;
while (z-- > 0) {
int t = lrand48_j();
assert (rwm_push_data (&m, &t, 4) == 4);
}

tcp_rpc_conn_send (JOB_REF_CREATE_PASS (C), &m, 0);

x = 0;
assert (rwm_create (&m, &x, 4) == 4);

z = lrand48_j() & 1;
while (z-- > 0) {
int t = lrand48_j();
assert (rwm_push_data (&m, &t, 4) == 4);
}

tcp_rpc_conn_send (JOB_REF_PASS (C), &m, 0);
}
}

struct client_packet_info {
Expand Down Expand Up @@ -1645,7 +1672,7 @@ conn_target_job_t choose_proxy_target (int target_dc) {
}

static int forward_mtproto_enc_packet (struct tl_in_state *tlio_in, connection_job_t C, long long auth_key_id, int len, int remote_ip_port[5], int rpc_flags) {
if (len < offsetof (struct encrypted_message, message) || (len & 15) != (offsetof (struct encrypted_message, server_salt) & 15)) {
if (len < offsetof (struct encrypted_message, message) /*|| (len & 15) != (offsetof (struct encrypted_message, server_salt) & 15)*/) {
return 0;
}
vkprintf (2, "received mtproto encrypted packet of %d bytes from connection %p (#%d~%d), key=%016llx\n", len, C, CONN_INFO(C)->fd, CONN_INFO(C)->generation, auth_key_id);
Expand All @@ -1670,11 +1697,11 @@ int forward_mtproto_packet (struct tl_in_state *tlio_in, connection_job_t C, int
}
vkprintf (2, "received mtproto packet of %d bytes\n", len);
int inner_len = header[4];
if (inner_len + 20 != len) {
if (inner_len + 20 > len) {
vkprintf (1, "received packet with bad inner length: %d (%d expected)\n", inner_len, len - 20);
return 0;
}
if (len < 40) {
if (inner_len < 20) {
//must have at least function id and nonce
return 0;
}
Expand Down
11 changes: 10 additions & 1 deletion net/net-tcp-rpc-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,17 @@ int tcp_rpc_write_packet_compact (connection_job_t C, struct raw_message *raw) {
return tcp_rpc_write_packet (C, raw);
}

if (TCP_RPC_DATA(C)->flags & RPC_F_PAD) {
int x = lrand48_j();
int y = lrand48_j() & 3;
assert (rwm_push_data (raw, &x, y) == y);
}

int len = raw->total_bytes;
assert (!(len & 0xfc000003));
assert (!(len & 0xfc000000));
if (!(TCP_RPC_DATA(C)->flags & RPC_F_PAD)) {
assert (!(len & 3));
}
if (TCP_RPC_DATA(C)->flags & RPC_F_MEDIUM) {
rwm_push_data_front (raw, &len, 4);
} else if (len <= 0x7e * 4) {
Expand Down
1 change: 1 addition & 0 deletions net/net-tcp-rpc-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ int tcp_rpc_default_execute (connection_job_t C, int op, struct raw_message *raw
#define RPCF_USE_CRC32C 2048

/* for flags in struct tcp_rpc_data */
#define RPC_F_PAD 0x8000000
#define RPC_F_DROPPED 0x10000000
#define RPC_F_MEDIUM 0x20000000
#define RPC_F_COMPACT 0x40000000
Expand Down
21 changes: 17 additions & 4 deletions net/net-tcp-rpc-ext-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
vkprintf (1, "Medium type\n");
continue;
}
if (packet_len == 0xdddddddd) {
D->flags |= RPC_F_MEDIUM | RPC_F_PAD;
assert (rwm_skip_data (&c->in, 4) == 4);
D->in_packet_num = 0;
vkprintf (1, "Medium type\n");
continue;
}

// http
if ((packet_len == *(int *)"HEAD" || packet_len == *(int *)"POST" || packet_len == *(int *)"GET " || packet_len == *(int *)"OPTI") && TCP_RPCS_FUNC(C)->http_fallback_type) {
Expand Down Expand Up @@ -216,7 +223,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
T->read_aeskey.type->ctr128_crypt (&T->read_aeskey, random_header, random_header, 64, T->read_iv, T->read_ebuf, &T->read_num);
unsigned tag = *(unsigned *)(random_header + 56);

if (tag == 0xeeeeeeee || tag == 0xefefefef) {
if (tag == 0xdddddddd || tag == 0xeeeeeeee || tag == 0xefefefef) {
assert (rwm_skip_data (&c->in, 64) == 64);
rwm_union (&c->in_u, &c->in);
rwm_init (&c->in, 0);
Expand All @@ -226,6 +233,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
case 0xeeeeeeee:
D->flags |= RPC_F_MEDIUM | RPC_F_EXTMODE2;
break;
case 0xdddddddd:
D->flags |= RPC_F_MEDIUM | RPC_F_EXTMODE2 | RPC_F_PAD;
break;
case 0xefefefef:
D->flags |= RPC_F_COMPACT | RPC_F_EXTMODE2;
break;
Expand Down Expand Up @@ -269,10 +279,10 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
int packet_len_bytes = 4;
if (D->flags & RPC_F_MEDIUM) {
// packet len in `medium` mode
if (D->crypto_flags & RPCF_QUICKACK) {
//if (D->crypto_flags & RPCF_QUICKACK) {
D->flags = (D->flags & ~RPC_F_QUICKACK) | (packet_len & RPC_F_QUICKACK);
packet_len &= ~RPC_F_QUICKACK;
}
//}
} else {
// packet len in `compact` mode
if (packet_len & 0x80) {
Expand All @@ -295,7 +305,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
packet_len <<= 2;
}

if (packet_len <= 0 || (packet_len & 0xc0000003)) {
if (packet_len <= 0 || (packet_len & 0xc0000000) || (!(D->flags & RPC_F_PAD) && (packet_len & 3))) {
vkprintf (1, "error while parsing packet: bad packet length %d\n", packet_len);
fail_connection (C, -1);
return 0;
Expand All @@ -317,6 +327,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
int packet_type;

rwm_split_head (&msg, &c->in, packet_len);
if (D->flags & RPC_F_PAD) {
rwm_trunc (&msg, packet_len & -4);
}

assert (rwm_fetch_lookup (&msg, &packet_type, 4) == 4);

Expand Down

1 comment on commit cf26efc

@AC130USpectre
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi. It would be nice to see a changelog, which issues this commit has solved or which features it has added.

Please sign in to comment.