1/*
2 This file is part of Mtproto-proxy Library.
3
4 Mtproto-proxy Library is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 Mtproto-proxy Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright 2010-2013 Vkontakte Ltd
18 2010-2013 Nikolai Durov
19 2010-2013 Andrey Lopatin
20 2013 Vitaliy Valtman
21
22 Copyright 2014-2016 Telegram Messenger Inc
23 2015-2016 Vitaly Valtman
24*/
25
26#pragma once
27
28#include "pid.h"
29
30struct tcp_message {
31 connection_job_t c;
32 int op;
33 int packet_num;
34 struct raw_message raw;
35};
36
37#pragma pack(push,4)
38struct tcp_rpc_nonce_packet {
39 int type;
40 int key_select; /* least significant 32 bits of key to use */
41 int crypto_schema; /* 0 = NONE, 1 = AES */
42 int crypto_ts;
43 char crypto_nonce[16];
44};
45
46#define RPC_MAX_EXTRA_KEYS 8
47
48struct tcp_rpc_nonce_ext_packet {
49 int type; /* type = RPC_NONCE */
50 int key_select; /* least significant 32 bits of key to use */
51 int crypto_schema; /* 2 = AES+extra keys */
52 int crypto_ts;
53 char crypto_nonce[16];
54 int extra_keys_count;
55 int extra_key_select[RPC_MAX_EXTRA_KEYS];
56};
57
58struct tcp_rpc_nonce_dh_packet {
59 int type; /* type = RPC_NONCE */
60 int key_select; /* least significant 32 bits of key to use */
61 int crypto_schema; /* 3 = AES+extra keys+DH */
62 int crypto_ts;
63 char crypto_nonce[16];
64 int extra_keys_count;
65 int extra_key_select[RPC_MAX_EXTRA_KEYS];
66 int dh_params_select; /* least significant 32 bits of SHA1 of DH params : g:int p:string */
67 unsigned char g_a[256];
68};
69
70struct tcp_rpc_handshake_packet {
71 int type;
72 int flags;
73 struct process_id sender_pid;
74 struct process_id peer_pid;
75 /* more ints? */
76};
77
78struct tcp_rpc_handshake_error_packet {
79 int type;
80 int error_code;
81 struct process_id sender_pid;
82};
83#pragma pack(pop)
84
85// Bit 1 - have to clone raw
86// Bit 2 - delete reference to connection
87// Bit 4 - raw is allocated pointer and it should be freed or reused
88void tcp_rpc_conn_send (JOB_REF_ARG (C), struct raw_message *raw, int flags);
89void tcp_rpc_conn_send_data (JOB_REF_ARG (C), int len, void *Q);
90void tcp_rpc_conn_send_init (__joblocked connection_job_t C, struct raw_message *raw, int flags);
91void tcp_rpc_conn_send_data_init (__joblocked connection_job_t c, int len, void *Q);
92void tcp_rpc_conn_send_im (JOB_REF_ARG (C), struct raw_message *raw, int flags);
93void tcp_rpc_conn_send_data_im (JOB_REF_ARG (C), int len, void *Q);
94int tcp_rpc_default_execute (connection_job_t C, int op, struct raw_message *raw);
95
96/* for crypto_flags in struct tcp_rpc_data */
97#define RPCF_ALLOW_UNENC 1
98#define RPCF_ALLOW_ENC 2
99#define RPCF_REQ_DH 4
100#define RPCF_ALLOW_SKIP_DH 8
101#define RPCF_ENC_SENT 16
102#define RPCF_SEQNO_HOLES 256
103#define RPCF_QUICKACK 512
104#define RPCF_COMPACT_OFF 1024
105#define RPCF_USE_CRC32C 2048
106
107/* for flags in struct tcp_rpc_data */
108#define RPC_F_DROPPED 0x10000000
109#define RPC_F_MEDIUM 0x20000000
110#define RPC_F_COMPACT 0x40000000
111#define RPC_F_COMPACT_MEDIUM (RPC_F_COMPACT | RPC_F_MEDIUM)
112#define RPC_F_QUICKACK 0x80000000
113#define RPC_F_EXTMODE1 0x10000
114#define RPC_F_EXTMODE2 0x20000
115#define RPC_F_EXTMODE3 0x30000
116
117/* in conn->custom_data */
118struct tcp_rpc_data {
119 //int packet_len;
120 //int packet_num;
121 //int packet_type;
122 //int packet_crc32;
123 int flags;
124 int in_packet_num;
125 int out_packet_num;
126 int crypto_flags; /* 1 = allow unencrypted, 2 = allow encrypted, 4 = require DH, 8 = crypto NONCE packet sent, 256 = packet numbers not sequential, 512 = allow quick ack packets, 1024 = compact mode off, 2048 = use CRC32-C instead of CRC32 */
127 struct process_id remote_pid;
128 char nonce[16];
129 int nonce_time;
130 int in_rpc_target;
131 union {
132 void *user_data;
133 void *extra;
134 };
135 int extra_int;
136 int extra_int2;
137 int extra_int3;
138 int extra_int4;
139 double extra_double, extra_double2;
140 crc32_partial_func_t custom_crc_partial;
141};
142
143//extern int default_rpc_flags; /* 0 = compatibility mode, RPC_USE_CRC32C = allow both CRC32C and CRC32 */
144
145#define RPC_NONCE 0x7acb87aa
146#define RPC_HANDSHAKE 0x7682eef5
147#define RPC_HANDSHAKE_ERROR 0x6a27beda
148
149#define RPC_CRYPTO_NONE 0
150#define RPC_CRYPTO_AES 1
151#define RPC_CRYPTO_AES_EXT 2
152#define RPC_CRYPTO_AES_DH 3
153
154#define RPC_MF_COMPACT_ALLOW 1
155#define RPC_MF_COMPACT_FORCE 2
156#define RPC_MF_IGNORE_PID 4
157#define RPC_MF_OPPORT_CRYPTO 8
158
159#define TCP_RPC_DATA(c) ((struct tcp_rpc_data *) (CONN_INFO(c)->custom_data))
160
161int tcp_rpc_flush_packet (connection_job_t C);
162int tcp_rpc_write_packet (connection_job_t C, struct raw_message *raw);
163int tcp_rpc_write_packet_compact (connection_job_t C, struct raw_message *raw);
164int tcp_rpc_flush (connection_job_t C);
165void tcp_rpc_send_ping (connection_job_t C, long long ping_id);
166unsigned tcp_set_default_rpc_flags (unsigned and_flags, unsigned or_flags);
167unsigned tcp_get_default_rpc_flags (void);
168void tcp_set_max_dh_accept_rate (int rate);
169int tcp_add_dh_accept (void);
170
171