Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
tg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
tg
Commits
b12ca538
Commit
b12ca538
authored
Aug 14, 2014
by
Vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
many updates
parent
fe08f0c5
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1496 additions
and
1699 deletions
+1496
-1699
Makefile.in
Makefile.in
+2
-1
binlog.c
binlog.c
+2
-1
loop.c
loop.c
+12
-306
main.c
main.c
+4
-3
mtproto-client.c
mtproto-client.c
+248
-915
mtproto-client.h
mtproto-client.h
+71
-10
mtproto-common.c
mtproto-common.c
+2
-16
mtproto-common.h
mtproto-common.h
+7
-5
net.c
net.c
+110
-186
net.h
net.h
+18
-66
queries.c
queries.c
+118
-138
queries.h
queries.h
+9
-15
structures.c
structures.c
+14
-13
tgl-inner.h
tgl-inner.h
+11
-0
tgl.c
tgl.c
+17
-0
tgl.h
tgl.h
+44
-8
tools.c
tools.c
+45
-1
tools.h
tools.h
+4
-0
tree.h
tree.h
+15
-15
updates.c
updates.c
+728
-0
updates.h
updates.h
+15
-0
No files found.
Makefile.in
View file @
b12ca538
...
...
@@ -18,7 +18,7 @@ DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${DEP}/auto ${OBJ}/auto
EXE_LIST
=
${
EXE
}
/generate
${
EXE
}
/tlc
${
EXE
}
/telegram-cli
TG_OBJECTS
=
${
OBJ
}
/main.o
${
OBJ
}
/loop.o
${
OBJ
}
/interface.o
${
OBJ
}
/net.o
${
OBJ
}
/mtproto-common.o
${
OBJ
}
/mtproto-client.o
${
OBJ
}
/queries.o
${
OBJ
}
/structures.o
${
OBJ
}
/binlog.o
${
OBJ
}
/lua-tg.o
${
OBJ
}
/auto/auto.o
${
OBJ
}
/tgl.o
TG_OBJECTS
=
${
OBJ
}
/main.o
${
OBJ
}
/loop.o
${
OBJ
}
/interface.o
${
OBJ
}
/net.o
${
OBJ
}
/mtproto-common.o
${
OBJ
}
/mtproto-client.o
${
OBJ
}
/queries.o
${
OBJ
}
/structures.o
${
OBJ
}
/binlog.o
${
OBJ
}
/lua-tg.o
${
OBJ
}
/auto/auto.o
${
OBJ
}
/tgl.o
${
OBJ
}
/updates.o
TLC_OBJECTS
=
${
OBJ
}
/tlc.o
${
OBJ
}
/tl-parser.o
${
OBJ
}
/crc32.o
GENERATE_OBJECTS
=
${
OBJ
}
/generate.o
COMMON_OBJECTS
=
${
OBJ
}
/tools.o
...
...
@@ -60,6 +60,7 @@ ${EXE}/generate: ${GENERATE_OBJECTS} ${COMMON_OBJECTS}
${
CC
}
${
GENERATE_OBJECTS
}
${
COMMON_OBJECTS
}
${
LINK_FLAGS
}
-o
$@
${AUTO}/scheme.tlo
:
${AUTO}/scheme.tl ${EXE}/tlc
${EXE}/tlc
-e
$@
${AUTO}/scheme.tl
${AUTO}/scheme.tl
:
${srcdir}/scheme.tl ${srcdir}/binlog.tl ${srcdir}/append.tl
...
...
binlog.c
View file @
b12ca538
...
...
@@ -44,6 +44,7 @@
#include "loop.h"
#include "tgl.h"
#include "auto.h"
#include <openssl/sha.h>
...
...
@@ -80,7 +81,7 @@ static int fetch_comb_binlog_dc_option (void *extra) {
vlogprintf
(
E_NOTICE
,
"DC%d '%.*s' update: %.*s:%d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
alloc_dc
(
id
,
tstrndup
(
ip
,
l2
),
port
);
tglmp_
alloc_dc
(
id
,
tstrndup
(
ip
,
l2
),
port
);
return
0
;
}
...
...
loop.c
View file @
b12ca538
...
...
@@ -44,20 +44,11 @@
#include <fcntl.h>
#include "interface.h"
#include "net.h"
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "queries.h"
#include "telegram.h"
#include "loop.h"
#include "binlog.h"
#include "lua-tg.h"
#include "structures.h"
#include "tgl.h"
#include "auto.h"
extern
char
*
default_username
;
extern
char
*
auth_token
;
void
set_default_username
(
const
char
*
s
);
...
...
@@ -80,7 +71,7 @@ void net_loop (int flags, int (*is_end)(void)) {
cc
++
;
}
write_state_file
();
//
write_state_file ();
int
x
=
connections_make_poll_array
(
fds
+
cc
,
101
-
cc
)
+
cc
;
double
timer
=
next_timer_in
();
if
(
timer
>
1000
)
{
timer
=
1000
;
}
...
...
@@ -155,289 +146,6 @@ char *get_state_filename (void);
char
*
get_secret_chat_filename
(
void
);
int
zero
[
512
];
/*
void write_dc (int auth_file_fd, struct dc *DC) {
assert (write (auth_file_fd, &DC->port, 4) == 4);
int l = strlen (DC->ip);
assert (write (auth_file_fd, &l, 4) == 4);
assert (write (auth_file_fd, DC->ip, l) == l);
if (DC->flags & 1) {
assert (write (auth_file_fd, &DC->auth_key_id, 8) == 8);
assert (write (auth_file_fd, DC->auth_key, 256) == 256);
} else {
assert (write (auth_file_fd, zero, 256 + 8) == 256 + 8);
}
assert (write (auth_file_fd, &DC->server_salt, 8) == 8);
assert (write (auth_file_fd, &DC->has_auth, 4) == 4);
}
void write_auth_file (void) {
if (binlog_enabled) { return; }
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
assert (auth_file_fd >= 0);
int x = DC_SERIALIZED_MAGIC_V2;
assert (write (auth_file_fd, &x, 4) == 4);
x = MAX_DC_ID;
assert (write (auth_file_fd, &x, 4) == 4);
assert (write (auth_file_fd, &dc_working_num, 4) == 4);
assert (write (auth_file_fd, &auth_state, 4) == 4);
int i;
for (i = 0; i <= MAX_DC_ID; i++) {
if (DC_list[i]) {
x = 1;
assert (write (auth_file_fd, &x, 4) == 4);
write_dc (auth_file_fd, DC_list[i]);
} else {
x = 0;
assert (write (auth_file_fd, &x, 4) == 4);
}
}
assert (write (auth_file_fd, &tgl_state.our_id, 4) == 4);
close (auth_file_fd);
}
void read_dc (int auth_file_fd, int id, unsigned ver) {
int port = 0;
assert (read (auth_file_fd, &port, 4) == 4);
int l = 0;
assert (read (auth_file_fd, &l, 4) == 4);
assert (l >= 0);
char *ip = talloc (l + 1);
assert (read (auth_file_fd, ip, l) == l);
ip[l] = 0;
struct dc *DC = alloc_dc (id, ip, port);
assert (read (auth_file_fd, &DC->auth_key_id, 8) == 8);
assert (read (auth_file_fd, &DC->auth_key, 256) == 256);
assert (read (auth_file_fd, &DC->server_salt, 8) == 8);
if (DC->auth_key_id) {
DC->flags |= 1;
}
if (ver != DC_SERIALIZED_MAGIC) {
assert (read (auth_file_fd, &DC->has_auth, 4) == 4);
} else {
DC->has_auth = 0;
}
}
void empty_auth_file (void) {
alloc_dc (1, tstrdup (tgl_state.test_mode ? TG_SERVER_TEST : TG_SERVER), 443);
dc_working_num = 1;
auth_state = 0;
write_auth_file ();
}
int need_dc_list_update;
void read_auth_file (void) {
if (binlog_enabled) { return; }
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
if (auth_file_fd < 0) {
empty_auth_file ();
}
assert (auth_file_fd >= 0);
unsigned x;
unsigned m;
if (read (auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC && m != DC_SERIALIZED_MAGIC_V2)) {
close (auth_file_fd);
empty_auth_file ();
return;
}
assert (read (auth_file_fd, &x, 4) == 4);
assert (x <= MAX_DC_ID);
assert (read (auth_file_fd, &dc_working_num, 4) == 4);
assert (read (auth_file_fd, &auth_state, 4) == 4);
if (m == DC_SERIALIZED_MAGIC) {
auth_state = 700;
}
int i;
for (i = 0; i <= (int)x; i++) {
int y;
assert (read (auth_file_fd, &y, 4) == 4);
if (y) {
read_dc (auth_file_fd, i, m);
}
}
int l = read (auth_file_fd, &tgl_state.our_id, 4);
if (l < 4) {
assert (!l);
}
close (auth_file_fd);
DC_working = DC_list[dc_working_num];
if (m == DC_SERIALIZED_MAGIC) {
DC_working->has_auth = 1;
}
}
int pts, qts, seq, last_date;
void read_state_file (void) {
if (binlog_enabled) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int version, magic;
if (read (state_file_fd, &magic, 4) < 4) { close (state_file_fd); return; }
if (magic != (int)STATE_FILE_MAGIC) { close (state_file_fd); return; }
if (read (state_file_fd, &version, 4) < 4) { close (state_file_fd); return; }
assert (version >= 0);
int x[4];
if (read (state_file_fd, x, 16) < 16) {
close (state_file_fd);
return;
}
pts = x[0];
qts = x[1];
seq = x[2];
last_date = x[3];
close (state_file_fd);
}
void write_state_file (void) {
if (binlog_enabled) { return; }
static int wseq;
static int wpts;
static int wqts;
static int wdate;
if (wseq >= seq && wpts >= pts && wqts >= qts && wdate >= last_date) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int x[6];
x[0] = STATE_FILE_MAGIC;
x[1] = 0;
x[2] = pts;
x[3] = qts;
x[4] = seq;
x[5] = last_date;
assert (write (state_file_fd, x, 24) == 24);
close (state_file_fd);
wseq = seq; wpts = pts; wqts = qts; wdate = last_date;
}
extern tgl_peer_t *Peers[];
extern int peer_num;
extern int encr_root;
extern unsigned char *encr_prime;
extern int encr_param_version;
extern int dialog_list_got;
void read_secret_chat_file (void) {
if (binlog_enabled) { return; }
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
if (read (fd, x, 8) < 8) {
close (fd); return;
}
if (x[0] != (int)SECRET_CHAT_FILE_MAGIC) { close (fd); return; }
int version = x[1];
assert (version >= 0);
int cc;
assert (read (fd, &cc, 4) == 4);
int i;
for (i = 0; i < cc; i++) {
tgl_peer_t *P = talloc0 (sizeof (*P));
struct tgl_secret_chat *E = &P->encr_chat;
int t;
assert (read (fd, &t, 4) == 4);
P->id = TGL_MK_ENCR_CHAT (t);
assert (read (fd, &P->flags, 4) == 4);
assert (read (fd, &t, 4) == 4);
assert (t > 0);
P->print_name = talloc (t + 1);
assert (read (fd, P->print_name, t) == t);
P->print_name[t] = 0;
tglp_peer_insert_name (P);
assert (read (fd, &E->state, 4) == 4);
assert (read (fd, &E->user_id, 4) == 4);
assert (read (fd, &E->admin_id, 4) == 4);
assert (read (fd, &E->ttl, 4) == 4);
assert (read (fd, &E->access_hash, 8) == 8);
if (E->state != sc_waiting) {
E->g_key = talloc (256);
assert (read (fd, E->g_key, 256) == 256);
E->nonce = talloc (256);
assert (read (fd, E->nonce, 256) == 256);
}
assert (read (fd, E->key, 256) == 256);
assert (read (fd, &E->key_fingerprint, 8) == 8);
tglp_insert_encrypted_chat (P);
}
if (version >= 1) {
assert (read (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (read (fd, &encr_param_version, 4) == 4);
encr_prime = talloc (256);
assert (read (fd, encr_prime, 256) == 256);
}
}
close (fd);
}
void count_encr_peer (tgl_peer_t *P, void *cc) {
if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) {
(*(int *)cc) ++;
}
}
void write_encr_peer (tgl_peer_t *P, void *pfd) {
int fd = *(int *)pfd;
if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) {
int t = tgl_get_peer_id (P->id);
assert (write (fd, &t, 4) == 4);
t = P->flags;
assert (write (fd, &t, 4) == 4);
t = strlen (P->print_name);
assert (write (fd, &t, 4) == 4);
assert (write (fd, P->print_name, t) == t);
assert (write (fd, &P->encr_chat.state, 4) == 4);
assert (write (fd, &P->encr_chat.user_id, 4) == 4);
assert (write (fd, &P->encr_chat.admin_id, 4) == 4);
assert (write (fd, &P->encr_chat.ttl, 4) == 4);
assert (write (fd, &P->encr_chat.access_hash, 8) == 8);
if (P->encr_chat.state != sc_waiting) {
assert (write (fd, P->encr_chat.g_key, 256) == 256);
}
if (P->encr_chat.state != sc_waiting) {
assert (write (fd, P->encr_chat.nonce, 256) == 256);
}
assert (write (fd, P->encr_chat.key, 256) == 256);
assert (write (fd, &P->encr_chat.key_fingerprint, 8) == 8);
}
}
void write_secret_chat_file (void) {
if (binlog_enabled) { return; }
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
x[0] = SECRET_CHAT_FILE_MAGIC;
x[1] = 1;
assert (write (fd, x, 8) == 8);
int cc = 0;
tgl_peer_iterator_ex (count_encr_peer, &cc);
tgl_peer_iterator_ex (write_encr_peer, &fd);
assert (write (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (write (fd, &encr_param_version, 4) == 4);
assert (write (fd, encr_prime, 256) == 256);
}
close (fd);
}*/
extern
int
max_chat_size
;
int
mcs
(
void
)
{
return
max_chat_size
;
...
...
@@ -456,19 +164,17 @@ int new_dc_num;
int
wait_dialog_list
;
int
loop
(
void
)
{
on_start
();
if
(
binlog_enabled
)
{
double
t
=
get_double_time
();
logprintf
(
"replay log start
\n
"
);
tgl_replay_log
();
logprintf
(
"replay log end in %lf seconds
\n
"
,
get_double_time
()
-
t
);
tgl_reopen_binlog_for_writing
();
#ifdef USE_LUA
lua_binlog_end
();
#endif
}
else
{
read_auth_file
();
}
//on_start ();
tgl_init
();
double
t
=
get_double_time
();
logprintf
(
"replay log start
\n
"
);
tgl_replay_log
();
logprintf
(
"replay log end in %lf seconds
\n
"
,
get_double_time
()
-
t
);
tgl_reopen_binlog_for_writing
();
#ifdef USE_LUA
lua_binlog_end
();
#endif
update_prompt
();
assert
(
DC_list
[
dc_working_num
]);
...
...
main.c
View file @
b12ca538
...
...
@@ -386,8 +386,8 @@ void usage (void) {
exit
(
1
);
}
extern
char
*
rsa_public_key_name
;
extern
int
default_dc_num
;
//
extern char *rsa_public_key_name;
//
extern int default_dc_num;
char
*
log_net_file
;
FILE
*
log_net_f
;
...
...
@@ -406,7 +406,8 @@ void args_parse (int argc, char **argv) {
set_default_username
(
optarg
);
break
;
case
'k'
:
rsa_public_key_name
=
tstrdup
(
optarg
);
//rsa_public_key_name = tstrdup (optarg);
tgl_set_rsa_key
(
optarg
);
break
;
case
'v'
:
tgl_incr_verbosity
();
...
...
mtproto-client.c
View file @
b12ca538
...
...
@@ -46,14 +46,18 @@
#include <poll.h>
#include "telegram.h"
#include "net.h"
#include "include.h"
#include "queries.h"
#include "loop.h"
//
#include "loop.h"
#include "structures.h"
#include "binlog.h"
#include "auto.h"
#include "tgl.h"
#include "mtproto-client.h"
#include "tools.h"
#include "tree.h"
#include "updates.h"
#include <event2/event.h>
#if defined(__FreeBSD__)
#define __builtin_bswap32(x) bswap32(x)
...
...
@@ -68,35 +72,29 @@
#include "mtproto-common.h"
#define MAX_NET_RES (1L << 16)
extern
int
log_level
;
//
extern int log_level;
int
verbosity
;
int
auth_success
;
enum
dc_state
c_state
;
char
nonce
[
256
];
char
new_nonce
[
256
];
char
server_nonce
[
256
];
extern
int
binlog_enabled
;
extern
int
disable_auto_accept
;
extern
int
allow_weak_random
;
//
int verbosity;
static
int
auth_success
;
static
enum
dc_state
c_state
;
static
char
nonce
[
256
];
static
char
new_nonce
[
256
];
static
char
server_nonce
[
256
];
//
extern int binlog_enabled;
//
extern int disable_auto_accept;
//
extern int allow_weak_random;
int
total_packets_sent
;
long
long
total_data_sent
;
static
int
total_packets_sent
;
static
long
long
total_data_sent
;
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
);
int
rpc_becomes_ready
(
struct
connection
*
c
);
int
rpc_close
(
struct
connection
*
c
);
static
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
);
static
int
rpc_becomes_ready
(
struct
connection
*
c
);
static
int
rpc_close
(
struct
connection
*
c
);
struct
connection_methods
auth_methods
=
{
.
execute
=
rpc_execute
,
.
ready
=
rpc_becomes_ready
,
.
close
=
rpc_close
};
static
long
long
precise_time
;
long
long
precise_time
;
double
get_utime
(
int
clock_id
)
{
static
double
get_utime
(
int
clock_id
)
{
struct
timespec
T
;
my_clock_gettime
(
clock_id
,
&
T
);
double
res
=
T
.
tv_sec
+
(
double
)
T
.
tv_nsec
*
1e-9
;
...
...
@@ -106,25 +104,15 @@ double get_utime (int clock_id) {
return
res
;
}
void
secure_random
(
void
*
s
,
int
l
)
{
if
(
RAND_bytes
(
s
,
l
)
<
0
)
{
if
(
allow_weak_random
)
{
RAND_pseudo_bytes
(
s
,
l
);
}
else
{
assert
(
0
&&
"End of random. If you want, you can start with -w"
);
}
}
}
#define STATS_BUFF_SIZE (64 << 10)
int
stats_buff_len
;
char
stats_buff
[
STATS_BUFF_SIZE
];
//
#define STATS_BUFF_SIZE (64 << 10)
//static
int stats_buff_len;
//static
char stats_buff[STATS_BUFF_SIZE];
#define MAX_RESPONSE_SIZE (1L << 24)
char
Response
[
MAX_RESPONSE_SIZE
];
int
Response_len
;
static
char
Response
[
MAX_RESPONSE_SIZE
];
//static
int Response_len;
/*
*
...
...
@@ -133,9 +121,9 @@ int Response_len;
*/
#define TG_SERVER_PUBKEY_FILENAME "tg-server.pub"
char
*
rsa_public_key_name
;
// = TG_SERVER_PUBKEY_FILENAME;
RSA
*
pubKey
;
long
long
pk_fingerprint
;
static
char
*
rsa_public_key_name
;
// = TG_SERVER_PUBKEY_FILENAME;
static
RSA
*
pubKey
;
static
long
long
pk_fingerprint
;
static
int
rsa_load_public_key
(
const
char
*
public_key_name
)
{
pubKey
=
NULL
;
...
...
@@ -162,18 +150,16 @@ static int rsa_load_public_key (const char *public_key_name) {
int
auth_work_start
(
struct
connection
*
c
);
/*
*
* UNAUTHORIZED (DH KEY EXCHANGE) PROTOCOL PART
*
*/
BIGNUM
dh_prime
,
dh_g
,
g_a
,
dh_power
,
auth_key_num
;
char
s_power
[
256
];
static
BIGNUM
dh_prime
,
dh_g
,
g_a
,
auth_key_num
;
static
char
s_power
[
256
];
struct
{
st
atic
st
ruct
{
long
long
auth_key_id
;
long
long
out_msg_id
;
int
msg_len
;
...
...
@@ -181,24 +167,25 @@ struct {
#define ENCRYPT_BUFFER_INTS 16384
int
encrypt_buffer
[
ENCRYPT_BUFFER_INTS
];
static
int
encrypt_buffer
[
ENCRYPT_BUFFER_INTS
];
#define DECRYPT_BUFFER_INTS 16384
int
decrypt_buffer
[
ENCRYPT_BUFFER_INTS
];
static
int
decrypt_buffer
[
ENCRYPT_BUFFER_INTS
];
int
encrypt_packet_buffer
(
void
)
{
static
int
encrypt_packet_buffer
(
void
)
{
return
pad_rsa_encrypt
((
char
*
)
packet_buffer
,
(
packet_ptr
-
packet_buffer
)
*
4
,
(
char
*
)
encrypt_buffer
,
ENCRYPT_BUFFER_INTS
*
4
,
pubKey
->
n
,
pubKey
->
e
);
}
int
encrypt_packet_buffer_aes_unauth
(
const
char
server_nonce
[
16
],
const
char
hidden_client_nonce
[
32
])
{
static
int
encrypt_packet_buffer_aes_unauth
(
const
char
server_nonce
[
16
],
const
char
hidden_client_nonce
[
32
])
{
init_aes_unauth
(
server_nonce
,
hidden_client_nonce
,
AES_ENCRYPT
);
return
pad_aes_encrypt
((
char
*
)
packet_buffer
,
(
packet_ptr
-
packet_buffer
)
*
4
,
(
char
*
)
encrypt_buffer
,
ENCRYPT_BUFFER_INTS
*
4
);
}
int
rpc_send_packet
(
struct
connection
*
c
)
{
static
int
rpc_send_packet
(
struct
connection
*
c
)
{
int
len
=
(
packet_ptr
-
packet_buffer
)
*
4
;
c
->
out_packet_num
++
;
//c->out_packet_num ++;
tgl_state
.
net_methods
->
incr_out_packet_num
(
c
);
long
long
next_msg_id
=
(
long
long
)
((
1LL
<<
32
)
*
get_utime
(
CLOCK_REALTIME
))
&
-
4
;
if
(
next_msg_id
<=
unenc_msg_header
.
out_msg_id
)
{
unenc_msg_header
.
out_msg_id
+=
4
;
...
...
@@ -211,60 +198,64 @@ int rpc_send_packet (struct connection *c) {
assert
(
total_len
>
0
&&
!
(
total_len
&
0xfc000003
));
total_len
>>=
2
;
if
(
total_len
<
0x7f
)
{
assert
(
write_out
(
c
,
&
total_len
,
1
)
==
1
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
&
total_len
,
1
)
==
1
);
}
else
{
total_len
=
(
total_len
<<
8
)
|
0x7f
;
assert
(
write_out
(
c
,
&
total_len
,
4
)
==
4
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
&
total_len
,
4
)
==
4
);
}
write_out
(
c
,
&
unenc_msg_header
,
20
);
write_out
(
c
,
packet_buffer
,
len
);
flush_out
(
c
);
tgl_state
.
net_methods
->
write_out
(
c
,
&
unenc_msg_header
,
20
);
tgl_state
.
net_methods
->
write_out
(
c
,
packet_buffer
,
len
);
tgl_state
.
net_methods
->
flush_out
(
c
);
total_packets_sent
++
;
total_data_sent
+=
total_len
;
return
1
;
}
int
rpc_send_message
(
struct
connection
*
c
,
void
*
data
,
int
len
)
{
static
int
rpc_send_message
(
struct
connection
*
c
,
void
*
data
,
int
len
)
{
assert
(
len
>
0
&&
!
(
len
&
0xfc000003
));
int
total_len
=
len
>>
2
;
if
(
total_len
<
0x7f
)
{
assert
(
write_out
(
c
,
&
total_len
,
1
)
==
1
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
&
total_len
,
1
)
==
1
);
}
else
{
total_len
=
(
total_len
<<
8
)
|
0x7f
;
assert
(
write_out
(
c
,
&
total_len
,
4
)
==
4
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
&
total_len
,
4
)
==
4
);
}
c
->
out_packet_num
++
;
assert
(
write_out
(
c
,
data
,
len
)
==
len
);
flush_out
(
c
);
tgl_state
.
net_methods
->
incr_out_packet_num
(
c
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
data
,
len
)
==
len
);
tgl_state
.
net_methods
->
flush_out
(
c
);
total_packets_sent
++
;
total_data_sent
+=
total_len
;
return
1
;
}
int
send_req_pq_packet
(
struct
connection
*
c
)
{
assert
(
c_state
==
st_init
);
secure_random
(
nonce
,
16
);
static
int
send_req_pq_packet
(
struct
connection
*
c
)
{
struct
dc
*
D
=
tgl_state
.
net_methods
->
get_dc
(
c
);
assert
(
D
->
state
==
st_init
);
tglt_secure_random
(
nonce
,
16
);
unenc_msg_header
.
out_msg_id
=
0
;
clear_packet
();
out_int
(
CODE_req_pq
);
out_ints
((
int
*
)
nonce
,
4
);
rpc_send_packet
(
c
);
c_state
=
st_reqpq_sent
;
D
->
state
=
st_reqpq_sent
;
return
1
;
}
unsigned
long
long
gcd
(
unsigned
long
long
a
,
unsigned
long
long
b
)
{
static
unsigned
long
long
gcd
(
unsigned
long
long
a
,
unsigned
long
long
b
)
{
return
b
?
gcd
(
b
,
a
%
b
)
:
a
;
}
//typedef unsigned int uint128_t __attribute__ ((mode(TI)));
unsigned
long
long
what
;
unsigned
p1
,
p2
;
int
process_respq_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
static
int
process_respq_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
unsigned
long
long
what
;
unsigned
p1
,
p2
;
int
i
;
vlogprintf
(
E_DEBUG
,
"process_respq_answer(), len=%d
\n
"
,
len
);
assert
(
len
>=
76
);
...
...
@@ -383,7 +374,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
//out_int (0x0501); // q=5
out_ints
((
int
*
)
nonce
,
4
);
out_ints
((
int
*
)
server_nonce
,
4
);
secure_random
(
new_nonce
,
32
);
tglt_
secure_random
(
new_nonce
,
32
);
out_ints
((
int
*
)
new_nonce
,
8
);
sha1
((
unsigned
char
*
)
(
packet_buffer
+
5
),
(
packet_ptr
-
packet_buffer
-
5
)
*
4
,
(
unsigned
char
*
)
packet_buffer
);
...
...
@@ -428,13 +419,13 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
return
rpc_send_packet
(
c
);
}
int
check_prime
(
BIGNUM
*
p
)
{
static
int
check_prime
(
BIGNUM
*
p
)
{
int
r
=
BN_is_prime
(
p
,
BN_prime_checks
,
0
,
BN_ctx
,
0
);
ensure
(
r
>=
0
);
return
r
;
}
int
check_DH_params
(
BIGNUM
*
p
,
int
g
)
{
int
tglmp_
check_DH_params
(
BIGNUM
*
p
,
int
g
)
{
if
(
g
<
2
||
g
>
7
)
{
return
-
1
;
}
BIGNUM
t
;
BN_init
(
&
t
);
...
...
@@ -480,7 +471,7 @@ int check_DH_params (BIGNUM *p, int g) {
return
0
;
}
int
check_g
(
unsigned
char
p
[
256
],
BIGNUM
*
g
)
{
int
tglmp_
check_g
(
unsigned
char
p
[
256
],
BIGNUM
*
g
)
{
static
unsigned
char
s
[
256
];
memset
(
s
,
0
,
256
);
assert
(
BN_num_bytes
(
g
)
<=
256
);
...
...
@@ -516,19 +507,19 @@ int check_g (unsigned char p[256], BIGNUM *g) {
return
0
;
}
int
check_g_bn
(
BIGNUM
*
p
,
BIGNUM
*
g
)
{
int
tglmp_
check_g_bn
(
BIGNUM
*
p
,
BIGNUM
*
g
)
{
static
unsigned
char
s
[
256
];
memset
(
s
,
0
,
256
);
assert
(
BN_num_bytes
(
p
)
<=
256
);
BN_bn2bin
(
p
,
s
);
return
check_g
(
s
,
g
);
return
tglmp_
check_g
(
s
,
g
);
}
int
process_dh_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
static
int
process_dh_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
vlogprintf
(
E_DEBUG
,
"process_dh_answer(), len=%d
\n
"
,
len
);
if
(
len
<
116
)
{
vlogprintf
(
E_ERROR
,
"%u * %u = %llu"
,
p1
,
p2
,
what
);
}
//
if (len < 116) {
//
vlogprintf (E_ERROR, "%u * %u = %llu", p1, p2, what);
//
}
assert
(
len
>=
116
);
assert
(
!*
(
long
long
*
)
packet
);
assert
(
*
(
int
*
)
(
packet
+
16
)
==
len
-
20
);
...
...
@@ -554,19 +545,20 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
BN_init
(
&
g_a
);
assert
(
fetch_bignum
(
&
dh_prime
)
>
0
);
assert
(
fetch_bignum
(
&
g_a
)
>
0
);
assert
(
check_g_bn
(
&
dh_prime
,
&
g_a
)
>=
0
);
assert
(
tglmp_
check_g_bn
(
&
dh_prime
,
&
g_a
)
>=
0
);
int
server_time
=
*
in_ptr
++
;
assert
(
in_ptr
<=
in_end
);
assert
(
check_DH_params
(
&
dh_prime
,
g
)
>=
0
);
assert
(
tglmp_
check_DH_params
(
&
dh_prime
,
g
)
>=
0
);
static
char
sha1_buffer
[
20
];
sha1
((
unsigned
char
*
)
decrypt_buffer
+
20
,
(
in_ptr
-
decrypt_buffer
-
5
)
*
4
,
(
unsigned
char
*
)
sha1_buffer
);
assert
(
!
memcmp
(
decrypt_buffer
,
sha1_buffer
,
20
));
assert
((
char
*
)
in_end
-
(
char
*
)
in_ptr
<
16
);
GET_DC
(
c
)
->
server_time_delta
=
server_time
-
time
(
0
);
GET_DC
(
c
)
->
server_time_udelta
=
server_time
-
get_utime
(
CLOCK_MONOTONIC
);
struct
dc
*
D
=
tgl_state
.
net_methods
->
get_dc
(
c
);
D
->
server_time_delta
=
server_time
-
time
(
0
);
D
->
server_time_udelta
=
server_time
-
get_utime
(
CLOCK_MONOTONIC
);
//logprintf ( "server time is %d, delta = %d\n", server_time, server_time_delta);
// Build set_client_DH_params answer
...
...
@@ -580,7 +572,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
BN_init
(
&
dh_g
);
ensure
(
BN_set_word
(
&
dh_g
,
g
));
secure_random
(
s_power
,
256
);
tglt_
secure_random
(
s_power
,
256
);
BIGNUM
*
dh_power
=
BN_bin2bn
((
unsigned
char
*
)
s_power
,
256
,
0
);
ensure_ptr
(
dh_power
);
...
...
@@ -594,8 +586,8 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
ensure
(
BN_mod_exp
(
&
auth_key_num
,
&
g_a
,
dh_power
,
&
dh_prime
,
BN_ctx
));
l
=
BN_num_bytes
(
&
auth_key_num
);
assert
(
l
>=
250
&&
l
<=
256
);
assert
(
BN_bn2bin
(
&
auth_key_num
,
(
unsigned
char
*
)
GET_DC
(
c
)
->
auth_key
));
memset
(
GET_DC
(
c
)
->
auth_key
+
l
,
0
,
256
-
l
);
assert
(
BN_bn2bin
(
&
auth_key_num
,
(
unsigned
char
*
)
D
->
auth_key
));
memset
(
D
->
auth_key
+
l
,
0
,
256
-
l
);
BN_free
(
dh_power
);
BN_free
(
&
auth_key_num
);
BN_free
(
&
dh_g
);
...
...
@@ -622,7 +614,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
}
int
process_auth_complete
(
struct
connection
*
c
UU
,
char
*
packet
,
int
len
)
{
static
int
process_auth_complete
(
struct
connection
*
c
UU
,
char
*
packet
,
int
len
)
{
vlogprintf
(
E_DEBUG
,
"process_dh_answer(), len=%d
\n
"
,
len
);
assert
(
len
==
72
);
assert
(
!*
(
long
long
*
)
packet
);
...
...
@@ -636,13 +628,14 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
tmp
[
32
]
=
1
;
//GET_DC(c)->auth_key_id = *(long long *)(sha1_buffer + 12);
bl_do_set_auth_key_id
(
GET_DC
(
c
)
->
id
,
(
unsigned
char
*
)
GET_DC
(
c
)
->
auth_key
);
sha1
((
unsigned
char
*
)
GET_DC
(
c
)
->
auth_key
,
256
,
sha1_buffer
);
struct
dc
*
D
=
tgl_state
.
net_methods
->
get_dc
(
c
);
bl_do_set_auth_key_id
(
D
->
id
,
(
unsigned
char
*
)
D
->
auth_key
);
sha1
((
unsigned
char
*
)
D
->
auth_key
,
256
,
sha1_buffer
);
memcpy
(
tmp
+
33
,
sha1_buffer
,
8
);
sha1
(
tmp
,
41
,
sha1_buffer
);
assert
(
!
memcmp
(
packet
+
56
,
sha1_buffer
+
4
,
16
));
GET_DC
(
c
)
->
server_salt
=
*
(
long
long
*
)
server_nonce
^
*
(
long
long
*
)
new_nonce
;
D
->
server_salt
=
*
(
long
long
*
)
server_nonce
^
*
(
long
long
*
)
new_nonce
;
//kprintf ("OK\n");
...
...
@@ -653,8 +646,8 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
//return 1;
vlogprintf
(
E_DEBUG
,
"Auth success
\n
"
);
auth_success
++
;
GET_DC
(
c
)
->
flags
|=
1
;
write_auth_file
();
D
->
flags
|=
1
;
//
write_auth_file ();
return
1
;
}
...
...
@@ -665,18 +658,18 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
*
*/
struct
encrypted_message
enc_msg
;
st
atic
st
ruct
encrypted_message
enc_msg
;
long
long
client_last_msg_id
,
server_last_msg_id
;
static
long
long
client_last_msg_id
,
server_last_msg_id
;
double
get_server_time
(
struct
dc
*
DC
)
{
static
double
get_server_time
(
struct
dc
*
DC
)
{
if
(
!
DC
->
server_time_udelta
)
{
DC
->
server_time_udelta
=
get_utime
(
CLOCK_REALTIME
)
-
get_utime
(
CLOCK_MONOTONIC
);
}
return
get_utime
(
CLOCK_MONOTONIC
)
+
DC
->
server_time_udelta
;
}
long
long
generate_next_msg_id
(
struct
dc
*
DC
)
{
static
long
long
generate_next_msg_id
(
struct
dc
*
DC
)
{
long
long
next_id
=
(
long
long
)
(
get_server_time
(
DC
)
*
(
1LL
<<
32
))
&
-
4
;
if
(
next_id
<=
client_last_msg_id
)
{
next_id
=
client_last_msg_id
+=
4
;
...
...
@@ -686,14 +679,14 @@ long long generate_next_msg_id (struct dc *DC) {
return
next_id
;
}
void
init_enc_msg
(
struct
session
*
S
,
int
useful
)
{
static
void
init_enc_msg
(
struct
session
*
S
,
int
useful
)
{
struct
dc
*
DC
=
S
->
dc
;
assert
(
DC
->
auth_key_id
);
enc_msg
.
auth_key_id
=
DC
->
auth_key_id
;
// assert (DC->server_salt);
enc_msg
.
server_salt
=
DC
->
server_salt
;
if
(
!
S
->
session_id
)
{
secure_random
(
&
S
->
session_id
,
8
);
tglt_
secure_random
(
&
S
->
session_id
,
8
);
}
enc_msg
.
session_id
=
S
->
session_id
;
//enc_msg.auth_key_id2 = auth_key_id;
...
...
@@ -707,7 +700,7 @@ void init_enc_msg (struct session *S, int useful) {
S
->
seq_no
+=
2
;
};
int
aes_encrypt_message
(
struct
dc
*
DC
,
struct
encrypted_message
*
enc
)
{
static
int
aes_encrypt_message
(
struct
dc
*
DC
,
struct
encrypted_message
*
enc
)
{
unsigned
char
sha1_buffer
[
20
];
const
int
MINSZ
=
offsetof
(
struct
encrypted_message
,
message
);
const
int
UNENCSZ
=
offsetof
(
struct
encrypted_message
,
server_salt
);
...
...
@@ -722,10 +715,11 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
return
pad_aes_encrypt
((
char
*
)
&
enc
->
server_salt
,
enc_len
,
(
char
*
)
&
enc
->
server_salt
,
MAX_MESSAGE_INTS
*
4
+
(
MINSZ
-
UNENCSZ
));
}
long
long
encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
)
{
struct
dc
*
DC
=
GET_DC
(
c
);
struct
session
*
S
=
c
->
session
;
long
long
tglmp_
encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
)
{
struct
dc
*
DC
=
tgl_state
.
net_methods
->
get_dc
(
c
);
struct
session
*
S
=
tgl_state
.
net_methods
->
get_session
(
c
)
;
assert
(
S
);
const
int
UNENCSZ
=
offsetof
(
struct
encrypted_message
,
server_salt
);
if
(
msg_ints
<=
0
||
msg_ints
>
MAX_MESSAGE_INTS
-
4
)
{
return
-
1
;
...
...
@@ -749,723 +743,17 @@ long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, in
return
client_last_msg_id
;
}
int
longpoll_count
,
good_messages
;
int
auth_work_start
(
struct
connection
*
c
UU
)
{
return
1
;
}
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
);
int
unread_messages
;
int
pts
;
int
qts
;
int
last_date
;
int
seq
;
void
fetch_pts
(
void
)
{
int
p
=
fetch_int
();
if
(
p
<=
pts
)
{
return
;
}
if
(
p
!=
pts
+
1
)
{
if
(
pts
)
{
//logprintf ("Hole in pts p = %d, pts = %d\n", p, pts);
// get difference should be here
pts
=
p
;
}
else
{
pts
=
p
;
}
}
else
{
pts
++
;
}
bl_do_set_pts
(
pts
);
}
void
fetch_qts
(
void
)
{
int
p
=
fetch_int
();
if
(
p
<=
qts
)
{
return
;
}
if
(
p
!=
qts
+
1
)
{
if
(
qts
)
{
//logprintf ("Hole in qts\n");
// get difference should be here
qts
=
p
;
}
else
{
qts
=
p
;
}
}
else
{
qts
++
;
}
bl_do_set_qts
(
qts
);
}
void
fetch_date
(
void
)
{
int
p
=
fetch_int
();
if
(
p
>
last_date
)
{
last_date
=
p
;
bl_do_set_date
(
last_date
);
}
}
void
fetch_seq
(
void
)
{
int
x
=
fetch_int
();
if
(
x
>
seq
+
1
)
{
vlogprintf
(
E_NOTICE
,
"Hole in seq: seq = %d, x = %d
\n
"
,
seq
,
x
);
//tgl_do_get_difference ();
//seq = x;
}
else
if
(
x
==
seq
+
1
)
{
seq
=
x
;
bl_do_set_seq
(
seq
);
}
}
/*
void work_update_binlog (void) {
unsigned op = fetch_int ();
switch (op) {
case CODE_update_user_name:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *UC = tgl_peer_get (user_id);
if (UC) {
struct tgl_user *U = &UC->user;
if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) {
tglp_peer_delete_name (UC);
tfree_str (U->print_name);
}
U->first_name = fetch_str_dup ();
U->last_name = fetch_str_dup ();
U->print_name = create_print_name (U->id, U->first_name, U->last_name, 0, 0);
tglp_peer_insert_name ((void *)U);
} else {
fetch_skip_str ();
fetch_skip_str ();
}
}
break;
case CODE_update_user_photo:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *UC = tgl_peer_get (user_id);
fetch_date ();
if (UC) {
struct tgl_user *U = &UC->user;
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
U->photo_id = 0;
U->photo_big.dc = -2;
U->photo_small.dc = -2;
} else {
assert (y == CODE_user_profile_photo);
U->photo_id = fetch_long ();
tglf_fetch_file_location (&U->photo_small);
tglf_fetch_file_location (&U->photo_big);
}
} else {
struct tgl_file_location t;
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
} else {
assert (y == CODE_user_profile_photo);
fetch_long (); // photo_id
tglf_fetch_file_location (&t);
tglf_fetch_file_location (&t);
}
}
fetch_bool ();
}
break;
default:
assert (0);
}
}*/
void
work_update
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
unsigned
op
=
fetch_int
();
switch
(
op
)
{
case
CODE_update_new_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
M
);
fetch_pts
();
tgl_state
.
callback
.
new_msg
(
M
);
//unread_messages ++;
//print_message (M);
//update_prompt ();
break
;
};
case
CODE_update_message_i_d
:
{
int
id
=
fetch_int
();
// id
int
new
=
fetch_long
();
// random_id
struct
tgl_message
*
M
=
tgl_message_get
(
new
);
if
(
M
)
{
bl_do_set_msg_id
(
M
,
id
);
}
}
break
;
case
CODE_update_read_messages
:
{
assert
(
fetch_int
()
==
(
int
)
CODE_vector
);
int
n
=
fetch_int
();
struct
tgl_message
**
ML
=
talloc
(
n
*
sizeof
(
void
*
));
int
p
=
0
;
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
id
=
fetch_int
();
struct
tgl_message
*
M
=
tgl_message_get
(
id
);
if
(
M
)
{
bl_do_set_unread
(
M
,
0
);
ML
[
p
++
]
=
M
;
}
}
fetch_pts
();
tgl_state
.
callback
.
marked_read
(
p
,
ML
);
tfree
(
ML
,
sizeof
(
void
*
)
*
n
);
/*if (log_level >= 1) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" %d messages marked as read\n", n);
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_user_typing
:
{
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
tgl_state
.
callback
.
type_notification
(
id
,
(
void
*
)
U
);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (id, U);
printf (" is typing....\n");
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_chat_user_typing
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
tgl_state
.
callback
.
type_in_chat_notification
(
id
,
(
void
*
)
U
,
chat_id
,
(
void
*
)
C
);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (id, U);
printf (" is typing in chat ");
print_chat_name (chat_id, C);
printf ("....\n");
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_user_status
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
if
(
U
)
{
tglf_fetch_user_status
(
&
U
->
user
.
status
);
tgl_state
.
callback
.
status_notification
((
void
*
)
U
);
/*if (log_level >= 3) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" is now ");
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
pop_color ();
print_end ();
}*/
}
else
{
struct
tgl_user_status
t
;
tglf_fetch_user_status
(
&
t
);
}
}
break
;
case
CODE_update_user_name
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
UC
=
tgl_peer_get
(
user_id
);
if
(
UC
&&
(
UC
->
flags
&
FLAG_CREATED
))
{
int
l1
=
prefetch_strlen
();
char
*
f
=
fetch_str
(
l1
);
int
l2
=
prefetch_strlen
();
char
*
l
=
fetch_str
(
l2
);
struct
tgl_user
*
U
=
&
UC
->
user
;
bl_do_user_set_real_name
(
U
,
f
,
l1
,
l
,
l2
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" changed name to ");
print_user_name (user_id, UC);
printf ("\n");
pop_color ();
print_end ();*/
}
else
{
fetch_skip_str
();
fetch_skip_str
();
}
}
break
;
case
CODE_update_user_photo
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
UC
=
tgl_peer_get
(
user_id
);
fetch_date
();
if
(
UC
&&
(
UC
->
flags
&
FLAG_CREATED
))
{
struct
tgl_user
*
U
=
&
UC
->
user
;
unsigned
y
=
fetch_int
();
long
long
photo_id
;
struct
tgl_file_location
big
;
struct
tgl_file_location
small
;
memset
(
&
big
,
0
,
sizeof
(
big
));
memset
(
&
small
,
0
,
sizeof
(
small
));
if
(
y
==
CODE_user_profile_photo_empty
)
{
photo_id
=
0
;
big
.
dc
=
-
2
;
small
.
dc
=
-
2
;
}
else
{
assert
(
y
==
CODE_user_profile_photo
);
photo_id
=
fetch_long
();
tglf_fetch_file_location
(
&
small
);
tglf_fetch_file_location
(
&
big
);
}
bl_do_set_user_profile_photo
(
U
,
photo_id
,
&
big
,
&
small
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" updated profile photo\n");
pop_color ();
print_end ();*/
}
else
{
struct
tgl_file_location
t
;
unsigned
y
=
fetch_int
();
if
(
y
==
CODE_user_profile_photo_empty
)
{
}
else
{
assert
(
y
==
CODE_user_profile_photo
);
fetch_long
();
// photo_id
tglf_fetch_file_location
(
&
t
);
tglf_fetch_file_location
(
&
t
);
}
}
fetch_bool
();
}
break
;
case
CODE_update_restore_messages
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Restored %d messages\n", n);
pop_color ();
print_end ();*/
fetch_skip
(
n
);
fetch_pts
();
}
break
;
case
CODE_update_delete_messages
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Deleted %d messages\n", n);
pop_color ();
print_end ();*/
fetch_skip
(
n
);
fetch_pts
();
}
break
;
case
CODE_update_chat_participants
:
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_chat_participants
||
x
==
CODE_chat_participants_forbidden
);
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
int
n
=
0
;
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
if
(
x
==
CODE_chat_participants
)
{
bl_do_chat_set_admin
(
&
C
->
chat
,
fetch_int
());
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
struct
tgl_chat_user
*
users
=
talloc
(
12
*
n
);
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_chat_participant
);
users
[
i
].
user_id
=
fetch_int
();
users
[
i
].
inviter_id
=
fetch_int
();
users
[
i
].
date
=
fetch_int
();
}
int
version
=
fetch_int
();
bl_do_chat_set_participants
(
&
C
->
chat
,
version
,
n
,
users
);
}
}
else
{
if
(
x
==
CODE_chat_participants
)
{
fetch_int
();
// admin_id
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
fetch_skip
(
n
*
4
);
fetch_int
();
// version
}
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
print_chat_name (chat_id, C);
if (x == CODE_chat_participants) {
printf (" changed list: now %d members\n", n);
} else {
printf (" changed list, but we are forbidden to know about it (Why this update even was sent to us?\n");
}
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_contact_registered
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
fetch_int
();
// date
tgl_state
.
callback
.
user_registered
(
U
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" registered\n");
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_contact_link
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Updated link with user ");
print_user_name (user_id, U);
printf ("\n");
pop_color ();
print_end ();*/
unsigned
t
=
fetch_int
();
assert
(
t
==
CODE_contacts_my_link_empty
||
t
==
CODE_contacts_my_link_requested
||
t
==
CODE_contacts_my_link_contact
);
if
(
t
==
CODE_contacts_my_link_requested
)
{
fetch_bool
();
// has_phone
}
t
=
fetch_int
();
assert
(
t
==
CODE_contacts_foreign_link_unknown
||
t
==
CODE_contacts_foreign_link_requested
||
t
==
CODE_contacts_foreign_link_mutual
);
if
(
t
==
CODE_contacts_foreign_link_requested
)
{
fetch_bool
();
// has_phone
}
}
break
;
case
CODE_update_activation
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
printf
(
" User "
);
print_user_name
(
user_id
,
U
);
printf
(
" activated
\n
"
);
pop_color
();
print_end
();
}
break
;
case
CODE_update_new_authorization
:
{
fetch_long
();
// auth_key_id
fetch_int
();
// date
char
*
s
=
fetch_str_dup
();
char
*
location
=
fetch_str_dup
();
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
printf
(
" New autorization: device='%s' location='%s'
\n
"
,
s
,
location
);
pop_color
();
print_end
();
tfree_str
(
s
);
tfree_str
(
location
);
}
break
;
case
CODE_update_new_geo_chat_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_geo_message
();
unread_messages
++
;
print_message
(
M
);
update_prompt
();
}
break
;
case
CODE_update_new_encrypted_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_encrypted_message
();
unread_messages
++
;
print_message
(
M
);
update_prompt
();
fetch_qts
();
}
break
;
case
CODE_update_encryption
:
{
struct
tgl_secret_chat
*
E
=
tglf_fetch_alloc_encrypted_chat
();
vlogprintf
(
E_DEBUG
,
"Secret chat state = %d
\n
"
,
E
->
state
);
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
switch
(
E
->
state
)
{
case
sc_none
:
break
;
case
sc_waiting
:
printf
(
" Encrypted chat "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" is now in wait state
\n
"
);
break
;
case
sc_request
:
printf
(
" Encrypted chat "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" is now in request state. Sending request ok
\n
"
);
break
;
case
sc_ok
:
printf
(
" Encrypted chat "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" is now in ok state
\n
"
);
break
;
case
sc_deleted
:
printf
(
" Encrypted chat "
);
print_encr_chat_name
(
E
->
id
,
(
void
*
)
E
);
printf
(
" is now in deleted state
\n
"
);
break
;
}
pop_color
();
print_end
();
if
(
E
->
state
==
sc_request
&&
!
disable_auto_accept
)
{
tgl_do_accept_encr_chat_request
(
E
);
}
if
(
E
->
state
==
sc_ok
)
{
tgl_do_send_encr_chat_layer
(
E
);
}
fetch_int
();
// date
}
break
;
case
CODE_update_encrypted_chat_typing
:
{
tgl_peer_id_t
id
=
TGL_MK_ENCR_CHAT
(
fetch_int
());
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
if
(
P
)
{
printf
(
" User "
);
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
P
->
encr_chat
.
user_id
);
print_user_name
(
user_id
,
tgl_peer_get
(
user_id
));
printf
(
" typing in secret chat "
);
print_encr_chat_name
(
id
,
P
);
printf
(
"
\n
"
);
}
else
{
printf
(
" Some user is typing in unknown secret chat
\n
"
);
}
pop_color
();
print_end
();
}
break
;
case
CODE_update_encrypted_messages_read
:
{
tgl_peer_id_t
id
=
TGL_MK_ENCR_CHAT
(
fetch_int
());
// chat_id
fetch_int
();
// max_date
fetch_int
();
// date
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
int
x
=
-
1
;
if
(
P
&&
P
->
last
)
{
x
=
0
;
struct
tgl_message
*
M
=
P
->
last
;
while
(
M
&&
(
!
M
->
out
||
M
->
unread
))
{
if
(
M
->
out
)
{
M
->
unread
=
0
;
x
++
;
}
M
=
M
->
next
;
}
}
if
(
log_level
>=
1
)
{
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
printf
(
" Encrypted chat "
);
print_encr_chat_name_full
(
id
,
tgl_peer_get
(
id
));
printf
(
": %d messages marked read
\n
"
,
x
);
pop_color
();
print_end
();
}
}
break
;
case
CODE_update_chat_participant_add
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_id_t
inviter_id
=
TGL_MK_USER
(
fetch_int
());
int
version
=
fetch_int
();
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
bl_do_chat_add_user
(
&
C
->
chat
,
version
,
tgl_get_peer_id
(
user_id
),
tgl_get_peer_id
(
inviter_id
),
time
(
0
));
}
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
printf
(
" Chat "
);
print_chat_name
(
chat_id
,
tgl_peer_get
(
chat_id
));
printf
(
": user "
);
print_user_name
(
user_id
,
tgl_peer_get
(
user_id
));
printf
(
" added by user "
);
print_user_name
(
inviter_id
,
tgl_peer_get
(
inviter_id
));
printf
(
"
\n
"
);
pop_color
();
print_end
();
}
break
;
case
CODE_update_chat_participant_delete
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
int
version
=
fetch_int
();
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
bl_do_chat_del_user
(
&
C
->
chat
,
version
,
tgl_get_peer_id
(
user_id
));
}
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
printf
(
" Chat "
);
print_chat_name
(
chat_id
,
tgl_peer_get
(
chat_id
));
printf
(
": user "
);
print_user_name
(
user_id
,
tgl_peer_get
(
user_id
));
printf
(
" deleted
\n
"
);
pop_color
();
print_end
();
}
break
;
case
CODE_update_dc_options
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
assert
(
n
>=
0
);
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_dc_option
();
}
}
break
;
case
CODE_update_user_blocked
:
{
int
id
=
fetch_int
();
int
blocked
=
fetch_bool
();
tgl_peer_t
*
P
=
tgl_peer_get
(
TGL_MK_USER
(
id
));
if
(
P
&&
(
P
->
flags
&
FLAG_CREATED
))
{
bl_do_user_set_blocked
(
&
P
->
user
,
blocked
);
}
}
break
;
case
CODE_update_notify_settings
:
{
assert
(
skip_type_any
(
TYPE_TO_PARAM
(
notify_peer
))
>=
0
);
assert
(
skip_type_any
(
TYPE_TO_PARAM
(
peer_notify_settings
))
>=
0
);
}
break
;
default:
vlogprintf
(
E_ERROR
,
"Unknown update type %08x
\n
"
,
op
);
;
}
}
void
work_update_short
(
struct
connection
*
c
,
long
long
msg_id
)
{
assert
(
fetch_int
()
==
CODE_update_short
);
work_update
(
c
,
msg_id
);
fetch_date
();
}
static
int
good_messages
;
void
work_updates
(
struct
connection
*
c
,
long
long
msg_id
)
{
int
*
save
=
in_ptr
;
assert
(
!
skip_type_any
(
TYPE_TO_PARAM
(
updates
)));
int
*
save_end
=
in_ptr
;
in_ptr
=
save
;
assert
(
fetch_int
()
==
CODE_updates
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
work_update
(
c
,
msg_id
);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_chat
();
}
bl_do_set_date
(
fetch_int
());
bl_do_set_seq
(
fetch_int
());
assert
(
save_end
==
in_ptr
);
}
static
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
);
void
work_update_short_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_update_short_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message_short
();
unread_messages
++
;
print_message
(
M
);
update_prompt
();
if
(
M
->
date
>
last_date
)
{
last_date
=
M
->
date
;
}
}
//int unread_messages;
//int pts;
//int qts;
//int last_date;
//int seq;
void
work_update_short_chat_message
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
CODE_update_short_chat_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message_short_chat
();
unread_messages
++
;
print_message
(
M
);
update_prompt
();
if
(
M
->
date
>
last_date
)
{
last_date
=
M
->
date
;
}
}
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
static
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
vlogprintf
(
E_DEBUG
,
"work_container: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
CODE_msg_container
);
int
n
=
fetch_int
();
...
...
@@ -1475,7 +763,7 @@ void work_container (struct connection *c, long long msg_id UU) {
//int seqno = fetch_int ();
fetch_int
();
// seq_no
if
(
id
&
1
)
{
insert_msg_id
(
c
->
session
,
id
);
tgln_insert_msg_id
(
tgl_state
.
net_methods
->
get_session
(
c
)
,
id
);
}
int
bytes
=
fetch_int
();
int
*
t
=
in_end
;
...
...
@@ -1486,17 +774,17 @@ void work_container (struct connection *c, long long msg_id UU) {
}
}
void
work_new_session_created
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
static
void
work_new_session_created
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
vlogprintf
(
E_DEBUG
,
"work_new_session_created: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
(
int
)
CODE_new_session_created
);
fetch_long
();
// first message id
//DC->session_id = fetch_long ();
fetch_long
();
// unique_id
GET_DC
(
c
)
->
server_salt
=
fetch_long
();
tgl_state
.
net_methods
->
get_dc
(
c
)
->
server_salt
=
fetch_long
();
}
void
work_msgs_ack
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_msgs_ack
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
vlogprintf
(
E_DEBUG
,
"work_msgs_ack: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
CODE_msgs_ack
);
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -1505,24 +793,24 @@ void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
long
long
id
=
fetch_long
();
vlogprintf
(
E_DEBUG
+
1
,
"ack for %lld
\n
"
,
id
);
query_ack
(
id
);
tglq_
query_ack
(
id
);
}
}
void
work_rpc_result
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_rpc_result
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
vlogprintf
(
E_DEBUG
,
"work_rpc_result: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
(
int
)
CODE_rpc_result
);
long
long
id
=
fetch_long
();
int
op
=
prefetch_int
();
if
(
op
==
CODE_rpc_error
)
{
query_error
(
id
);
tglq_
query_error
(
id
);
}
else
{
query_result
(
id
);
tglq_
query_result
(
id
);
}
}
#define MAX_PACKED_SIZE (1 << 24)
void
work_packed
(
struct
connection
*
c
,
long
long
msg_id
)
{
static
void
work_packed
(
struct
connection
*
c
,
long
long
msg_id
)
{
assert
(
fetch_int
()
==
CODE_gzip_packed
);
static
int
in_gzip
;
static
int
buf
[
MAX_PACKED_SIZE
>>
2
];
...
...
@@ -1544,23 +832,23 @@ void work_packed (struct connection *c, long long msg_id) {
in_gzip
=
0
;
}
void
work_bad_server_salt
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_bad_server_salt
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_bad_server_salt
);
long
long
id
=
fetch_long
();
query_restart
(
id
);
tglq_
query_restart
(
id
);
fetch_int
();
// seq_no
fetch_int
();
// error_code
long
long
new_server_salt
=
fetch_long
();
GET_DC
(
c
)
->
server_salt
=
new_server_salt
;
tgl_state
.
net_methods
->
get_dc
(
c
)
->
server_salt
=
new_server_salt
;
}
void
work_pong
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_pong
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
CODE_pong
);
fetch_long
();
// msg_id
fetch_long
();
// ping_id
}
void
work_detailed_info
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_detailed_info
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
CODE_msg_detailed_info
);
fetch_long
();
// msg_id
fetch_long
();
// answer_msg_id
...
...
@@ -1568,20 +856,14 @@ void work_detailed_info (struct connection *c UU, long long msg_id UU) {
fetch_int
();
// status
}
void
work_new_detailed_info
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_new_detailed_info
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_msg_new_detailed_info
);
fetch_long
();
// answer_msg_id
fetch_int
();
// bytes
fetch_int
();
// status
}
void
work_updates_to_long
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_too_long
);
vlogprintf
(
E_NOTICE
,
"updates to long... Getting difference
\n
"
);
tgl_do_get_difference
();
}
void
work_bad_msg_notification
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
static
void
work_bad_msg_notification
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_bad_msg_notification
);
long
long
m1
=
fetch_long
();
int
s
=
fetch_int
();
...
...
@@ -1589,7 +871,7 @@ void work_bad_msg_notification (struct connection *c UU, long long msg_id UU) {
vlogprintf
(
E_NOTICE
,
"bad_msg_notification: msg_id = %lld, seq = %d, error = %d
\n
"
,
m1
,
s
,
e
);
}
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
static
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
int
op
=
prefetch_int
();
switch
(
op
)
{
case
CODE_msg_container
:
...
...
@@ -1605,16 +887,16 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
work_rpc_result
(
c
,
msg_id
);
return
;
case
CODE_update_short
:
work_update_short
(
c
,
msg_id
);
tglu_
work_update_short
(
c
,
msg_id
);
return
;
case
CODE_updates
:
work_updates
(
c
,
msg_id
);
tglu_
work_updates
(
c
,
msg_id
);
return
;
case
CODE_update_short_message
:
work_update_short_message
(
c
,
msg_id
);
tglu_
work_update_short_message
(
c
,
msg_id
);
return
;
case
CODE_update_short_chat_message
:
work_update_short_chat_message
(
c
,
msg_id
);
tglu_
work_update_short_chat_message
(
c
,
msg_id
);
return
;
case
CODE_gzip_packed
:
work_packed
(
c
,
msg_id
);
...
...
@@ -1632,7 +914,7 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
work_new_detailed_info
(
c
,
msg_id
);
return
;
case
CODE_updates_too_long
:
work_updates_to_long
(
c
,
msg_id
);
tglu_
work_updates_to_long
(
c
,
msg_id
);
return
;
case
CODE_bad_msg_notification
:
work_bad_msg_notification
(
c
,
msg_id
);
...
...
@@ -1642,12 +924,12 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
in_ptr
=
in_end
;
// Will not fail due to assertion in_ptr == in_end
}
int
process_rpc_message
(
struct
connection
*
c
UU
,
struct
encrypted_message
*
enc
,
int
len
)
{
static
int
process_rpc_message
(
struct
connection
*
c
UU
,
struct
encrypted_message
*
enc
,
int
len
)
{
const
int
MINSZ
=
offsetof
(
struct
encrypted_message
,
message
);
const
int
UNENCSZ
=
offsetof
(
struct
encrypted_message
,
server_salt
);
vlogprintf
(
E_DEBUG
,
"process_rpc_message(), len=%d
\n
"
,
len
);
assert
(
len
>=
MINSZ
&&
(
len
&
15
)
==
(
UNENCSZ
&
15
));
struct
dc
*
DC
=
GET_DC
(
c
);
struct
dc
*
DC
=
tgl_state
.
net_methods
->
get_dc
(
c
);
assert
(
enc
->
auth_key_id
==
DC
->
auth_key_id
);
assert
(
DC
->
auth_key_id
);
init_aes_auth
(
DC
->
auth_key
+
8
,
enc
->
msg_key
,
AES_DECRYPT
);
...
...
@@ -1661,7 +943,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
//assert (enc->server_salt == server_salt); //in fact server salt can change
if
(
DC
->
server_salt
!=
enc
->
server_salt
)
{
DC
->
server_salt
=
enc
->
server_salt
;
write_auth_file
();
//
write_auth_file ();
}
int
this_server_time
=
enc
->
msg_id
>>
32LL
;
...
...
@@ -1678,10 +960,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
assert
(
this_server_time
>=
st
-
300
&&
this_server_time
<=
st
+
30
);
//assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1);
if
(
verbosity
>=
1
)
{
logprintf
(
"received mesage id %016llx
\n
"
,
enc
->
msg_id
);
hexdump_in
();
}
vlogprintf
(
E_DEBUG
,
"received mesage id %016llx
\n
"
,
enc
->
msg_id
);
server_last_msg_id
=
enc
->
msg_id
;
//*(long long *)(longpoll_query + 3) = *(long long *)((char *)(&enc->msg_id) + 0x3c);
...
...
@@ -1694,77 +973,72 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
in_ptr
=
enc
->
message
;
in_end
=
in_ptr
+
(
enc
->
msg_len
/
4
);
struct
session
*
S
=
tgl_state
.
net_methods
->
get_session
(
c
);
if
(
enc
->
msg_id
&
1
)
{
insert_msg_id
(
c
->
session
,
enc
->
msg_id
);
tgln_insert_msg_id
(
S
,
enc
->
msg_id
);
}
assert
(
c
->
session
->
session_id
==
enc
->
session_id
);
assert
(
S
->
session_id
==
enc
->
session_id
);
rpc_execute_answer
(
c
,
enc
->
msg_id
);
assert
(
in_ptr
==
in_end
);
return
0
;
}
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
)
{
if
(
verbosity
)
{
logprintf
(
"outbound rpc connection #%d : received rpc answer %d with %d content bytes
\n
"
,
c
->
fd
,
op
,
len
);
}
static
int
rpc_execute
(
struct
connection
*
c
,
int
op
,
int
len
)
{
vlogprintf
(
E_DEBUG
,
"outbound rpc connection from dc #%d : received rpc answer %d with %d content bytes
\n
"
,
tgl_state
.
net_methods
->
get_dc
(
c
)
->
id
,
op
,
len
);
/* if (op < 0) {
assert (read_in (c, Response, Response_len) == Response_len);
assert (
tgl_state.net_methods->
read_in (c, Response, Response_len) == Response_len);
return 0;
}*/
if
(
len
>=
MAX_RESPONSE_SIZE
/* - 12*/
||
len
<
0
/*12*/
)
{
logprintf
(
"answer too long (%d bytes), skipping
\n
"
,
len
);
vlogprintf
(
E_WARNING
,
"answer too long (%d bytes), skipping
\n
"
,
len
);
return
0
;
}
int
Response_len
=
len
;
if
(
verbosity
>=
2
)
{
logprintf
(
"Response_len = %d
\n
"
,
Response_len
);
}
assert
(
read_in
(
c
,
Response
,
Response_len
)
==
Response_len
);
vlogprintf
(
E_DEBUG
,
"Response_len = %d
\n
"
,
Response_len
);
assert
(
tgl_state
.
net_methods
->
read_in
(
c
,
Response
,
Response_len
)
==
Response_len
);
Response
[
Response_len
]
=
0
;
if
(
verbosity
>=
2
)
{
logprintf
(
"have %d Response bytes
\n
"
,
Response_len
);
}
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
int
o
=
c_state
;
if
(
GET_DC
(
c
)
->
flags
&
1
)
{
o
=
st_authorized
;}
struct
dc
*
D
=
tgl_state
.
net_methods
->
get_dc
(
c
);
int
o
=
D
->
state
;
if
(
D
->
flags
&
1
)
{
o
=
st_authorized
;}
switch
(
o
)
{
case
st_reqpq_sent
:
process_respq_answer
(
c
,
Response
/* + 8*/
,
Response_len
/* - 12*/
);
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
return
0
;
case
st_reqdh_sent
:
process_dh_answer
(
c
,
Response
/* + 8*/
,
Response_len
/* - 12*/
);
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
return
0
;
case
st_client_dh_sent
:
process_auth_complete
(
c
,
Response
/* + 8*/
,
Response_len
/* - 12*/
);
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
return
0
;
case
st_authorized
:
if
(
op
<
0
&&
op
>=
-
999
)
{
logprintf
(
"Server error %d
\n
"
,
op
);
vlogprintf
(
E_WARNING
,
"Server error %d
\n
"
,
op
);
}
else
{
process_rpc_message
(
c
,
(
void
*
)(
Response
/* + 8*/
),
Response_len
/* - 12*/
);
}
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
return
0
;
default:
logprintf
(
"fatal: cannot receive answer in state %d
\n
"
,
c_state
);
vlogprintf
(
E_ERROR
,
"fatal: cannot receive answer in state %d
\n
"
,
c_state
);
exit
(
2
);
}
...
...
@@ -1772,60 +1046,50 @@ int rpc_execute (struct connection *c, int op, int len) {
}
int
tc_close
(
struct
connection
*
c
,
int
who
)
{
if
(
verbosity
)
{
logprintf
(
"outbound http connection #%d : closing by %d
\n
"
,
c
->
fd
,
who
);
}
static
int
tc_close
(
struct
connection
*
c
,
int
who
)
{
vlogprintf
(
E_DEBUG
,
"outbound rpc connection from dc #%d : closing by %d
\n
"
,
tgl_state
.
net_methods
->
get_dc
(
c
)
->
id
,
who
);
return
0
;
}
int
tc_becomes_ready
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
logprintf
(
"outbound connection #%d becomes ready
\n
"
,
c
->
fd
);
}
static
int
tc_becomes_ready
(
struct
connection
*
c
)
{
vlogprintf
(
E_DEBUG
,
"outbound rpc connection from dc #%d becomed ready
\n
"
,
tgl_state
.
net_methods
->
get_dc
(
c
)
->
id
);
char
byte
=
0xef
;
assert
(
write_out
(
c
,
&
byte
,
1
)
==
1
);
flush_out
(
c
);
assert
(
tgl_state
.
net_methods
->
write_out
(
c
,
&
byte
,
1
)
==
1
);
tgl_state
.
net_methods
->
flush_out
(
c
);
#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__)
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_QUICKACK
,
(
int
[]){
0
},
4
);
//
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
#endif
int
o
=
c_state
;
if
(
GET_DC
(
c
)
->
flags
&
1
)
{
o
=
st_authorized
;
}
struct
dc
*
D
=
tgl_state
.
net_methods
->
get_dc
(
c
);
int
o
=
D
->
state
;
if
(
D
->
flags
&
1
)
{
o
=
st_authorized
;
}
switch
(
o
)
{
case
st_init
:
send_req_pq_packet
(
c
);
break
;
case
st_authorized
:
auth_work_start
(
c
);
break
;
default:
logprintf
(
"c_state = %d
\n
"
,
c_state
);
vlogprintf
(
E_DEBUG
,
"c_state = %d
\n
"
,
c_state
);
assert
(
0
);
}
return
0
;
}
int
rpc_becomes_ready
(
struct
connection
*
c
)
{
static
int
rpc_becomes_ready
(
struct
connection
*
c
)
{
return
tc_becomes_ready
(
c
);
}
int
rpc_close
(
struct
connection
*
c
)
{
static
int
rpc_close
(
struct
connection
*
c
)
{
return
tc_close
(
c
,
0
);
}
int
auth_is_success
(
void
)
{
return
auth_success
;
}
#define RANDSEED_PASSWORD_FILENAME NULL
#define RANDSEED_PASSWORD_LENGTH 0
void
on_start
(
void
)
{
void
tglmp_on_start
(
const
char
*
key
)
{
prng_seed
(
RANDSEED_PASSWORD_FILENAME
,
RANDSEED_PASSWORD_LENGTH
);
if
(
rsa_public_key_name
)
{
if
(
rsa_load_public_key
(
rsa_public_key_name
)
<
0
)
{
if
(
key
)
{
if
(
rsa_load_public_key
(
key
)
<
0
)
{
perror
(
"rsa_load_public_key"
);
exit
(
1
);
}
...
...
@@ -1839,18 +1103,87 @@ void on_start (void) {
pk_fingerprint
=
compute_rsa_key_fingerprint
(
pubKey
);
}
int
auth_ok
(
void
)
{
return
auth_success
;
}
//
int auth_ok (void) {
//
return auth_success;
//
}
void
dc_authorize
(
struct
dc
*
DC
)
{
c_state
=
0
;
auth_success
=
0
;
void
tgl_
dc_authorize
(
struct
dc
*
DC
)
{
//
c_state = 0;
//
auth_success = 0;
if
(
!
DC
->
sessions
[
0
])
{
dc_create_session
(
DC
);
tglmp_
dc_create_session
(
DC
);
}
if
(
verbosity
)
{
logprintf
(
"Starting authorization for DC #%d: %s:%d
\n
"
,
DC
->
id
,
DC
->
ip
,
DC
->
port
);
vlogprintf
(
E_DEBUG
,
"Starting authorization for DC #%d: %s:%d
\n
"
,
DC
->
id
,
DC
->
ip
,
DC
->
port
);
//net_loop (0, auth_ok);
}
#define long_cmp(a,b) ((a) > (b) ? 1 : (a) == (b) ? 0 : -1)
DEFINE_TREE
(
long
,
long
long
,
long_cmp
,
0
)
static
int
send_all_acks
(
struct
session
*
S
)
{
clear_packet
();
out_int
(
CODE_msgs_ack
);
out_int
(
CODE_vector
);
out_int
(
tree_count_long
(
S
->
ack_tree
));
while
(
S
->
ack_tree
)
{
long
long
x
=
tree_get_min_long
(
S
->
ack_tree
);
out_long
(
x
);
S
->
ack_tree
=
tree_delete_long
(
S
->
ack_tree
,
x
);
}
net_loop
(
0
,
auth_ok
);
tglmp_encrypt_send_message
(
S
->
c
,
packet_buffer
,
packet_ptr
-
packet_buffer
,
0
);
return
0
;
}
static
void
send_all_acks_gateway
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
send_all_acks
(
arg
);
}
void
tgln_insert_msg_id
(
struct
session
*
S
,
long
long
id
)
{
if
(
!
S
->
ack_tree
)
{
static
struct
timeval
ptimeout
=
{
ACK_TIMEOUT
,
0
};
event_add
(
S
->
ev
,
&
ptimeout
);
}
if
(
!
tree_lookup_long
(
S
->
ack_tree
,
id
))
{
S
->
ack_tree
=
tree_insert_long
(
S
->
ack_tree
,
id
,
lrand48
());
}
}
//extern struct dc *DC_list[];
struct
dc
*
tglmp_alloc_dc
(
int
id
,
char
*
ip
,
int
port
UU
)
{
assert
(
!
tgl_state
.
DC_list
[
id
]);
struct
dc
*
DC
=
talloc0
(
sizeof
(
*
DC
));
DC
->
id
=
id
;
DC
->
ip
=
ip
;
DC
->
port
=
port
;
tgl_state
.
DC_list
[
id
]
=
DC
;
return
DC
;
}
static
struct
mtproto_methods
mtproto_methods
=
{
.
execute
=
rpc_execute
,
.
ready
=
rpc_becomes_ready
,
.
close
=
rpc_close
};
void
tglmp_dc_create_session
(
struct
dc
*
DC
)
{
struct
session
*
S
=
talloc0
(
sizeof
(
*
S
));
assert
(
RAND_pseudo_bytes
((
unsigned
char
*
)
&
S
->
session_id
,
8
)
>=
0
);
S
->
dc
=
DC
;
S
->
c
=
tgl_state
.
net_methods
->
create_connection
(
DC
->
ip
,
DC
->
port
,
DC
,
S
,
&
mtproto_methods
);
if
(
!
S
->
c
)
{
vlogprintf
(
E_DEBUG
,
"Can not create connection to DC. Is network down?
\n
"
);
exit
(
1
);
}
S
->
ev
=
evtimer_new
(
tgl_state
.
ev_base
,
send_all_acks_gateway
,
S
);
assert
(
!
DC
->
sessions
[
0
]);
DC
->
sessions
[
0
]
=
S
;
}
void
tgl_do_send_ping
(
struct
connection
*
c
)
{
int
x
[
3
];
x
[
0
]
=
CODE_ping
;
*
(
long
long
*
)(
x
+
1
)
=
lrand48
()
*
(
1ll
<<
32
)
+
lrand48
();
tglmp_encrypt_send_message
(
c
,
x
,
3
,
0
);
}
mtproto-client.h
View file @
b12ca538
...
...
@@ -19,15 +19,76 @@
*/
#ifndef __MTPROTO_CLIENT_H__
#define __MTPROTO_CLIENT_H__
#include "net.h"
//
#include "net.h"
#include <openssl/bn.h>
void
on_start
(
void
);
long
long
encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
);
void
dc_authorize
(
struct
dc
*
DC
);
void
work_update
(
struct
connection
*
c
,
long
long
msg_id
);
void
work_update_binlog
(
void
);
int
check_g
(
unsigned
char
p
[
256
],
BIGNUM
*
g
);
int
check_g_bn
(
BIGNUM
*
p
,
BIGNUM
*
g
);
int
check_DH_params
(
BIGNUM
*
p
,
int
g
);
void
secure_random
(
void
*
s
,
int
l
);
//void on_start (void);
//..long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
//void dc_authorize (struct dc *DC);
//void work_update (struct connection *c, long long msg_id);
//void work_update_binlog (void);
//int check_g (unsigned char p[256], BIGNUM *g);
//int check_g_bn (BIGNUM *p, BIGNUM *g);
//int check_DH_params (BIGNUM *p, int g);
//void secure_random (void *s, int l);
struct
connection
;
struct
dc
;
//#include "queries.h"
#define TG_SERVER "173.240.5.1"
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
struct
connection
;
enum
dc_state
{
st_init
,
st_reqpq_sent
,
st_reqdh_sent
,
st_client_dh_sent
,
st_authorized
,
st_error
};
#define MAX_DC_SESSIONS 3
struct
session
{
struct
dc
*
dc
;
long
long
session_id
;
int
seq_no
;
struct
connection
*
c
;
struct
tree_long
*
ack_tree
;
struct
event
*
ev
;
//struct event_timer ev;
};
struct
dc
{
int
id
;
int
port
;
int
flags
;
enum
dc_state
state
;
char
*
ip
;
char
*
user
;
struct
session
*
sessions
[
MAX_DC_SESSIONS
];
char
auth_key
[
256
];
long
long
auth_key_id
;
long
long
server_salt
;
int
server_time_delta
;
double
server_time_udelta
;
int
has_auth
;
};
long
long
tglmp_encrypt_send_message
(
struct
connection
*
c
,
int
*
msg
,
int
msg_ints
,
int
useful
);
void
tglmp_dc_create_session
(
struct
dc
*
DC
);
int
tglmp_check_g
(
unsigned
char
p
[
256
],
BIGNUM
*
g
);
int
tglmp_check_DH_params
(
BIGNUM
*
p
,
int
g
);
struct
dc
*
tglmp_alloc_dc
(
int
id
,
char
*
ip
,
int
port
);
void
tgln_insert_msg_id
(
struct
session
*
S
,
long
long
id
);
void
tglmp_on_start
(
const
char
*
key
);
void
tgl_dc_authorize
(
struct
dc
*
DC
);
#endif
mtproto-common.c
View file @
b12ca538
...
...
@@ -53,9 +53,9 @@ int *packet_buffer = __packet_buffer + 16;
long
long
rsa_encrypted_chunks
,
rsa_decrypted_chunks
;
BN_CTX
*
BN_ctx
;
int
verbosity
;
//
int verbosity;
int
get_random_bytes
(
unsigned
char
*
buf
,
int
n
)
{
static
int
get_random_bytes
(
unsigned
char
*
buf
,
int
n
)
{
int
r
=
0
,
h
=
open
(
"/dev/random"
,
O_RDONLY
|
O_NONBLOCK
);
if
(
h
>=
0
)
{
r
=
read
(
h
,
buf
,
n
);
...
...
@@ -87,20 +87,6 @@ int get_random_bytes (unsigned char *buf, int n) {
return
r
;
}
void
my_clock_gettime
(
int
clock_id
UU
,
struct
timespec
*
T
)
{
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back too often
clock_serv_t
cclock
;
mach_timespec_t
mts
;
host_get_clock_service
(
mach_host_self
(),
CALENDAR_CLOCK
,
&
cclock
);
clock_get_time
(
cclock
,
&
mts
);
mach_port_deallocate
(
mach_task_self
(),
cclock
);
T
->
tv_sec
=
mts
.
tv_sec
;
T
->
tv_nsec
=
mts
.
tv_nsec
;
#else
assert
(
clock_gettime
(
clock_id
,
T
)
>=
0
);
#endif
}
/* RDTSC */
#if defined(__i386__)
...
...
mtproto-common.h
View file @
b12ca538
...
...
@@ -25,12 +25,14 @@
#include <openssl/bn.h>
#include <openssl/aes.h>
#include <stdio.h>
#include <assert.h>
//#include "interface.h"
#include "tools.h"
#include "auto/constants.h"
#include "tgl.h"
#include "tgl-inner.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
...
...
@@ -157,10 +159,10 @@ static inline void out_bignum (BIGNUM *n) {
extern
int
*
in_ptr
,
*
in_end
;
void
fetch_pts
(
void
);
void
fetch_qts
(
void
);
void
fetch_date
(
void
);
void
fetch_seq
(
void
);
//
void fetch_pts (void);
//
void fetch_qts (void);
//
void fetch_date (void);
//
void fetch_seq (void);
static
inline
int
prefetch_strlen
(
void
)
{
if
(
in_ptr
>=
in_end
)
{
return
-
1
;
...
...
@@ -331,7 +333,7 @@ static inline void fetch256 (void *buf) {
}
}
int
get_random_bytes
(
unsigned
char
*
buf
,
int
n
);
//
int get_random_bytes (unsigned char *buf, int n);
int
pad_rsa_encrypt
(
char
*
from
,
int
from_len
,
char
*
to
,
int
size
,
BIGNUM
*
N
,
BIGNUM
*
E
);
int
pad_rsa_decrypt
(
char
*
from
,
int
from_len
,
char
*
to
,
int
size
,
BIGNUM
*
N
,
BIGNUM
*
D
);
...
...
net.c
View file @
b12ca538
...
...
@@ -37,81 +37,73 @@
#include <poll.h>
#include <openssl/rand.h>
#include <arpa/inet.h>
#include <event2/event.h>
#include <sys/time.h>
#include <time.h>
#include "net.h"
#include "include.h"
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "tgl.h"
#include "tgl-inner.h"
//#include "mtproto-client.h"
//#include "mtproto-common.h"
#include "tree.h"
#include "interface.h"
#ifndef POLLRDHUP
#define POLLRDHUP 0
#endif
#define long_cmp(a,b) ((a) > (b) ? 1 : (a) == (b) ? 0 : -1)
DEFINE_TREE
(
long
,
long
long
,
long_cmp
,
0
)
double
get_utime
(
int
clock_id
);
//double get_utime (int clock_id);
int
verbosity
;
extern
struct
connection_methods
auth_methods
;
extern
FILE
*
log_net_f
;
//extern struct mtproto_methods auth_methods;
void
fail_connection
(
struct
connection
*
c
);
static
void
fail_connection
(
struct
connection
*
c
);
#define PING_TIMEOUT 10
void
start_ping_timer
(
struct
connection
*
c
);
int
ping_alarm
(
struct
connection
*
c
)
{
if
(
verbosity
>
2
)
{
logprintf
(
"ping alarm
\n
"
);
}
static
void
start_ping_timer
(
struct
connection
*
c
);
static
void
ping_alarm
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
struct
connection
*
c
=
arg
;
vlogprintf
(
E_DEBUG
+
2
,
"ping alarm
\n
"
);
assert
(
c
->
state
==
conn_ready
||
c
->
state
==
conn_connecting
);
if
(
get_double_time
()
-
c
->
last_receive_time
>
20
*
PING_TIMEOUT
)
{
if
(
verbosity
)
{
logprintf
(
"fail connection: reason: ping timeout
\n
"
);
}
vlogprintf
(
E_WARNING
,
"fail connection: reason: ping timeout
\n
"
);
c
->
state
=
conn_failed
;
fail_connection
(
c
);
}
else
if
(
get_double_time
()
-
c
->
last_receive_time
>
5
*
PING_TIMEOUT
&&
c
->
state
==
conn_ready
)
{
int
x
[
3
];
x
[
0
]
=
CODE_ping
;
*
(
long
long
*
)(
x
+
1
)
=
lrand48
()
*
(
1ll
<<
32
)
+
lrand48
();
encrypt_send_message
(
c
,
x
,
3
,
0
);
tgl_do_send_ping
(
c
);
start_ping_timer
(
c
);
}
else
{
start_ping_timer
(
c
);
}
return
0
;
}
void
stop_ping_timer
(
struct
connection
*
c
)
{
remove_event_timer
(
&
c
->
ev
);
static
void
stop_ping_timer
(
struct
connection
*
c
)
{
event_del
(
c
->
ping_
ev
);
}
void
start_ping_timer
(
struct
connection
*
c
)
{
c
->
ev
.
timeout
=
get_double_time
()
+
PING_TIMEOUT
;
c
->
ev
.
alarm
=
(
void
*
)
ping_alarm
;
c
->
ev
.
self
=
c
;
insert_event_timer
(
&
c
->
ev
);
static
void
start_ping_timer
(
struct
connection
*
c
)
{
static
struct
timeval
ptimeout
=
{
PING_TIMEOUT
,
0
};
event_add
(
c
->
ping_ev
,
&
ptimeout
);
}
void
restart_connection
(
struct
connection
*
c
);
int
fail_alarm
(
void
*
ev
)
{
((
struct
connection
*
)
ev
)
->
in_fail_timer
=
0
;
restart_connection
(
ev
);
return
0
;
static
void
restart_connection
(
struct
connection
*
c
);
static
void
fail_alarm
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
struct
connection
*
c
=
arg
;
c
->
in_fail_timer
=
0
;
restart_connection
(
c
);
}
void
start_fail_timer
(
struct
connection
*
c
)
{
static
void
start_fail_timer
(
struct
connection
*
c
)
{
if
(
c
->
in_fail_timer
)
{
return
;
}
c
->
in_fail_timer
=
1
;
c
->
ev
.
timeout
=
get_double_time
()
+
10
;
c
->
ev
.
alarm
=
(
void
*
)
fail_alarm
;
c
->
ev
.
self
=
c
;
insert_event_timer
(
&
c
->
ev
);
static
struct
timeval
ptimeout
=
{
10
,
0
};
event_add
(
c
->
fail_ev
,
&
ptimeout
);
}
struct
connection_buffer
*
new_connection_buffer
(
int
size
)
{
st
atic
st
ruct
connection_buffer
*
new_connection_buffer
(
int
size
)
{
struct
connection_buffer
*
b
=
talloc0
(
sizeof
(
*
b
));
b
->
start
=
talloc
(
size
);
b
->
end
=
b
->
start
+
size
;
...
...
@@ -119,16 +111,19 @@ struct connection_buffer *new_connection_buffer (int size) {
return
b
;
}
void
delete_connection_buffer
(
struct
connection_buffer
*
b
)
{
static
void
delete_connection_buffer
(
struct
connection_buffer
*
b
)
{
tfree
(
b
->
start
,
b
->
end
-
b
->
start
);
tfree
(
b
,
sizeof
(
*
b
));
}
int
write_out
(
struct
connection
*
c
,
const
void
*
_data
,
int
len
)
{
int
tgln_
write_out
(
struct
connection
*
c
,
const
void
*
_data
,
int
len
)
{
const
unsigned
char
*
data
=
_data
;
if
(
!
len
)
{
return
0
;
}
assert
(
len
>
0
);
int
x
=
0
;
if
(
!
c
->
out_bytes
)
{
event_add
(
c
->
write_ev
,
0
);
}
if
(
!
c
->
out_head
)
{
struct
connection_buffer
*
b
=
new_connection_buffer
(
1
<<
20
);
c
->
out_head
=
c
->
out_tail
=
b
;
...
...
@@ -156,7 +151,7 @@ int write_out (struct connection *c, const void *_data, int len) {
return
x
;
}
int
read_in
(
struct
connection
*
c
,
void
*
_data
,
int
len
)
{
int
tgln_
read_in
(
struct
connection
*
c
,
void
*
_data
,
int
len
)
{
unsigned
char
*
data
=
_data
;
if
(
!
len
)
{
return
0
;
}
assert
(
len
>
0
);
...
...
@@ -188,7 +183,7 @@ int read_in (struct connection *c, void *_data, int len) {
return
x
;
}
int
read_in_lookup
(
struct
connection
*
c
,
void
*
_data
,
int
len
)
{
int
tgln_
read_in_lookup
(
struct
connection
*
c
,
void
*
_data
,
int
len
)
{
unsigned
char
*
data
=
_data
;
if
(
!
len
||
!
c
->
in_bytes
)
{
return
0
;
}
assert
(
len
>
0
);
...
...
@@ -213,14 +208,14 @@ int read_in_lookup (struct connection *c, void *_data, int len) {
return
x
;
}
void
flush_out
(
struct
connection
*
c
UU
)
{
void
tgln_
flush_out
(
struct
connection
*
c
UU
)
{
}
#define MAX_CONNECTIONS 100
struct
connection
*
Connections
[
MAX_CONNECTIONS
];
int
max_connection_fd
;
st
atic
st
ruct
connection
*
Connections
[
MAX_CONNECTIONS
];
static
int
max_connection_fd
;
void
rotate_port
(
struct
connection
*
c
)
{
static
void
rotate_port
(
struct
connection
*
c
)
{
switch
(
c
->
port
)
{
case
443
:
c
->
port
=
80
;
...
...
@@ -234,11 +229,26 @@ void rotate_port (struct connection *c) {
}
}
struct
connection
*
create_connection
(
const
char
*
host
,
int
port
,
struct
session
*
session
,
struct
connection_methods
*
methods
)
{
static
void
try_read
(
struct
connection
*
c
);
static
void
try_write
(
struct
connection
*
c
);
static
void
conn_try_read
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
struct
connection
*
c
=
arg
;
try_read
(
c
);
}
static
void
conn_try_write
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
struct
connection
*
c
=
arg
;
try_write
(
c
);
if
(
c
->
out_bytes
)
{
event_add
(
c
->
write_ev
,
0
);
}
}
struct
connection
*
tgln_create_connection
(
const
char
*
host
,
int
port
,
struct
session
*
session
,
struct
mtproto_methods
*
methods
)
{
struct
connection
*
c
=
talloc0
(
sizeof
(
*
c
));
int
fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
fd
==
-
1
)
{
logprintf
(
"Can not create socket: %m
\n
"
);
vlogprintf
(
E_ERROR
,
"Can not create socket: %m
\n
"
);
exit
(
1
);
}
assert
(
fd
>=
0
&&
fd
<
MAX_CONNECTIONS
);
...
...
@@ -260,51 +270,38 @@ struct connection *create_connection (const char *host, int port, struct session
if
(
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
if
(
errno
!=
EINPROGRESS
)
{
logprintf
(
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
vlogprintf
(
E_ERROR
,
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
close
(
fd
);
tfree
(
c
,
sizeof
(
*
c
));
return
0
;
}
}
struct
pollfd
s
;
s
.
fd
=
fd
;
s
.
events
=
POLLOUT
|
POLLERR
|
POLLRDHUP
|
POLLHUP
;
errno
=
0
;
while
(
poll
(
&
s
,
1
,
10000
)
<=
0
||
!
(
s
.
revents
&
POLLOUT
))
{
if
(
errno
==
EINTR
)
{
continue
;
}
if
(
errno
)
{
logprintf
(
"Problems in poll: %m
\n
"
);
exit
(
1
);
}
logprintf
(
"Connect with %s:%d timeout
\n
"
,
host
,
port
);
close
(
fd
);
tfree
(
c
,
sizeof
(
*
c
));
return
0
;
}
c
->
session
=
session
;
c
->
fd
=
fd
;
c
->
fd
=
fd
;
c
->
state
=
conn_connecting
;
c
->
last_receive_time
=
get_double_time
();
c
->
ip
=
tstrdup
(
host
);
c
->
flags
=
0
;
c
->
state
=
conn_ready
;
c
->
methods
=
methods
;
c
->
port
=
port
;
assert
(
!
Connections
[
fd
]);
Connections
[
fd
]
=
c
;
if
(
verbosity
)
{
logprintf
(
"connect to %s:%d successful
\n
"
,
host
,
port
);
}
if
(
c
->
methods
->
ready
)
{
c
->
methods
->
ready
(
c
);
}
c
->
last_receive_time
=
get_double_time
();
c
->
ping_ev
=
evtimer_new
(
tgl_state
.
ev_base
,
ping_alarm
,
c
);
c
->
fail_ev
=
evtimer_new
(
tgl_state
.
ev_base
,
fail_alarm
,
c
);
c
->
read_ev
=
event_new
(
tgl_state
.
ev_base
,
c
->
fd
,
EV_READ
|
EV_PERSIST
,
conn_try_read
,
c
);
c
->
write_ev
=
event_new
(
tgl_state
.
ev_base
,
c
->
fd
,
EV_WRITE
,
conn_try_write
,
c
);
event_add
(
c
->
read_ev
,
0
);
start_ping_timer
(
c
);
char
byte
=
0xef
;
assert
(
tgln_write_out
(
c
,
&
byte
,
1
)
==
1
);
tgln_flush_out
(
c
);
return
c
;
}
void
restart_connection
(
struct
connection
*
c
)
{
static
void
restart_connection
(
struct
connection
*
c
)
{
if
(
c
->
last_connect_time
==
time
(
0
))
{
start_fail_timer
(
c
);
return
;
...
...
@@ -313,7 +310,7 @@ void restart_connection (struct connection *c) {
c
->
last_connect_time
=
time
(
0
);
int
fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
fd
==
-
1
)
{
logprintf
(
"Can not create socket: %m
\n
"
);
vlogprintf
(
E_ERROR
,
"Can not create socket: %m
\n
"
);
exit
(
1
);
}
assert
(
fd
>=
0
&&
fd
<
MAX_CONNECTIONS
);
...
...
@@ -335,7 +332,7 @@ void restart_connection (struct connection *c) {
if
(
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
if
(
errno
!=
EINPROGRESS
)
{
logprintf
(
"Can not connect to %s:%d %m
\n
"
,
c
->
ip
,
c
->
port
);
vlogprintf
(
E_WARNING
,
"Can not connect to %s:%d %m
\n
"
,
c
->
ip
,
c
->
port
);
start_fail_timer
(
c
);
close
(
fd
);
return
;
...
...
@@ -349,14 +346,15 @@ void restart_connection (struct connection *c) {
Connections
[
fd
]
=
c
;
char
byte
=
0xef
;
assert
(
write_out
(
c
,
&
byte
,
1
)
==
1
);
flush_out
(
c
);
assert
(
tgln_
write_out
(
c
,
&
byte
,
1
)
==
1
);
tgln_
flush_out
(
c
);
}
void
fail_connection
(
struct
connection
*
c
)
{
static
void
fail_connection
(
struct
connection
*
c
)
{
if
(
c
->
state
==
conn_ready
||
c
->
state
==
conn_connecting
)
{
stop_ping_timer
(
c
);
}
event_del
(
c
->
write_ev
);
rotate_port
(
c
);
struct
connection_buffer
*
b
=
c
->
out_head
;
while
(
b
)
{
...
...
@@ -375,19 +373,17 @@ void fail_connection (struct connection *c) {
c
->
out_bytes
=
c
->
in_bytes
=
0
;
close
(
c
->
fd
);
Connections
[
c
->
fd
]
=
0
;
logprintf
(
"Lost connection to server... %s:%d
\n
"
,
c
->
ip
,
c
->
port
);
vlogprintf
(
E_NOTICE
,
"Lost connection to server... %s:%d
\n
"
,
c
->
ip
,
c
->
port
);
restart_connection
(
c
);
}
extern
FILE
*
log_net_f
;
void
try_write
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
logprintf
(
"try write: fd = %d
\n
"
,
c
->
fd
);
}
//extern FILE *log_net_f;
static
void
try_write
(
struct
connection
*
c
)
{
vlogprintf
(
E_DEBUG
,
"try write: fd = %d
\n
"
,
c
->
fd
);
int
x
=
0
;
while
(
c
->
out_head
)
{
int
r
=
write
(
c
->
fd
,
c
->
out_head
->
rptr
,
c
->
out_head
->
wptr
-
c
->
out_head
->
rptr
);
if
(
r
>
0
&&
log_net_f
)
{
/*
if (r > 0 && log_net_f) {
fprintf (log_net_f, "%.02lf %d OUT %s:%d", get_utime (CLOCK_REALTIME), r, c->ip, c->port);
int i;
for (i = 0; i < r; i++) {
...
...
@@ -395,7 +391,7 @@ void try_write (struct connection *c) {
}
fprintf (log_net_f, "\n");
fflush (log_net_f);
}
}
*/
if
(
r
>=
0
)
{
x
+=
r
;
c
->
out_head
->
rptr
+=
r
;
...
...
@@ -410,9 +406,7 @@ void try_write (struct connection *c) {
delete_connection_buffer
(
b
);
}
else
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EWOULDBLOCK
)
{
if
(
verbosity
)
{
logprintf
(
"fail_connection: write_error %m
\n
"
);
}
vlogprintf
(
E_NOTICE
,
"fail_connection: write_error %m
\n
"
);
fail_connection
(
c
);
return
;
}
else
{
...
...
@@ -420,13 +414,11 @@ void try_write (struct connection *c) {
}
}
}
if
(
verbosity
)
{
logprintf
(
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
}
vlogprintf
(
E_DEBUG
,
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
c
->
out_bytes
-=
x
;
}
void
hexdump_buf
(
struct
connection_buffer
*
b
)
{
/*static
void hexdump_buf (struct connection_buffer *b) {
int pos = 0;
int rem = 8;
while (b) {
...
...
@@ -448,57 +440,52 @@ void hexdump_buf (struct connection_buffer *b) {
}
printf ("\n");
}
}
*/
void
try_rpc_read
(
struct
connection
*
c
)
{
static
void
try_rpc_read
(
struct
connection
*
c
)
{
assert
(
c
->
in_head
);
if
(
verbosity
>=
3
)
{
hexdump_buf
(
c
->
in_head
);
}
while
(
1
)
{
if
(
c
->
in_bytes
<
1
)
{
return
;
}
unsigned
len
=
0
;
unsigned
t
=
0
;
assert
(
read_in_lookup
(
c
,
&
len
,
1
)
==
1
);
assert
(
tgln_
read_in_lookup
(
c
,
&
len
,
1
)
==
1
);
if
(
len
>=
1
&&
len
<=
0x7e
)
{
if
(
c
->
in_bytes
<
(
int
)(
1
+
4
*
len
))
{
return
;
}
}
else
{
if
(
c
->
in_bytes
<
4
)
{
return
;
}
assert
(
read_in_lookup
(
c
,
&
len
,
4
)
==
4
);
assert
(
tgln_
read_in_lookup
(
c
,
&
len
,
4
)
==
4
);
len
=
(
len
>>
8
);
if
(
c
->
in_bytes
<
(
int
)(
4
+
4
*
len
))
{
return
;
}
len
=
0x7f
;
}
if
(
len
>=
1
&&
len
<=
0x7e
)
{
assert
(
read_in
(
c
,
&
t
,
1
)
==
1
);
assert
(
tgln_
read_in
(
c
,
&
t
,
1
)
==
1
);
assert
(
t
==
len
);
assert
(
len
>=
1
);
}
else
{
assert
(
len
==
0x7f
);
assert
(
read_in
(
c
,
&
len
,
4
)
==
4
);
assert
(
tgln_
read_in
(
c
,
&
len
,
4
)
==
4
);
len
=
(
len
>>
8
);
assert
(
len
>=
1
);
}
len
*=
4
;
int
op
;
assert
(
read_in_lookup
(
c
,
&
op
,
4
)
==
4
);
assert
(
tgln_
read_in_lookup
(
c
,
&
op
,
4
)
==
4
);
c
->
methods
->
execute
(
c
,
op
,
len
);
}
}
void
try_read
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
logprintf
(
"try read: fd = %d
\n
"
,
c
->
fd
);
}
static
void
try_read
(
struct
connection
*
c
)
{
vlogprintf
(
E_DEBUG
,
"try read: fd = %d
\n
"
,
c
->
fd
);
if
(
!
c
->
in_tail
)
{
c
->
in_head
=
c
->
in_tail
=
new_connection_buffer
(
1
<<
20
);
}
int
x
=
0
;
while
(
1
)
{
int
r
=
read
(
c
->
fd
,
c
->
in_tail
->
wptr
,
c
->
in_tail
->
end
-
c
->
in_tail
->
wptr
);
if
(
r
>
0
&&
log_net_f
)
{
/*
if (r > 0 && log_net_f) {
fprintf (log_net_f, "%.02lf %d IN %s:%d", get_utime (CLOCK_REALTIME), r, c->ip, c->port);
int i;
for (i = 0; i < r; i++) {
...
...
@@ -506,7 +493,7 @@ void try_read (struct connection *c) {
}
fprintf (log_net_f, "\n");
fflush (log_net_f);
}
}
*/
if
(
r
>
0
)
{
c
->
last_receive_time
=
get_double_time
();
stop_ping_timer
(
c
);
...
...
@@ -523,9 +510,7 @@ void try_read (struct connection *c) {
c
->
in_tail
=
b
;
}
else
{
if
(
errno
!=
EAGAIN
&&
errno
!=
EWOULDBLOCK
)
{
if
(
verbosity
)
{
logprintf
(
"fail_connection: read_error %m
\n
"
);
}
vlogprintf
(
E_NOTICE
,
"fail_connection: read_error %m
\n
"
);
fail_connection
(
c
);
return
;
}
else
{
...
...
@@ -533,16 +518,14 @@ void try_read (struct connection *c) {
}
}
}
if
(
verbosity
)
{
logprintf
(
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
}
vlogprintf
(
E_DEBUG
,
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
c
->
in_bytes
+=
x
;
if
(
x
)
{
try_rpc_read
(
c
);
}
}
int
connections_make_poll_array
(
struct
pollfd
*
fds
,
int
max
)
{
int
tgl_
connections_make_poll_array
(
struct
pollfd
*
fds
,
int
max
)
{
int
_max
=
max
;
int
i
;
for
(
i
=
0
;
i
<=
max_connection_fd
;
i
++
)
{
...
...
@@ -561,16 +544,10 @@ int connections_make_poll_array (struct pollfd *fds, int max) {
max
--
;
}
}
if
(
verbosity
>=
10
)
{
logprintf
(
"%d connections in poll
\n
"
,
_max
-
max
);
}
return
_max
-
max
;
}
void
connections_poll_result
(
struct
pollfd
*
fds
,
int
max
)
{
if
(
verbosity
>=
10
)
{
logprintf
(
"connections_poll_result: max = %d
\n
"
,
max
);
}
void
tgl_connections_poll_result
(
struct
pollfd
*
fds
,
int
max
)
{
int
i
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
struct
connection
*
c
=
Connections
[
fds
[
i
].
fd
];
...
...
@@ -578,13 +555,11 @@ void connections_poll_result (struct pollfd *fds, int max) {
try_read
(
c
);
}
if
(
fds
[
i
].
revents
&
(
POLLHUP
|
POLLERR
|
POLLRDHUP
))
{
if
(
verbosity
)
{
logprintf
(
"fail_connection: events_mask=0x%08x
\n
"
,
fds
[
i
].
revents
);
}
vlogprintf
(
E_NOTICE
,
"fail_connection: events_mask=0x%08x
\n
"
,
fds
[
i
].
revents
);
fail_connection
(
c
);
}
else
if
(
fds
[
i
].
revents
&
POLLOUT
)
{
if
(
c
->
state
==
conn_connecting
)
{
logprintf
(
"connection ready
\n
"
);
vlogprintf
(
E_DEBUG
,
"connection ready
\n
"
);
c
->
state
=
conn_ready
;
c
->
last_receive_time
=
get_double_time
();
}
...
...
@@ -594,54 +569,3 @@ void connections_poll_result (struct pollfd *fds, int max) {
}
}
}
int
send_all_acks
(
struct
session
*
S
)
{
clear_packet
();
out_int
(
CODE_msgs_ack
);
out_int
(
CODE_vector
);
out_int
(
tree_count_long
(
S
->
ack_tree
));
while
(
S
->
ack_tree
)
{
long
long
x
=
tree_get_min_long
(
S
->
ack_tree
);
out_long
(
x
);
S
->
ack_tree
=
tree_delete_long
(
S
->
ack_tree
,
x
);
}
encrypt_send_message
(
S
->
c
,
packet_buffer
,
packet_ptr
-
packet_buffer
,
0
);
return
0
;
}
void
insert_msg_id
(
struct
session
*
S
,
long
long
id
)
{
if
(
!
S
->
ack_tree
)
{
S
->
ev
.
alarm
=
(
void
*
)
send_all_acks
;
S
->
ev
.
self
=
(
void
*
)
S
;
S
->
ev
.
timeout
=
get_double_time
()
+
ACK_TIMEOUT
;
insert_event_timer
(
&
S
->
ev
);
}
if
(
!
tree_lookup_long
(
S
->
ack_tree
,
id
))
{
S
->
ack_tree
=
tree_insert_long
(
S
->
ack_tree
,
id
,
lrand48
());
}
}
extern
struct
dc
*
DC_list
[];
struct
dc
*
alloc_dc
(
int
id
,
char
*
ip
,
int
port
UU
)
{
assert
(
!
DC_list
[
id
]);
struct
dc
*
DC
=
talloc0
(
sizeof
(
*
DC
));
DC
->
id
=
id
;
DC
->
ip
=
ip
;
DC
->
port
=
port
;
DC_list
[
id
]
=
DC
;
return
DC
;
}
void
dc_create_session
(
struct
dc
*
DC
)
{
struct
session
*
S
=
talloc0
(
sizeof
(
*
S
));
assert
(
RAND_pseudo_bytes
((
unsigned
char
*
)
&
S
->
session_id
,
8
)
>=
0
);
S
->
dc
=
DC
;
S
->
c
=
create_connection
(
DC
->
ip
,
DC
->
port
,
S
,
&
auth_methods
);
if
(
!
S
->
c
)
{
logprintf
(
"Can not create connection to DC. Is network down?
\n
"
);
exit
(
1
);
}
assert
(
!
DC
->
sessions
[
0
]);
DC
->
sessions
[
0
]
=
S
;
}
net.h
View file @
b12ca538
...
...
@@ -20,59 +20,6 @@
#define __NET_H__
#include <poll.h>
struct
dc
;
#include "queries.h"
#define TG_SERVER "173.240.5.1"
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
enum
dc_state
{
st_init
,
st_reqpq_sent
,
st_reqdh_sent
,
st_client_dh_sent
,
st_authorized
,
st_error
}
;
struct
connection
;
struct
connection_methods
{
int
(
*
ready
)
(
struct
connection
*
c
);
int
(
*
close
)
(
struct
connection
*
c
);
int
(
*
execute
)
(
struct
connection
*
c
,
int
op
,
int
len
);
};
#define MAX_DC_SESSIONS 3
struct
session
{
struct
dc
*
dc
;
long
long
session_id
;
int
seq_no
;
struct
connection
*
c
;
struct
tree_long
*
ack_tree
;
struct
event_timer
ev
;
};
struct
dc
{
int
id
;
int
port
;
int
flags
;
char
*
ip
;
char
*
user
;
struct
session
*
sessions
[
MAX_DC_SESSIONS
];
char
auth_key
[
256
];
long
long
auth_key_id
;
long
long
server_salt
;
int
server_time_delta
;
double
server_time_udelta
;
int
has_auth
;
};
#define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb
...
...
@@ -122,27 +69,32 @@ struct connection {
int
out_packet_num
;
int
last_connect_time
;
int
in_fail_timer
;
struct
connection
_methods
*
methods
;
struct
mtproto
_methods
*
methods
;
struct
session
*
session
;
void
*
extra
;
struct
event_timer
ev
;
struct
event
*
ping_ev
;
struct
event
*
fail_ev
;
struct
event
*
read_ev
;
struct
event
*
write_ev
;
double
last_receive_time
;
};
extern
struct
connection
*
Connections
[];
//extern struct connection *Connections[];
int
tgln_write_out
(
struct
connection
*
c
,
const
void
*
data
,
int
len
);
void
tgln_flush_out
(
struct
connection
*
c
);
int
tgln_read_in
(
struct
connection
*
c
,
void
*
data
,
int
len
);
int
tgln_read_in_lookup
(
struct
connection
*
c
,
void
*
data
,
int
len
);
void
tgln_insert_msg_id
(
struct
session
*
S
,
long
long
id
);
int
write_out
(
struct
connection
*
c
,
const
void
*
data
,
int
len
);
void
flush_out
(
struct
connection
*
c
);
int
read_in
(
struct
connection
*
c
,
void
*
data
,
int
len
);
void
create_all_outbound_connections
(
void
);
//
void create_all_outbound_connections (void);
struct
connection
*
create_connection
(
const
char
*
host
,
int
port
,
struct
session
*
session
,
struct
connection_methods
*
methods
);
int
connections_make_poll_array
(
struct
pollfd
*
fds
,
int
max
);
void
connections_poll_result
(
struct
pollfd
*
fds
,
int
max
);
void
dc_create_session
(
struct
dc
*
DC
);
void
insert_msg_id
(
struct
session
*
S
,
long
long
id
);
struct
dc
*
alloc_dc
(
int
id
,
char
*
ip
,
int
port
);
//struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods);
struct
dc
*
tgln_alloc_dc
(
int
id
,
char
*
ip
,
int
port
);
void
tgln_dc_create_session
(
struct
dc
*
DC
,
struct
mtproto_methods
*
methods
);
struct
connection
*
tgln_create_connection
(
const
char
*
host
,
int
port
,
struct
session
*
session
,
struct
mtproto_methods
*
methods
);
#define GET_DC(c) (c->session->dc)
#endif
queries.c
View file @
b12ca538
...
...
@@ -44,7 +44,7 @@
#include "loop.h"
#include "structures.h"
//#include "interface.h"
#include "net.h"
//
#include "net.h"
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
...
...
@@ -53,8 +53,10 @@
#include "no-preview.h"
#include "binlog.h"
#include "updates.h"
#include "auto.h"
#include "tgl.h"
#include <event2/event.h>
#define sha1 SHA1
...
...
@@ -85,25 +87,23 @@ static void out_peer_id (tgl_peer_id_t id);
DEFINE_TREE
(
query
,
struct
query
*
,
memcmp8
,
0
)
;
struct
tree_query
*
queries_tree
;
double
get_double_time
(
void
)
{
struct
timespec
tv
;
my_clock_gettime
(
CLOCK_REALTIME
,
&
tv
);
return
tv
.
tv_sec
+
1e-9
*
tv
.
tv_nsec
;
}
struct
query
*
query_get
(
long
long
id
)
{
struct
query
*
tglq_query_get
(
long
long
id
)
{
return
tree_lookup_query
(
queries_tree
,
(
void
*
)
&
id
);
}
int
alarm_query
(
struct
query
*
q
)
{
static
int
alarm_query
(
struct
query
*
q
)
{
assert
(
q
);
vlogprintf
(
E_DEBUG
,
"Alarm query %lld
\n
"
,
q
->
msg_id
);
q
->
ev
.
timeout
=
get_double_time
()
+
QUERY_TIMEOUT
;
insert_event_timer
(
&
q
->
ev
);
//q->ev.timeout = get_double_time () + QUERY_TIMEOUT;
//insert_event_timer (&q->ev);
static
struct
timeval
ptimeout
=
{
QUERY_TIMEOUT
,
0
};
event_add
(
q
->
ev
,
&
ptimeout
);
if
(
q
->
session
->
c
->
out_bytes
>=
100000
)
{
/*
if (q->session->c->out_bytes >= 100000) {
return 0;
}
}
*/
clear_packet
();
out_int
(
CODE_msg_container
);
...
...
@@ -113,30 +113,35 @@ int alarm_query (struct query *q) {
out_int
(
4
*
q
->
data_len
);
out_ints
(
q
->
data
,
q
->
data_len
);
encrypt_send_message
(
q
->
session
->
c
,
packet_buffer
,
packet_ptr
-
packet_buffer
,
0
);
tglmp_
encrypt_send_message
(
q
->
session
->
c
,
packet_buffer
,
packet_ptr
-
packet_buffer
,
0
);
return
0
;
}
void
query_restart
(
long
long
id
)
{
struct
query
*
q
=
query_get
(
id
);
void
tglq_
query_restart
(
long
long
id
)
{
struct
query
*
q
=
tglq_
query_get
(
id
);
if
(
q
)
{
remove_event_timer
(
&
q
->
ev
);
event_del
(
q
->
ev
);
alarm_query
(
q
);
}
}
struct
query
*
send_query
(
struct
dc
*
DC
,
int
ints
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
,
void
*
callback
,
void
*
callback_extra
)
{
static
void
alarm_query_gateway
(
evutil_socket_t
fd
,
short
what
,
void
*
arg
)
{
alarm_query
(
arg
);
}
struct
query
*
tglq_send_query
(
struct
dc
*
DC
,
int
ints
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
,
void
*
callback
,
void
*
callback_extra
)
{
assert
(
DC
);
assert
(
DC
->
auth_key_id
);
if
(
!
DC
->
sessions
[
0
])
{
dc_create_session
(
DC
);
tglmp_
dc_create_session
(
DC
);
}
vlogprintf
(
E_DEBUG
,
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
struct
query
*
q
=
talloc0
(
sizeof
(
*
q
));
q
->
data_len
=
ints
;
q
->
data
=
talloc
(
4
*
ints
);
memcpy
(
q
->
data
,
data
,
4
*
ints
);
q
->
msg_id
=
encrypt_send_message
(
DC
->
sessions
[
0
]
->
c
,
data
,
ints
,
1
);
q
->
msg_id
=
tglmp_
encrypt_send_message
(
DC
->
sessions
[
0
]
->
c
,
data
,
ints
,
1
);
q
->
session
=
DC
->
sessions
[
0
];
q
->
seq_no
=
DC
->
sessions
[
0
]
->
seq_no
-
1
;
vlogprintf
(
E_DEBUG
,
"Msg_id is %lld %p
\n
"
,
q
->
msg_id
,
q
);
...
...
@@ -147,10 +152,14 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
}
queries_tree
=
tree_insert_query
(
queries_tree
,
q
,
lrand48
());
q
->
ev
.
alarm
=
(
void
*
)
alarm_query
;
q
->
ev
.
timeout
=
get_double_time
()
+
QUERY_TIMEOUT
;
q
->
ev
.
self
=
(
void
*
)
q
;
insert_event_timer
(
&
q
->
ev
);
//q->ev.alarm = (void *)alarm_query;
//q->ev.timeout = get_double_time () + QUERY_TIMEOUT;
//q->ev.self = (void *)q;
//insert_event_timer (&q->ev);
q
->
ev
=
evtimer_new
(
tgl_state
.
ev_base
,
alarm_query_gateway
,
q
);
static
struct
timeval
ptimeout
=
{
QUERY_TIMEOUT
,
0
};
event_add
(
q
->
ev
,
&
ptimeout
);
q
->
extra
=
extra
;
q
->
callback
=
callback
;
...
...
@@ -165,27 +174,27 @@ static int fail_on_error (struct query *q UU, int error_code UU, int l UU, char
return
0
;
}
void
query_ack
(
long
long
id
)
{
struct
query
*
q
=
query_get
(
id
);
void
tglq_
query_ack
(
long
long
id
)
{
struct
query
*
q
=
tglq_
query_get
(
id
);
if
(
q
&&
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
assert
(
q
->
msg_id
==
id
);
q
->
flags
|=
QUERY_ACK_RECEIVED
;
remove_event_timer
(
&
q
->
ev
);
event_del
(
q
->
ev
);
}
}
void
query_error
(
long
long
id
)
{
void
tglq_
query_error
(
long
long
id
)
{
assert
(
fetch_int
()
==
CODE_rpc_error
);
int
error_code
=
fetch_int
();
int
error_len
=
prefetch_strlen
();
char
*
error
=
fetch_str
(
error_len
);
vlogprintf
(
E_WARNING
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
struct
query
*
q
=
query_get
(
id
);
struct
query
*
q
=
tglq_
query_get
(
id
);
if
(
!
q
)
{
vlogprintf
(
E_WARNING
,
"No such query
\n
"
);
}
else
{
if
(
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
remove_event_timer
(
&
q
->
ev
);
event_del
(
q
->
ev
);
}
queries_tree
=
tree_delete_query
(
queries_tree
,
q
);
if
(
q
->
methods
&&
q
->
methods
->
on_error
)
{
...
...
@@ -194,6 +203,7 @@ void query_error (long long id) {
vlogprintf
(
E_WARNING
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
}
tfree
(
q
->
data
,
q
->
data_len
*
4
);
event_free
(
q
->
ev
);
tfree
(
q
,
sizeof
(
*
q
));
}
queries_num
--
;
...
...
@@ -202,7 +212,7 @@ void query_error (long long id) {
#define MAX_PACKED_SIZE (1 << 24)
static
int
packed_buffer
[
MAX_PACKED_SIZE
/
4
];
void
query_result
(
long
long
id
UU
)
{
void
tglq_
query_result
(
long
long
id
UU
)
{
vlogprintf
(
E_DEBUG
,
"result for query #%lld
\n
"
,
id
);
/*if (verbosity >= 4) {
logprintf ( "result: ");
...
...
@@ -226,7 +236,7 @@ void query_result (long long id UU) {
hexdump_in ();
}*/
}
struct
query
*
q
=
query_get
(
id
);
struct
query
*
q
=
tglq_
query_get
(
id
);
if
(
!
q
)
{
//if (verbosity) {
// logprintf ( "No such query\n");
...
...
@@ -235,7 +245,7 @@ void query_result (long long id UU) {
in_ptr
=
in_end
;
}
else
{
if
(
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
remove_event_timer
(
&
q
->
ev
);
event_del
(
q
->
ev
);
}
queries_tree
=
tree_delete_query
(
queries_tree
,
q
);
if
(
q
->
methods
&&
q
->
methods
->
on_answer
)
{
...
...
@@ -253,6 +263,7 @@ void query_result (long long id UU) {
assert
(
in_ptr
==
in_end
);
}
tfree
(
q
->
data
,
4
*
q
->
data_len
);
event_free
(
q
->
ev
);
tfree
(
q
,
sizeof
(
*
q
));
}
if
(
end
)
{
...
...
@@ -262,37 +273,6 @@ void query_result (long long id UU) {
queries_num
--
;
}
#define event_timer_cmp(a,b) ((a)->timeout > (b)->timeout ? 1 : ((a)->timeout < (b)->timeout ? -1 : (memcmp (a, b, sizeof (struct event_timer)))))
DEFINE_TREE
(
timer
,
struct
event_timer
*
,
event_timer_cmp
,
0
)
struct
tree_timer
*
timer_tree
;
void
insert_event_timer
(
struct
event_timer
*
ev
)
{
vlogprintf
(
E_DEBUG
+
2
,
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
timer_tree
=
tree_insert_timer
(
timer_tree
,
ev
,
lrand48
());
}
void
remove_event_timer
(
struct
event_timer
*
ev
)
{
vlogprintf
(
E_DEBUG
+
2
,
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
timer_tree
=
tree_delete_timer
(
timer_tree
,
ev
);
}
double
next_timer_in
(
void
)
{
if
(
!
timer_tree
)
{
return
1e100
;
}
return
tree_get_min_timer
(
timer_tree
)
->
timeout
;
}
void
work_timers
(
void
)
{
double
t
=
get_double_time
();
while
(
timer_tree
)
{
struct
event_timer
*
ev
=
tree_get_min_timer
(
timer_tree
);
assert
(
ev
);
if
(
ev
->
timeout
>
t
)
{
break
;
}
remove_event_timer
(
ev
);
assert
(
ev
->
alarm
);
vlogprintf
(
E_DEBUG
,
"Alarm
\n
"
);
ev
->
alarm
(
ev
->
self
);
}
}
int
max_chat_size
;
int
max_bcast_size
;
...
...
@@ -304,7 +284,7 @@ extern struct dc *DC_working;
static
void
out_random
(
int
n
)
{
assert
(
n
<=
32
);
static
char
buf
[
32
];
secure_random
(
buf
,
n
);
tglt_
secure_random
(
buf
,
n
);
out_cstring
(
buf
,
n
);
}
...
...
@@ -383,7 +363,7 @@ void tgl_do_help_get_config (void (*callback)(void *, int), void *callback_extra
clear_packet
();
tgl_do_insert_header
();
out_int
(
CODE_help_get_config
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -447,7 +427,7 @@ void tgl_do_send_code (const char *user, void (*callback)(void *callback_extra,
out_string
(
TG_APP_HASH
);
out_string
(
"en"
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_code_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_code_methods
,
0
,
callback
,
callback_extra
);
}
...
...
@@ -474,7 +454,7 @@ void tgl_do_phone_call (const char *user, void (*callback)(void *callback_extra,
out_string
(
user
);
out_string
(
phone_code_hash
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
phone_call_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
phone_call_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -534,10 +514,10 @@ int tgl_do_auth_check_phone (const char *user) {
out_int (CODE_auth_check_phone);
out_string (user);
check_phone_result = -1;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
net_loop (0, cr_f);
check_phone_result = -1;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
net_loop (0, cr_f);
return check_phone_result;
}*/
...
...
@@ -571,7 +551,7 @@ int tgl_do_get_nearest_dc (void) {
clear_packet ();
out_int (CODE_help_get_nearest_dc);
nearest_dc_num = -1;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &nearest_dc_methods, 0);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &nearest_dc_methods, 0);
net_loop (0, nr_f);
return nearest_dc_num;
}*/
...
...
@@ -607,7 +587,7 @@ int tgl_do_send_code_result (const char *user, const char *code, void (*callback
out_string
(
user
);
out_string
(
phone_code_hash
);
out_string
(
code
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
return
0
;
}
...
...
@@ -619,7 +599,7 @@ int tgl_do_send_code_result_auth (const char *user, const char *code, const char
out_string
(
code
);
out_string
(
first_name
);
out_string
(
last_name
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
return
0
;
}
/* }}} */
...
...
@@ -688,7 +668,7 @@ void tgl_do_update_contact_list (void (*callback) (void *callback_extra, int suc
clear_packet
();
out_int
(
CODE_contacts_get_contacts
);
out_string
(
""
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -745,7 +725,7 @@ static char *encrypt_decrypted_message (struct tgl_secret_chat *E) {
return
(
void
*
)
msg_key
;
}
void
encr_start
(
void
)
{
static
void
encr_start
(
void
)
{
encr_extra
=
packet_ptr
;
packet_ptr
+=
1
;
// str len
packet_ptr
+=
2
;
// fingerprint
...
...
@@ -754,11 +734,11 @@ void encr_start (void) {
}
void
encr_finish
(
struct
tgl_secret_chat
*
E
)
{
static
void
encr_finish
(
struct
tgl_secret_chat
*
E
)
{
int
l
=
packet_ptr
-
(
encr_extra
+
8
);
while
(((
packet_ptr
-
encr_extra
)
-
3
)
&
3
)
{
int
t
;
secure_random
(
&
t
,
4
);
tglt_
secure_random
(
&
t
,
4
);
out_int
(
t
);
}
...
...
@@ -775,7 +755,7 @@ void encr_finish (struct tgl_secret_chat *E) {
void
tgl_do_send_encr_chat_layer
(
struct
tgl_secret_chat
*
E
)
{
long
long
t
;
secure_random
(
&
t
,
8
);
tglt_
secure_random
(
&
t
,
8
);
int
action
[
2
];
action
[
0
]
=
CODE_decrypted_message_action_notify_layer
;
action
[
1
]
=
15
;
...
...
@@ -807,9 +787,9 @@ static int msg_send_on_answer (struct query *q UU) {
int
id
=
fetch_int
();
// id
struct
tgl_message
*
M
=
q
->
extra
;
bl_do_set_msg_id
(
M
,
id
);
fetch_date
();
fetch_pts
();
fetch_seq
();
tglu_
fetch_date
();
tglu_
fetch_pts
();
tglu_
fetch_seq
();
if
(
x
==
CODE_messages_sent_message_link
)
{
assert
(
skip_type_any
(
TYPE_TO_PARAM_1
(
vector
,
TYPE_TO_PARAM
(
contacts_link
)))
>=
0
);
}
...
...
@@ -902,7 +882,7 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M, void (*callback)(void *
out_int
(
CODE_decrypted_message_service
);
out_long
(
M
->
id
);
static
int
buf
[
4
];
secure_random
(
buf
,
16
);
tglt_
secure_random
(
buf
,
16
);
out_cstring
((
void
*
)
buf
,
16
);
switch
(
M
->
action
.
type
)
{
...
...
@@ -915,7 +895,7 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M, void (*callback)(void *
}
encr_finish
(
&
P
->
encr_chat
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_encr_msg
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
...
...
@@ -942,13 +922,13 @@ void tgl_do_send_encr_msg (struct tgl_message *M, void (*callback)(void *callbac
out_int
(
CODE_decrypted_message
);
out_long
(
M
->
id
);
static
int
buf
[
4
];
secure_random
(
buf
,
16
);
tglt_
secure_random
(
buf
,
16
);
out_cstring
((
void
*
)
buf
,
16
);
out_cstring
((
void
*
)
M
->
message
,
M
->
message_len
);
out_int
(
CODE_decrypted_message_media_empty
);
encr_finish
(
&
P
->
encr_chat
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_msg
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
...
...
@@ -961,7 +941,7 @@ void tgl_do_send_msg (struct tgl_message *M, void (*callback)(void *callback_ext
out_peer_id
(
M
->
to_id
);
out_cstring
(
M
->
message
,
M
->
message_len
);
out_long
(
M
->
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_message
(
tgl_peer_id_t
id
,
const
char
*
msg
,
int
len
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
...
...
@@ -983,7 +963,7 @@ void tgl_do_send_message (tgl_peer_id_t id, const char *msg, int len, void (*cal
}
}
long
long
t
;
secure_random
(
&
t
,
8
);
tglt_
secure_random
(
&
t
,
8
);
vlogprintf
(
E_DEBUG
,
"t = %lld, len = %d
\n
"
,
t
,
len
);
bl_do_send_message_text
(
t
,
tgl_state
.
our_id
,
tgl_get_peer_type
(
id
),
tgl_get_peer_id
(
id
),
time
(
0
),
len
,
msg
);
struct
tgl_message
*
M
=
tgl_message_get
(
t
);
...
...
@@ -1024,8 +1004,8 @@ void tgl_do_send_text (tgl_peer_id_t id, char *file_name, void (*callback)(void
/* {{{ Mark read */
static
int
mark_read_on_receive
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_affected_history
);
fetch_pts
();
fetch_seq
();
tglu_
fetch_pts
();
tglu_
fetch_seq
();
fetch_int
();
// offset
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)(
q
->
callback_extra
,
1
);
...
...
@@ -1057,7 +1037,7 @@ void tgl_do_messages_mark_read (tgl_peer_id_t id, int max_id, void (*callback)(v
out_peer_id
(
id
);
out_int
(
max_id
);
out_int
(
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_messages_mark_read_encr
(
tgl_peer_id_t
id
,
long
long
access_hash
,
int
last_time
,
void
(
*
callback
)(
void
*
callback_extra
,
int
),
void
*
callback_extra
)
{
...
...
@@ -1067,7 +1047,7 @@ void tgl_do_messages_mark_read_encr (tgl_peer_id_t id, long long access_hash, in
out_int
(
tgl_get_peer_id
(
id
));
out_long
(
access_hash
);
out_int
(
last_time
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_encr_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_encr_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_mark_read
(
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
...
...
@@ -1177,7 +1157,7 @@ void tgl_do_get_history (tgl_peer_id_t id, int limit, int offline_mode, void (*c
out_int
(
0
);
out_int
(
0
);
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_history_methods
,
(
void
*
)
*
(
long
*
)
&
id
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_history_methods
,
(
void
*
)
*
(
long
*
)
&
id
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1264,7 +1244,7 @@ void tgl_do_get_dialog_list (void (*callback)(void *callback_extra, int success,
out_int
(
0
);
out_int
(
0
);
out_int
(
1000
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dialogs_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dialogs_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1332,8 +1312,8 @@ static int send_file_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
fetch_pts
();
fetch_seq
();
tglu_
fetch_pts
();
tglu_
fetch_seq
();
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)(
q
->
callback_extra
,
1
,
M
);
...
...
@@ -1402,7 +1382,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
if
(
f
->
encr
)
{
if
(
x
&
15
)
{
assert
(
f
->
offset
==
f
->
size
);
secure_random
(
buf
+
x
,
(
-
x
)
&
15
);
tglt_
secure_random
(
buf
+
x
,
(
-
x
)
&
15
);
x
=
(
x
+
15
)
&
~
15
;
}
...
...
@@ -1420,7 +1400,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
assert
(
f
->
part_size
==
x
);
}
//update_prompt ();
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_part_methods
,
f
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_part_methods
,
f
,
callback
,
callback_extra
);
}
else
{
tgl_state
.
cur_uploaded_bytes
-=
f
->
size
;
tgl_state
.
cur_uploading_bytes
-=
f
->
size
;
...
...
@@ -1467,7 +1447,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
}
out_long
(
-
lrand48
()
*
(
1ll
<<
32
)
-
lrand48
());
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_methods
,
0
,
callback
,
callback_extra
);
}
else
{
struct
tgl_message
*
M
=
talloc0
(
sizeof
(
*
M
));
...
...
@@ -1558,7 +1538,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
M
->
id
=
r
;
M
->
date
=
time
(
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_file_methods
,
M
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_file_methods
,
M
,
callback
,
callback_extra
);
}
tfree_str
(
f
->
file_name
);
tfree
(
f
,
sizeof
(
*
f
));
...
...
@@ -1572,7 +1552,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra
out_long (f->thumb_id);
out_int (0);
out_cstring ((void *)thumb_file, thumb_file_size);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra);
}*/
void
tgl_do_send_photo
(
int
type
,
tgl_peer_id_t
to_id
,
char
*
file_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
...
...
@@ -1617,11 +1597,11 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*c
if
(
tgl_get_peer_type
(
f
->
to_id
)
==
TGL_PEER_ENCR_CHAT
)
{
f
->
encr
=
1
;
f
->
iv
=
talloc
(
32
);
secure_random
(
f
->
iv
,
32
);
tglt_
secure_random
(
f
->
iv
,
32
);
f
->
init_iv
=
talloc
(
32
);
memcpy
(
f
->
init_iv
,
f
->
iv
,
32
);
f
->
key
=
talloc
(
32
);
secure_random
(
f
->
key
,
32
);
tglt_
secure_random
(
f
->
key
,
32
);
}
/*if (f->media_type == CODE_input_media_uploaded_video && !f->encr) {
f->media_type = CODE_input_media_uploaded_thumb_video;
...
...
@@ -1651,8 +1631,8 @@ static int fwd_msg_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
fetch_pts
();
fetch_seq
();
tglu_
fetch_pts
();
tglu_
fetch_seq
();
//print_message (M);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
...
...
@@ -1676,7 +1656,7 @@ void tgl_do_forward_message (tgl_peer_id_t id, int n, void (*callback)(void *cal
out_peer_id
(
id
);
out_int
(
n
);
out_long
(
lrand48
()
*
(
1ll
<<
32
)
+
lrand48
());
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
fwd_msg_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
fwd_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1695,8 +1675,8 @@ static int rename_chat_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
fetch_pts
();
fetch_seq
();
tglu_
fetch_pts
();
tglu_
fetch_seq
();
//print_message (M);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
...
...
@@ -1715,7 +1695,7 @@ void tgl_do_rename_chat (tgl_peer_id_t id, char *name UU, void (*callback)(void
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_CHAT
);
out_int
(
tgl_get_peer_id
(
id
));
out_string
(
name
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
rename_chat_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
rename_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1774,7 +1754,7 @@ void tgl_do_get_chat_info (tgl_peer_id_t id, int offline_mode, void (*callback)(
out_int
(
CODE_messages_get_full_chat
);
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_CHAT
);
out_int
(
tgl_get_peer_id
(
id
));
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
chat_info_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
chat_info_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1836,7 +1816,7 @@ void tgl_do_get_user_info (tgl_peer_id_t id, int offline_mode, void (*callback)(
out_int
(
CODE_input_user_contact
);
out_int
(
tgl_get_peer_id
(
id
));
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
user_info_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
user_info_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1867,7 +1847,7 @@ void tgl_do_get_user_list_info_silent (int num, int *list) {
out_int (list[i]);
//out_long (0);
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0);
}*/
/* }}} */
...
...
@@ -2012,8 +1992,8 @@ static void load_next_part (struct download *D, void *callback, void *callback_e
}
out_int
(
D
->
offset
);
out_int
(
1
<<
14
);
send_query
(
DC_list
[
D
->
dc
],
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
download_methods
,
D
,
callback
,
callback_extra
);
//send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
tglq_
send_query
(
DC_list
[
D
->
dc
],
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
download_methods
,
D
,
callback
,
callback_extra
);
//
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
}
void
tgl_do_load_photo_size
(
struct
tgl_photo_size
*
P
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
...
...
@@ -2160,7 +2140,7 @@ static int export_auth_on_answer (struct query *q UU) {
out_int
(
CODE_auth_import_authorization
);
out_int
(
tgl_state
.
our_id
);
out_cstring
(
s
,
l
);
send_query
(
q
->
extra
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
import_auth_methods
,
0
,
q
->
callback
,
q
->
callback_extra
);
tglq_
send_query
(
q
->
extra
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
import_auth_methods
,
0
,
q
->
callback
,
q
->
callback_extra
);
tfree
(
s
,
l
);
return
0
;
}
...
...
@@ -2175,7 +2155,7 @@ void tgl_do_export_auth (int num, void (*callback) (void *callback_extra, int su
clear_packet
();
out_int
(
CODE_auth_export_authorization
);
out_int
(
num
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
export_auth_methods
,
DC_list
[
num
],
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
export_auth_methods
,
DC_list
[
num
],
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2262,7 +2242,7 @@ void tgl_do_add_contact (const char *phone, int phone_len, const char *first_nam
out_cstring
(
first_name
,
first_name_len
);
out_cstring
(
last_name
,
last_name_len
);
out_int
(
force
?
CODE_bool_true
:
CODE_bool_false
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_contact_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_contact_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2298,7 +2278,7 @@ void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const cha
out_int
(
0
);
// offset
out_int
(
0
);
// max_id
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2348,7 +2328,7 @@ void tgl_do_contacts_search (int limit, const char *s, void (*callback) (void *c
out_int
(
CODE_contacts_search
);
out_string
(
s
);
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
contacts_search_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
contacts_search_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2437,7 +2417,7 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
return
;
}
// Already generated key for this chat
unsigned
char
random_here
[
256
];
secure_random
(
random_here
,
256
);
tglt_
secure_random
(
random_here
,
256
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
random
[
i
]
^=
random_here
[
i
];
}
...
...
@@ -2445,7 +2425,7 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
ensure_ptr
(
b
);
BIGNUM
*
g_a
=
BN_bin2bn
(
E
->
g_key
,
256
,
0
);
ensure_ptr
(
g_a
);
assert
(
check_g
(
tgl_state
.
encr_prime
,
g_a
)
>=
0
);
assert
(
tglmp_
check_g
(
tgl_state
.
encr_prime
,
g_a
)
>=
0
);
if
(
!
ctx
)
{
ctx
=
BN_CTX_new
();
ensure_ptr
(
ctx
);
...
...
@@ -2485,14 +2465,14 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
BN_clear_free
(
p
);
BN_clear_free
(
r
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
,
callback
,
callback_extra
);
}
void
tgl_do_create_keys_end
(
struct
tgl_secret_chat
*
U
)
{
assert
(
tgl_state
.
encr_prime
);
BIGNUM
*
g_b
=
BN_bin2bn
(
U
->
g_key
,
256
,
0
);
ensure_ptr
(
g_b
);
assert
(
check_g
(
tgl_state
.
encr_prime
,
g_b
)
>=
0
);
assert
(
tglmp_
check_g
(
tgl_state
.
encr_prime
,
g_b
)
>=
0
);
if
(
!
ctx
)
{
ctx
=
BN_CTX_new
();
ensure_ptr
(
ctx
);
...
...
@@ -2535,7 +2515,7 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random, void (*callba
int
user_id
=
(
long
)
x
;
int
i
;
unsigned
char
random_here
[
256
];
secure_random
(
random_here
,
256
);
tglt_
secure_random
(
random_here
,
256
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
random
[
i
]
^=
random_here
[
i
];
}
...
...
@@ -2595,7 +2575,7 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random, void (*callba
BN_clear_free
(
p
);
BN_clear_free
(
r
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_request_methods
,
E
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_request_methods
,
E
,
callback
,
callback_extra
);
}
static
int
get_dh_config_on_answer
(
struct
query
*
q
UU
)
{
...
...
@@ -2611,7 +2591,7 @@ static int get_dh_config_on_answer (struct query *q UU) {
BIGNUM
*
p
=
BN_bin2bn
((
void
*
)
s
,
256
,
0
);
ensure_ptr
(
p
);
assert
(
check_DH_params
(
p
,
a
)
>=
0
);
assert
(
tglmp_
check_DH_params
(
p
,
a
)
>=
0
);
BN_free
(
p
);
}
int
l
=
prefetch_strlen
();
...
...
@@ -2644,7 +2624,7 @@ void tgl_do_accept_encr_chat_request (struct tgl_secret_chat *E, void (*callback
void
**
x
=
talloc
(
2
*
sizeof
(
void
*
));
x
[
0
]
=
tgl_do_send_accept_encr_chat
;
x
[
1
]
=
E
;
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
}
void
tgl_do_create_encr_chat_request
(
int
user_id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
...
...
@@ -2655,7 +2635,7 @@ void tgl_do_create_encr_chat_request (int user_id, void (*callback)(void *callba
void
**
x
=
talloc
(
2
*
sizeof
(
void
*
));
x
[
0
]
=
tgl_do_send_create_encr_chat
;
x
[
1
]
=
(
void
*
)(
long
)(
user_id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2711,7 +2691,7 @@ static int get_difference_on_answer (struct query *q UU) {
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
work_update
(
0
,
0
);
tglu_
work_update
(
0
,
0
);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
...
...
@@ -2780,10 +2760,10 @@ void tgl_do_get_difference (int sync_from_start, void (*callback)(void *callback
out_int
(
tgl_state
.
pts
);
out_int
(
tgl_state
.
date
);
out_int
(
tgl_state
.
qts
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_difference_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_difference_methods
,
0
,
callback
,
callback_extra
);
}
else
{
out_int
(
CODE_updates_get_state
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_state_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_state_methods
,
0
,
callback
,
callback_extra
);
}
}
/* }}} */
...
...
@@ -2872,7 +2852,7 @@ void tgl_do_get_suggested (void) {
clear_packet ();
out_int (CODE_contacts_get_suggested);
out_int (100);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_suggested_methods, 0);
tglq_
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_suggested_methods, 0);
}*/
/* }}} */
...
...
@@ -2899,7 +2879,7 @@ void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit
out_int
(
tgl_get_peer_id
(
id
));
}
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_del_user_from_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
...
...
@@ -2917,7 +2897,7 @@ void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, void (*
out_int
(
CODE_input_user_contact
);
out_int
(
tgl_get_peer_id
(
id
));
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2962,7 +2942,7 @@ void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic, void (*callba
out_int
(
tgl_get_peer_id
(
id
));
}
out_string
(
chat_topic
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
create_group_chat_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
create_group_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -2991,7 +2971,7 @@ void tgl_do_delete_msg (long long id, void (*callback)(void *callback_extra, int
out_int
(
CODE_vector
);
out_int
(
1
);
out_int
(
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
delete_msg_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
delete_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -3020,11 +3000,11 @@ void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, in
out_int
(
CODE_vector
);
out_int
(
1
);
out_int
(
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
restore_msg_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
restore_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
int
update_status_on_answer
(
struct
query
*
q
UU
)
{
static
int
update_status_on_answer
(
struct
query
*
q
UU
)
{
fetch_bool
();
if
(
q
->
callback
)
{
...
...
@@ -3042,5 +3022,5 @@ void tgl_do_update_status (int online UU, void (*callback)(void *callback_extra,
clear_packet
();
out_int
(
CODE_account_update_status
);
out_int
(
online
?
CODE_bool_false
:
CODE_bool_true
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
update_status_methods
,
0
,
callback
,
callback_extra
);
tglq_
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
update_status_methods
,
0
,
callback
,
callback_extra
);
}
queries.h
View file @
b12ca538
...
...
@@ -16,13 +16,15 @@
Copyright Vitaly Valtman 2013
*/
#include "net.h"
//
#include "net.h"
#ifndef __QUERIES_H__
#define __QUERIES_H__
#include "structures.h"
#include "auto.h"
#include "tgl-layout.h"
struct
event
;
#define QUERY_ACK_RECEIVED 1
struct
query
;
...
...
@@ -33,12 +35,6 @@ struct query_methods {
struct
paramed_type
*
type
;
};
struct
event_timer
{
double
timeout
;
int
(
*
alarm
)(
void
*
self
);
void
*
self
;
};
struct
query
{
long
long
msg_id
;
int
data_len
;
...
...
@@ -46,7 +42,7 @@ struct query {
int
seq_no
;
void
*
data
;
struct
query_methods
*
methods
;
struct
event
_timer
ev
;
struct
event
*
ev
;
struct
dc
*
DC
;
struct
session
*
session
;
void
*
extra
;
...
...
@@ -55,14 +51,12 @@ struct query {
};
struct
query
*
send_query
(
struct
dc
*
DC
,
int
len
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
,
void
*
callback
,
void
*
callback_extra
);
void
query_ack
(
long
long
id
);
void
query_error
(
long
long
id
);
void
query_result
(
long
long
id
);
void
query_restart
(
long
long
id
);
struct
query
*
tglq_
send_query
(
struct
dc
*
DC
,
int
len
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
,
void
*
callback
,
void
*
callback_extra
);
void
tglq_
query_ack
(
long
long
id
);
void
tglq_
query_error
(
long
long
id
);
void
tglq_
query_result
(
long
long
id
);
void
tglq_
query_restart
(
long
long
id
);
void
insert_event_timer
(
struct
event_timer
*
ev
);
void
remove_event_timer
(
struct
event_timer
*
ev
);
double
next_timer_in
(
void
);
void
work_timers
(
void
);
...
...
structures.c
View file @
b12ca538
...
...
@@ -32,6 +32,7 @@
#include <openssl/sha.h>
#include "queries.h"
#include "binlog.h"
#include "updates.h"
#include "tgl.h"
...
...
@@ -497,7 +498,7 @@ void tglf_fetch_photo_size (struct tgl_photo_size *S) {
}
}
void
fetch_geo
(
struct
tgl_geo
*
G
)
{
void
tglf_
fetch_geo
(
struct
tgl_geo
*
G
)
{
unsigned
x
=
fetch_int
();
if
(
x
==
CODE_geo_point
)
{
G
->
longitude
=
fetch_double
();
...
...
@@ -519,7 +520,7 @@ void tglf_fetch_photo (struct tgl_photo *P) {
P
->
user_id
=
fetch_int
();
P
->
date
=
fetch_int
();
P
->
caption
=
fetch_str_dup
();
fetch_geo
(
&
P
->
geo
);
tglf_
fetch_geo
(
&
P
->
geo
);
assert
(
fetch_int
()
==
CODE_vector
);
P
->
sizes_num
=
fetch_int
();
P
->
sizes
=
talloc
(
sizeof
(
struct
tgl_photo_size
)
*
P
->
sizes_num
);
...
...
@@ -630,10 +631,10 @@ void tglf_fetch_message_short (struct tgl_message *M) {
int
l
=
prefetch_strlen
();
char
*
s
=
fetch_str
(
l
);
fetch_pts
();
tglu_
fetch_pts
();
int
date
=
fetch_int
();
fetch_seq
();
tglu_
fetch_seq
();
bl_do_create_message_text
(
id
,
from_id
,
TGL_PEER_USER
,
to_id
,
date
,
l
,
s
);
}
else
{
...
...
@@ -642,9 +643,9 @@ void tglf_fetch_message_short (struct tgl_message *M) {
int
l
=
prefetch_strlen
();
fetch_str
(
l
);
// text
fetch_pts
();
tglu_
fetch_pts
();
fetch_int
();
fetch_seq
();
tglu_
fetch_seq
();
}
}
...
...
@@ -658,10 +659,10 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) {
int
l
=
prefetch_strlen
();
char
*
s
=
fetch_str
(
l
);
fetch_pts
();
tglu_
fetch_pts
();
int
date
=
fetch_int
();
fetch_seq
();
tglu_
fetch_seq
();
bl_do_create_message_text
(
id
,
from_id
,
TGL_PEER_CHAT
,
to_id
,
date
,
l
,
s
);
}
else
{
...
...
@@ -671,9 +672,9 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) {
int
l
=
prefetch_strlen
();
fetch_str
(
l
);
// text
fetch_pts
();
tglu_
fetch_pts
();
fetch_int
();
fetch_seq
();
tglu_
fetch_seq
();
}
}
...
...
@@ -697,7 +698,7 @@ void tglf_fetch_message_media (struct tgl_message_media *M) {
tglf_fetch_document
(
&
M
->
document
);
break
;
case
CODE_message_media_geo
:
fetch_geo
(
&
M
->
geo
);
tglf_
fetch_geo
(
&
M
->
geo
);
break
;
case
CODE_message_media_contact
:
M
->
phone
=
fetch_str_dup
();
...
...
@@ -995,7 +996,7 @@ void tglf_fetch_message (struct tgl_message *M) {
bl_do_set_unread
(
M
,
unread
);
}
void
tglf_fetch_geo_message
(
struct
tgl_message
*
M
)
{
void
tglf_
tglf_
fetch_geo_message
(
struct
tgl_message
*
M
)
{
memset
(
M
,
0
,
sizeof
(
*
M
));
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_geo_chat_message_empty
||
x
==
CODE_geo_chat_message
||
x
==
CODE_geo_chat_message_service
);
...
...
@@ -1254,7 +1255,7 @@ struct tgl_message *tglf_fetch_alloc_message (void) {
struct
tgl_message
*
tglf_fetch_alloc_geo_message
(
void
)
{
struct
tgl_message
*
M
=
talloc
(
sizeof
(
*
M
));
tglf_fetch_geo_message
(
M
);
tglf_
tglf_
fetch_geo_message
(
M
);
struct
tgl_message
*
M1
=
tree_lookup_message
(
message_tree
,
M
);
messages_allocated
++
;
if
(
M1
)
{
...
...
tgl-inner.h
0 → 100644
View file @
b12ca538
#ifndef __TGL_INNER_H__
#define __TGL_INNER_H__
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
#endif
tgl.c
View file @
b12ca538
...
...
@@ -3,6 +3,10 @@
#endif
#include "tgl.h"
#include "tools.h"
#include "mtproto-client.h"
#include <event2/event.h>
struct
tgl_state
tgl_state
;
...
...
@@ -21,3 +25,16 @@ void tgl_set_auth_file_path (const char *path) {
void
tgl_set_download_directory
(
const
char
*
path
)
{
tgl_state
.
downloads_directory
=
tstrdup
(
path
);
}
void
tgl_set_callback
(
struct
tgl_update_callback
*
cb
)
{
tgl_state
.
callback
=
*
cb
;
}
void
tgl_set_rsa_key
(
const
char
*
key
)
{
tgl_state
.
rsa_key
=
tstrdup
(
key
);
}
void
tgl_init
(
void
)
{
tgl_state
.
ev_base
=
event_base_new
();
tglmp_on_start
(
tgl_state
.
rsa_key
);
}
tgl.h
View file @
b12ca538
...
...
@@ -10,22 +10,37 @@
#define TGL_VERSION "0.9-beta"
// Do not modify this structure, unless you know what you do
struct
connection
;
struct
mtproto_methods
;
struct
session
;
struct
dc
;
struct
tgl_update_callback
{
void
(
*
new_msg
)(
struct
tgl_message
*
M
);
void
(
*
marked_read
)(
int
num
,
struct
tgl_message
*
list
[]);
void
(
*
logprintf
)(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
(
*
type_notification
)(
tgl_peer_id_t
id
,
struct
tgl_user
*
U
);
void
(
*
type_in_chat_notification
)(
tgl_peer_id_t
id
,
struct
tgl_user
*
U
,
tgl_peer_id_t
chat_id
,
struct
tgl_chat
*
C
);
void
(
*
type_notification
)(
struct
tgl_user
*
U
);
void
(
*
type_in_chat_notification
)(
struct
tgl_user
*
U
,
struct
tgl_chat
*
C
);
void
(
*
type_in_secret_chat_notification
)(
struct
tgl_secret_chat
*
E
);
void
(
*
status_notification
)(
struct
tgl_user
*
U
);
void
(
*
user_registered
)(
struct
tgl_user
*
U
);
void
(
*
user_activated
)(
struct
tgl_user
*
U
);
void
(
*
new_authorization
)(
const
char
*
device
,
const
char
*
location
);
void
(
*
secret_chat_request
)(
struct
tgl_secret_chat
*
E
);
void
(
*
secret_chat_established
)(
struct
tgl_secret_chat
*
E
);
void
(
*
secret_chat_deleted
)(
struct
tgl_secret_chat
*
E
);
};
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
struct
tgl_net_methods
{
int
(
*
write_out
)
(
struct
connection
*
c
,
void
*
data
,
int
len
);
int
(
*
read_in
)
(
struct
connection
*
c
,
void
*
data
,
int
len
);
int
(
*
read_in_lookup
)
(
struct
connection
*
c
,
void
*
data
,
int
len
);
int
(
*
flush_out
)
(
struct
connection
*
c
);
void
(
*
incr_out_packet_num
)
(
struct
connection
*
c
);
struct
dc
*
(
*
get_dc
)
(
struct
connection
*
c
);
struct
session
*
(
*
get_session
)
(
struct
connection
*
c
);
struct
connection
*
(
*
create_connection
)
(
const
char
*
host
,
int
port
,
struct
dc
*
dc
,
struct
session
*
session
,
struct
mtproto_methods
*
methods
);
};
#define E_ERROR 0
...
...
@@ -61,6 +76,10 @@ struct tgl_state {
char
*
downloads_directory
;
struct
tgl_update_callback
callback
;
struct
tgl_net_methods
*
net_methods
;
struct
event_base
*
ev_base
;
char
*
rsa_key
;
};
extern
struct
tgl_state
tgl_state
;
...
...
@@ -94,6 +113,8 @@ void tgl_set_binlog_mode (int mode);
void
tgl_set_binlog_path
(
const
char
*
path
);
void
tgl_set_auth_file_path
(
const
char
*
path
);
void
tgl_set_download_directory
(
const
char
*
path
);
void
tgl_set_callback
(
struct
tgl_update_callback
*
cb
);
void
tgl_set_rsa_key
(
const
char
*
key
);
static
inline
int
tgl_get_peer_type
(
tgl_peer_id_t
id
)
{
...
...
@@ -127,6 +148,10 @@ static inline void tgl_set_test_mode (void) {
tgl_state
.
test_mode
++
;
}
struct
pollfd
;
int
tgl_connections_make_poll_array
(
struct
pollfd
*
fds
,
int
max
);
void
tgl_connections_poll_result
(
struct
pollfd
*
fds
,
int
max
);
void
tgl_do_help_get_config
(
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_send_code
(
const
char
*
user
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
registered
,
const
char
*
hash
),
void
*
callback_extra
);
void
tgl_do_phone_call
(
const
char
*
user
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
...
...
@@ -168,8 +193,19 @@ void tgl_do_update_status (int online, void (*callback)(void *callback_extra, in
void
tgl_do_visualize_key
(
tgl_peer_id_t
id
,
unsigned
char
buf
[
16
]);
void
tgl_do_send_ping
(
struct
connection
*
c
);
//void tgl_do_get_suggested (void);
void
tgl_do_create_keys_end
(
struct
tgl_secret_chat
*
U
);
void
tgl_do_send_encr_chat_layer
(
struct
tgl_secret_chat
*
E
);
struct
mtproto_methods
{
int
(
*
ready
)
(
struct
connection
*
c
);
int
(
*
close
)
(
struct
connection
*
c
);
int
(
*
execute
)
(
struct
connection
*
c
,
int
op
,
int
len
);
};
void
tgl_init
(
void
);
void
tgl_dc_authorize
(
struct
dc
*
DC
);
#endif
tools.c
View file @
b12ca538
...
...
@@ -28,9 +28,12 @@
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <zlib.h>
#include <time.h>
#include <sys/time.h>
#include "interface.h"
//
#include "interface.h"
#include "tools.h"
#ifdef DEBUG
...
...
@@ -43,6 +46,15 @@ int used_blocks;
int
free_blocks_cnt
;
#endif
void
logprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
),
weak
));
void
logprintf
(
const
char
*
format
,
...)
{
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stdout
,
format
,
ap
);
va_end
(
ap
);
}
extern
int
verbosity
;
long
long
total_allocated_bytes
;
...
...
@@ -269,3 +281,35 @@ void texists (void *ptr, int size) {
assert
(
block_num
<
used_blocks
);
}
#endif
void
my_clock_gettime
(
int
clock_id
,
struct
timespec
*
T
)
{
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back too often
clock_serv_t
cclock
;
mach_timespec_t
mts
;
host_get_clock_service
(
mach_host_self
(),
CALENDAR_CLOCK
,
&
cclock
);
clock_get_time
(
cclock
,
&
mts
);
mach_port_deallocate
(
mach_task_self
(),
cclock
);
T
->
tv_sec
=
mts
.
tv_sec
;
T
->
tv_nsec
=
mts
.
tv_nsec
;
#else
assert
(
clock_gettime
(
clock_id
,
T
)
>=
0
);
#endif
}
double
get_double_time
(
void
)
{
struct
timespec
tv
;
my_clock_gettime
(
CLOCK_REALTIME
,
&
tv
);
return
tv
.
tv_sec
+
1e-9
*
tv
.
tv_nsec
;
}
void
tglt_secure_random
(
void
*
s
,
int
l
)
{
if
(
RAND_bytes
(
s
,
l
)
<
0
)
{
/*if (allow_weak_random) {
RAND_pseudo_bytes (s, l);
} else {*/
assert
(
0
&&
"End of random. If you want, you can start with -w"
);
//}
}
}
tools.h
View file @
b12ca538
...
...
@@ -20,6 +20,8 @@
#ifndef __TOOLS_H__
#define __TOOLS_H__
double
get_double_time
(
void
);
void
*
talloc
(
size_t
size
);
void
*
trealloc
(
void
*
ptr
,
size_t
old_size
,
size_t
size
);
void
*
talloc0
(
size_t
size
);
...
...
@@ -37,6 +39,8 @@ void tfree_secure (void *ptr, int size);
int
tsnprintf
(
char
*
buf
,
int
len
,
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
3
,
4
)));
int
tasprintf
(
char
**
res
,
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
void
tglt_secure_random
(
void
*
s
,
int
l
);
#ifdef DEBUG
void
tcheck
(
void
);
void
texists
(
void
*
ptr
,
int
size
);
...
...
tree.h
View file @
b12ca538
...
...
@@ -32,7 +32,7 @@ struct tree_ ## X_NAME { \
int y;\
};\
\
struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
st
atic inline st
ruct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
struct tree_ ## X_NAME *T = talloc (sizeof (*T));\
T->x = x;\
T->y = y;\
...
...
@@ -40,11 +40,11 @@ struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
return T;\
}\
\
void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
static inline
void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
tfree (T, sizeof (*T));\
}\
\
void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\
static inline
void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\
if (!T) {\
*L = *R = 0;\
} else {\
...
...
@@ -59,8 +59,8 @@ void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ##
}\
}\
\
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\
st
atic inline st
ruct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\
st
atic inline st
ruct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\
if (!T) {\
return new_tree_node_ ## X_NAME (x, y);\
} else {\
...
...
@@ -81,7 +81,7 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\
}\
\
struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\
st
atic inline st
ruct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\
if (!L || !R) {\
return L ? L : R;\
} else {\
...
...
@@ -95,8 +95,8 @@ struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct
}\
}\
\
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
st
atic inline st
ruct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\
st
atic inline st
ruct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
assert (T);\
int c = X_CMP (x, T->x);\
if (!c) {\
...
...
@@ -113,13 +113,13 @@ struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\
}\
\
X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\
static inline
X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\
if (!T) { return X_UNSET; } \
while (T->left) { T = T->left; }\
return T->x; \
} \
\
X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
static inline
X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
int c;\
while (T && (c = X_CMP (x, T->x))) {\
T = (c < 0 ? T->left : T->right);\
...
...
@@ -127,25 +127,25 @@ X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
return T ? T->x : X_UNSET;\
}\
\
void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\
static inline
void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\
if (!T) { return; } \
tree_act_ ## X_NAME (T->left, act); \
act (T->x); \
tree_act_ ## X_NAME (T->right, act); \
}\
\
void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\
static inline
void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\
if (!T) { return; } \
tree_act_ex_ ## X_NAME (T->left, act, extra); \
act (T->x, extra); \
tree_act_ex_ ## X_NAME (T->right, act, extra); \
}\
\
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
static inline
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\
return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \
}\
void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
static inline
void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return; }\
if (T->left) { \
assert (T->left->y <= T->y);\
...
...
@@ -158,7 +158,7 @@ void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
tree_check_ ## X_NAME (T->left); \
tree_check_ ## X_NAME (T->right); \
}\
struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \
st
atic inline st
ruct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\
tree_clear_ ## X_NAME (T->left); \
tree_clear_ ## X_NAME (T->right); \
...
...
updates.c
0 → 100644
View file @
b12ca538
#include "tgl.h"
#include "updates.h"
#include "mtproto-common.h"
#include "binlog.h"
#include "auto.h"
#include <assert.h>
void
tglu_fetch_pts
(
void
)
{
int
p
=
fetch_int
();
if
(
p
<=
tgl_state
.
pts
)
{
return
;
}
if
(
p
!=
tgl_state
.
pts
+
1
)
{
if
(
tgl_state
.
pts
)
{
//vlogprintf (E_NOTICE, "Hole in pts p = %d, pts = %d\n", p, tgl_state.pts);
// get difference should be here
tgl_state
.
pts
=
p
;
}
else
{
tgl_state
.
pts
=
p
;
}
}
else
{
tgl_state
.
pts
++
;
}
bl_do_set_pts
(
tgl_state
.
pts
);
}
void
tglu_fetch_qts
(
void
)
{
int
p
=
fetch_int
();
if
(
p
<=
tgl_state
.
qts
)
{
return
;
}
if
(
p
!=
tgl_state
.
qts
+
1
)
{
if
(
tgl_state
.
qts
)
{
//logprintf ("Hole in qts\n");
// get difference should be here
tgl_state
.
qts
=
p
;
}
else
{
tgl_state
.
qts
=
p
;
}
}
else
{
tgl_state
.
qts
++
;
}
bl_do_set_qts
(
tgl_state
.
qts
);
}
void
tglu_fetch_date
(
void
)
{
int
p
=
fetch_int
();
if
(
p
>
tgl_state
.
date
)
{
tgl_state
.
date
=
p
;
bl_do_set_date
(
tgl_state
.
date
);
}
}
void
tglu_fetch_seq
(
void
)
{
int
x
=
fetch_int
();
if
(
x
>
tgl_state
.
seq
+
1
)
{
vlogprintf
(
E_NOTICE
,
"Hole in seq: seq = %d, x = %d
\n
"
,
tgl_state
.
seq
,
x
);
//tgl_do_get_difference ();
//seq = x;
}
else
if
(
x
==
tgl_state
.
seq
+
1
)
{
tgl_state
.
seq
=
x
;
bl_do_set_seq
(
tgl_state
.
seq
);
}
}
static
void
fetch_dc_option
(
void
)
{
assert
(
fetch_int
()
==
CODE_dc_option
);
int
id
=
fetch_int
();
int
l1
=
prefetch_strlen
();
char
*
name
=
fetch_str
(
l1
);
int
l2
=
prefetch_strlen
();
char
*
ip
=
fetch_str
(
l2
);
int
port
=
fetch_int
();
vlogprintf
(
E_DEBUG
,
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
bl_do_dc_option
(
id
,
l1
,
name
,
l2
,
ip
,
port
);
}
void
tglu_work_update
(
struct
connection
*
c
,
long
long
msg_id
)
{
unsigned
op
=
fetch_int
();
switch
(
op
)
{
case
CODE_update_new_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
M
);
tglu_fetch_pts
();
//if (tgl_state.callback.new_msg) {
// tgl_state.callback.new_msg (M);
//}
//unread_messages ++;
//print_message (M);
//update_prompt ();
break
;
};
case
CODE_update_message_i_d
:
{
int
id
=
fetch_int
();
// id
int
new
=
fetch_long
();
// random_id
struct
tgl_message
*
M
=
tgl_message_get
(
new
);
if
(
M
)
{
bl_do_set_msg_id
(
M
,
id
);
}
}
break
;
case
CODE_update_read_messages
:
{
assert
(
fetch_int
()
==
(
int
)
CODE_vector
);
int
n
=
fetch_int
();
//int p = 0;
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
id
=
fetch_int
();
struct
tgl_message
*
M
=
tgl_message_get
(
id
);
if
(
M
)
{
bl_do_set_unread
(
M
,
0
);
}
}
tglu_fetch_pts
();
/*if (log_level >= 1) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" %d messages marked as read\n", n);
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_user_typing
:
{
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
tgl_state
.
callback
.
type_notification
&&
U
)
{
tgl_state
.
callback
.
type_notification
((
void
*
)
U
);
}
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (id, U);
printf (" is typing....\n");
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_chat_user_typing
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
U
&&
C
)
{
if
(
tgl_state
.
callback
.
type_in_chat_notification
)
{
tgl_state
.
callback
.
type_in_chat_notification
((
void
*
)
U
,
(
void
*
)
C
);
}
}
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (id, U);
printf (" is typing in chat ");
print_chat_name (chat_id, C);
printf ("....\n");
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_user_status
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
if
(
U
)
{
tglf_fetch_user_status
(
&
U
->
user
.
status
);
if
(
tgl_state
.
callback
.
status_notification
)
{
tgl_state
.
callback
.
status_notification
((
void
*
)
U
);
}
/*if (log_level >= 3) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" is now ");
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
pop_color ();
print_end ();
}*/
}
else
{
struct
tgl_user_status
t
;
tglf_fetch_user_status
(
&
t
);
}
}
break
;
case
CODE_update_user_name
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
UC
=
tgl_peer_get
(
user_id
);
if
(
UC
&&
(
UC
->
flags
&
FLAG_CREATED
))
{
int
l1
=
prefetch_strlen
();
char
*
f
=
fetch_str
(
l1
);
int
l2
=
prefetch_strlen
();
char
*
l
=
fetch_str
(
l2
);
struct
tgl_user
*
U
=
&
UC
->
user
;
bl_do_user_set_real_name
(
U
,
f
,
l1
,
l
,
l2
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" changed name to ");
print_user_name (user_id, UC);
printf ("\n");
pop_color ();
print_end ();*/
}
else
{
fetch_skip_str
();
fetch_skip_str
();
}
}
break
;
case
CODE_update_user_photo
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
UC
=
tgl_peer_get
(
user_id
);
tglu_fetch_date
();
if
(
UC
&&
(
UC
->
flags
&
FLAG_CREATED
))
{
struct
tgl_user
*
U
=
&
UC
->
user
;
unsigned
y
=
fetch_int
();
long
long
photo_id
;
struct
tgl_file_location
big
;
struct
tgl_file_location
small
;
memset
(
&
big
,
0
,
sizeof
(
big
));
memset
(
&
small
,
0
,
sizeof
(
small
));
if
(
y
==
CODE_user_profile_photo_empty
)
{
photo_id
=
0
;
big
.
dc
=
-
2
;
small
.
dc
=
-
2
;
}
else
{
assert
(
y
==
CODE_user_profile_photo
);
photo_id
=
fetch_long
();
tglf_fetch_file_location
(
&
small
);
tglf_fetch_file_location
(
&
big
);
}
bl_do_set_user_profile_photo
(
U
,
photo_id
,
&
big
,
&
small
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" updated profile photo\n");
pop_color ();
print_end ();*/
}
else
{
struct
tgl_file_location
t
;
unsigned
y
=
fetch_int
();
if
(
y
==
CODE_user_profile_photo_empty
)
{
}
else
{
assert
(
y
==
CODE_user_profile_photo
);
fetch_long
();
// photo_id
tglf_fetch_file_location
(
&
t
);
tglf_fetch_file_location
(
&
t
);
}
}
fetch_bool
();
}
break
;
case
CODE_update_restore_messages
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Restored %d messages\n", n);
pop_color ();
print_end ();*/
fetch_skip
(
n
);
tglu_fetch_pts
();
}
break
;
case
CODE_update_delete_messages
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Deleted %d messages\n", n);
pop_color ();
print_end ();*/
fetch_skip
(
n
);
tglu_fetch_pts
();
}
break
;
case
CODE_update_chat_participants
:
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_chat_participants
||
x
==
CODE_chat_participants_forbidden
);
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
int
n
=
0
;
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
if
(
x
==
CODE_chat_participants
)
{
bl_do_chat_set_admin
(
&
C
->
chat
,
fetch_int
());
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
struct
tgl_chat_user
*
users
=
talloc
(
12
*
n
);
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_chat_participant
);
users
[
i
].
user_id
=
fetch_int
();
users
[
i
].
inviter_id
=
fetch_int
();
users
[
i
].
date
=
fetch_int
();
}
int
version
=
fetch_int
();
bl_do_chat_set_participants
(
&
C
->
chat
,
version
,
n
,
users
);
}
}
else
{
if
(
x
==
CODE_chat_participants
)
{
fetch_int
();
// admin_id
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
fetch_skip
(
n
*
4
);
fetch_int
();
// version
}
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
print_chat_name (chat_id, C);
if (x == CODE_chat_participants) {
printf (" changed list: now %d members\n", n);
} else {
printf (" changed list, but we are forbidden to know about it (Why this update even was sent to us?\n");
}
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_contact_registered
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
fetch_int
();
// date
if
(
tgl_state
.
callback
.
user_registered
&&
U
)
{
tgl_state
.
callback
.
user_registered
((
void
*
)
U
);
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" registered\n");
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_contact_link
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Updated link with user ");
print_user_name (user_id, U);
printf ("\n");
pop_color ();
print_end ();*/
unsigned
t
=
fetch_int
();
assert
(
t
==
CODE_contacts_my_link_empty
||
t
==
CODE_contacts_my_link_requested
||
t
==
CODE_contacts_my_link_contact
);
if
(
t
==
CODE_contacts_my_link_requested
)
{
fetch_bool
();
// has_phone
}
t
=
fetch_int
();
assert
(
t
==
CODE_contacts_foreign_link_unknown
||
t
==
CODE_contacts_foreign_link_requested
||
t
==
CODE_contacts_foreign_link_mutual
);
if
(
t
==
CODE_contacts_foreign_link_requested
)
{
fetch_bool
();
// has_phone
}
if
(
U
)
{}
}
break
;
case
CODE_update_activation
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
if
(
tgl_state
.
callback
.
user_activated
&&
U
)
{
tgl_state
.
callback
.
user_activated
((
void
*
)
U
);
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" activated\n");
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_new_authorization
:
{
fetch_long
();
// auth_key_id
fetch_int
();
// date
char
*
s
=
fetch_str_dup
();
char
*
location
=
fetch_str_dup
();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" New autorization: device='%s' location='%s'\n",
s, location);
pop_color ();
print_end ();*/
if
(
tgl_state
.
callback
.
new_authorization
)
{
tgl_state
.
callback
.
new_authorization
(
s
,
location
);
}
tfree_str
(
s
);
tfree_str
(
location
);
}
break
;
case
CODE_update_new_geo_chat_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_geo_message
();
assert
(
M
);
//if (tgl_state.callback.new_msg) {
// tgl_state.callback.new_msg (M);
//}
//unread_messages ++;
//print_message (M);
//update_prompt ();
}
break
;
case
CODE_update_new_encrypted_message
:
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_encrypted_message
();
assert
(
M
);
//unread_messages ++;
//print_message (M);
//update_prompt ();
tglu_fetch_qts
();
//if (tgl_state.callback.new_msg) {
// tgl_state.callback.new_msg (M);
//}
}
break
;
case
CODE_update_encryption
:
{
struct
tgl_secret_chat
*
E
=
tglf_fetch_alloc_encrypted_chat
();
vlogprintf
(
E_DEBUG
,
"Secret chat state = %d
\n
"
,
E
->
state
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
switch (E->state) {
case sc_none:
break;
case sc_waiting:
printf (" Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in wait state\n");
break;
case sc_request:
printf (" Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in request state. Sending request ok\n");
break;
case sc_ok:
printf (" Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in ok state\n");
break;
case sc_deleted:
printf (" Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in deleted state\n");
break;
}
pop_color ();
print_end ();*/
if
(
E
->
state
==
sc_request
)
{
if
(
tgl_state
.
callback
.
secret_chat_request
)
{
tgl_state
.
callback
.
secret_chat_request
(
E
);
}
}
else
if
(
E
->
state
==
sc_ok
)
{
if
(
tgl_state
.
callback
.
secret_chat_established
)
{
tgl_state
.
callback
.
secret_chat_established
(
E
);
}
}
else
if
(
E
->
state
==
sc_deleted
)
{
if
(
tgl_state
.
callback
.
secret_chat_deleted
)
{
tgl_state
.
callback
.
secret_chat_deleted
(
E
);
}
}
if
(
E
->
state
==
sc_ok
)
{
tgl_do_send_encr_chat_layer
(
E
);
}
fetch_int
();
// date
}
break
;
case
CODE_update_encrypted_chat_typing
:
{
tgl_peer_id_t
id
=
TGL_MK_ENCR_CHAT
(
fetch_int
());
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
if
(
P
)
{
if
(
tgl_state
.
callback
.
type_in_secret_chat_notification
)
{
tgl_state
.
callback
.
type_in_secret_chat_notification
((
void
*
)
P
);
}
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
if (P) {
printf (" User ");
tgl_peer_id_t user_id = TGL_MK_USER (P->encr_chat.user_id);
print_user_name (user_id, tgl_peer_get (user_id));
printf (" typing in secret chat ");
print_encr_chat_name (id, P);
printf ("\n");
} else {
printf (" Some user is typing in unknown secret chat\n");
}
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_encrypted_messages_read
:
{
tgl_peer_id_t
id
=
TGL_MK_ENCR_CHAT
(
fetch_int
());
// chat_id
fetch_int
();
// max_date
fetch_int
();
// date
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
//int x = -1;
if
(
P
&&
P
->
last
)
{
//x = 0;
struct
tgl_message
*
M
=
P
->
last
;
while
(
M
&&
(
!
M
->
out
||
M
->
unread
))
{
if
(
M
->
out
)
{
bl_do_set_unread
(
M
,
0
);
}
M
=
M
->
next
;
}
}
/*if (log_level >= 1) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Encrypted chat ");
print_encr_chat_name_full (id, tgl_peer_get (id));
printf (": %d messages marked read \n", x);
pop_color ();
print_end ();
}*/
}
break
;
case
CODE_update_chat_participant_add
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_id_t
inviter_id
=
TGL_MK_USER
(
fetch_int
());
int
version
=
fetch_int
();
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
bl_do_chat_add_user
(
&
C
->
chat
,
version
,
tgl_get_peer_id
(
user_id
),
tgl_get_peer_id
(
inviter_id
),
time
(
0
));
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
print_chat_name (chat_id, tgl_peer_get (chat_id));
printf (": user ");
print_user_name (user_id, tgl_peer_get (user_id));
printf (" added by user ");
print_user_name (inviter_id, tgl_peer_get (inviter_id));
printf ("\n");
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_chat_participant_delete
:
{
tgl_peer_id_t
chat_id
=
TGL_MK_CHAT
(
fetch_int
());
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
int
version
=
fetch_int
();
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
if
(
C
&&
(
C
->
flags
&
FLAG_CREATED
))
{
bl_do_chat_del_user
(
&
C
->
chat
,
version
,
tgl_get_peer_id
(
user_id
));
}
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
print_chat_name (chat_id, tgl_peer_get (chat_id));
printf (": user ");
print_user_name (user_id, tgl_peer_get (user_id));
printf (" deleted\n");
pop_color ();
print_end ();*/
}
break
;
case
CODE_update_dc_options
:
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
assert
(
n
>=
0
);
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fetch_dc_option
();
}
}
break
;
case
CODE_update_user_blocked
:
{
int
id
=
fetch_int
();
int
blocked
=
fetch_bool
();
tgl_peer_t
*
P
=
tgl_peer_get
(
TGL_MK_USER
(
id
));
if
(
P
&&
(
P
->
flags
&
FLAG_CREATED
))
{
bl_do_user_set_blocked
(
&
P
->
user
,
blocked
);
}
}
break
;
case
CODE_update_notify_settings
:
{
assert
(
skip_type_any
(
TYPE_TO_PARAM
(
notify_peer
))
>=
0
);
assert
(
skip_type_any
(
TYPE_TO_PARAM
(
peer_notify_settings
))
>=
0
);
}
break
;
default:
vlogprintf
(
E_ERROR
,
"Unknown update type %08x
\n
"
,
op
);
;
}
}
void
tglu_work_update_short
(
struct
connection
*
c
,
long
long
msg_id
)
{
int
*
save
=
in_ptr
;
assert
(
!
skip_type_any
(
TYPE_TO_PARAM
(
updates
)));
int
*
save_end
=
in_ptr
;
in_ptr
=
save
;
assert
(
fetch_int
()
==
CODE_update_short
);
tglu_work_update
(
c
,
msg_id
);
tglu_fetch_date
();
assert
(
save_end
==
in_ptr
);
}
void
tglu_work_updates
(
struct
connection
*
c
,
long
long
msg_id
)
{
int
*
save
=
in_ptr
;
assert
(
!
skip_type_any
(
TYPE_TO_PARAM
(
updates
)));
int
*
save_end
=
in_ptr
;
in_ptr
=
save
;
assert
(
fetch_int
()
==
CODE_updates
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglu_work_update
(
c
,
msg_id
);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_chat
();
}
bl_do_set_date
(
fetch_int
());
bl_do_set_seq
(
fetch_int
());
assert
(
save_end
==
in_ptr
);
}
void
tglu_work_update_short_message
(
struct
connection
*
c
,
long
long
msg_id
)
{
int
*
save
=
in_ptr
;
assert
(
!
skip_type_any
(
TYPE_TO_PARAM
(
updates
)));
int
*
save_end
=
in_ptr
;
in_ptr
=
save
;
assert
(
fetch_int
()
==
(
int
)
CODE_update_short_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message_short
();
assert
(
M
);
/*unread_messages ++;
print_message (M);
update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}*/
assert
(
save_end
==
in_ptr
);
}
void
tglu_work_update_short_chat_message
(
struct
connection
*
c
,
long
long
msg_id
)
{
int
*
save
=
in_ptr
;
assert
(
!
skip_type_any
(
TYPE_TO_PARAM
(
updates
)));
int
*
save_end
=
in_ptr
;
in_ptr
=
save
;
assert
(
fetch_int
()
==
CODE_update_short_chat_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message_short_chat
();
assert
(
M
);
/*unread_messages ++;
print_message (M);
update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}*/
assert
(
save_end
==
in_ptr
);
}
void
tglu_work_updates_to_long
(
struct
connection
*
c
,
long
long
msg_id
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_too_long
);
vlogprintf
(
E_NOTICE
,
"updates to long... Getting difference
\n
"
);
tgl_do_get_difference
(
0
,
0
,
0
);
}
updates.h
0 → 100644
View file @
b12ca538
#ifndef __UPDATES_H__
#define __UPDATES_H__
struct
connection
;
void
tglu_work_update
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_work_updates_to_long
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_work_update_short_chat_message
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_work_update_short_message
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_work_update_short
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_work_updates
(
struct
connection
*
c
,
long
long
msg_id
);
void
tglu_fetch_pts
(
void
);
void
tglu_fetch_qts
(
void
);
void
tglu_fetch_seq
(
void
);
void
tglu_fetch_date
(
void
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment