Commit cf26efc6 authored by vvaltman's avatar vvaltman

updated mtproto proxy protocol

parent 20824f5f
...@@ -789,11 +789,38 @@ static int _notify_remote_closed (JOB_REF_ARG(C), long long out_conn_id) { ...@@ -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) { void push_rpc_confirmation (JOB_REF_ARG (C), int confirm) {
if ((lrand48_j() & 1) || !(TCP_RPC_DATA(C)->flags & RPC_F_PAD)) {
struct raw_message *msg = malloc (sizeof (struct raw_message)); struct raw_message *msg = malloc (sizeof (struct raw_message));
rwm_create (msg, "\xdd", 1); rwm_create (msg, "\xdd", 1);
rwm_push_data (msg, &confirm, 4); rwm_push_data (msg, &confirm, 4);
mpq_push_w (CONN_INFO(C)->out_queue, msg, 0); mpq_push_w (CONN_INFO(C)->out_queue, msg, 0);
job_signal (JOB_REF_PASS (C), JS_RUN); 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 { struct client_packet_info {
...@@ -1645,7 +1672,7 @@ conn_target_job_t choose_proxy_target (int target_dc) { ...@@ -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) { 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; 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); 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);
...@@ -1670,11 +1697,11 @@ int forward_mtproto_packet (struct tl_in_state *tlio_in, connection_job_t C, int ...@@ -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); vkprintf (2, "received mtproto packet of %d bytes\n", len);
int inner_len = header[4]; 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); vkprintf (1, "received packet with bad inner length: %d (%d expected)\n", inner_len, len - 20);
return 0; return 0;
} }
if (len < 40) { if (inner_len < 20) {
//must have at least function id and nonce //must have at least function id and nonce
return 0; return 0;
} }
......
...@@ -185,8 +185,17 @@ int tcp_rpc_write_packet_compact (connection_job_t C, struct raw_message *raw) { ...@@ -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); 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; 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) { if (TCP_RPC_DATA(C)->flags & RPC_F_MEDIUM) {
rwm_push_data_front (raw, &len, 4); rwm_push_data_front (raw, &len, 4);
} else if (len <= 0x7e * 4) { } else if (len <= 0x7e * 4) {
......
...@@ -105,6 +105,7 @@ int tcp_rpc_default_execute (connection_job_t C, int op, struct raw_message *raw ...@@ -105,6 +105,7 @@ int tcp_rpc_default_execute (connection_job_t C, int op, struct raw_message *raw
#define RPCF_USE_CRC32C 2048 #define RPCF_USE_CRC32C 2048
/* for flags in struct tcp_rpc_data */ /* for flags in struct tcp_rpc_data */
#define RPC_F_PAD 0x8000000
#define RPC_F_DROPPED 0x10000000 #define RPC_F_DROPPED 0x10000000
#define RPC_F_MEDIUM 0x20000000 #define RPC_F_MEDIUM 0x20000000
#define RPC_F_COMPACT 0x40000000 #define RPC_F_COMPACT 0x40000000
......
...@@ -149,6 +149,13 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -149,6 +149,13 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
vkprintf (1, "Medium type\n"); vkprintf (1, "Medium type\n");
continue; 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 // 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) { if ((packet_len == *(int *)"HEAD" || packet_len == *(int *)"POST" || packet_len == *(int *)"GET " || packet_len == *(int *)"OPTI") && TCP_RPCS_FUNC(C)->http_fallback_type) {
...@@ -216,7 +223,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -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); 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); 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); assert (rwm_skip_data (&c->in, 64) == 64);
rwm_union (&c->in_u, &c->in); rwm_union (&c->in_u, &c->in);
rwm_init (&c->in, 0); rwm_init (&c->in, 0);
...@@ -226,6 +233,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -226,6 +233,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
case 0xeeeeeeee: case 0xeeeeeeee:
D->flags |= RPC_F_MEDIUM | RPC_F_EXTMODE2; D->flags |= RPC_F_MEDIUM | RPC_F_EXTMODE2;
break; break;
case 0xdddddddd:
D->flags |= RPC_F_MEDIUM | RPC_F_EXTMODE2 | RPC_F_PAD;
break;
case 0xefefefef: case 0xefefefef:
D->flags |= RPC_F_COMPACT | RPC_F_EXTMODE2; D->flags |= RPC_F_COMPACT | RPC_F_EXTMODE2;
break; break;
...@@ -269,10 +279,10 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -269,10 +279,10 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
int packet_len_bytes = 4; int packet_len_bytes = 4;
if (D->flags & RPC_F_MEDIUM) { if (D->flags & RPC_F_MEDIUM) {
// packet len in `medium` mode // 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); D->flags = (D->flags & ~RPC_F_QUICKACK) | (packet_len & RPC_F_QUICKACK);
packet_len &= ~RPC_F_QUICKACK; packet_len &= ~RPC_F_QUICKACK;
} //}
} else { } else {
// packet len in `compact` mode // packet len in `compact` mode
if (packet_len & 0x80) { if (packet_len & 0x80) {
...@@ -295,7 +305,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -295,7 +305,7 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
packet_len <<= 2; 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); vkprintf (1, "error while parsing packet: bad packet length %d\n", packet_len);
fail_connection (C, -1); fail_connection (C, -1);
return 0; return 0;
...@@ -317,6 +327,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) { ...@@ -317,6 +327,9 @@ int tcp_rpcs_compact_parse_execute (connection_job_t C) {
int packet_type; int packet_type;
rwm_split_head (&msg, &c->in, packet_len); 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); assert (rwm_fetch_lookup (&msg, &packet_type, 4) == 4);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment