many updates
This commit is contained in:
parent
fe08f0c5e7
commit
b12ca53816
@ -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
|
||||
|
3
binlog.c
3
binlog.c
@ -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;
|
||||
}
|
||||
|
||||
|
318
loop.c
318
loop.c
@ -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]);
|
||||
|
7
main.c
7
main.c
@ -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 ();
|
||||
|
1165
mtproto-client.c
1165
mtproto-client.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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__)
|
||||
|
@ -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);
|
||||
|
294
net.c
294
net.c
@ -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) {
|
||||
static struct 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;
|
||||
static struct 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->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;
|
||||
}
|
||||
|
84
net.h
84
net.h
@ -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 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);
|
||||
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 create_all_outbound_connections (void);
|
||||
void tgln_insert_msg_id (struct session *S, long long id);
|
||||
|
||||
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);
|
||||
|
||||
//void create_all_outbound_connections (void);
|
||||
|
||||
//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
|
||||
|
256
queries.c
256
queries.c
@ -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);
|
||||
|
||||
if (q->session->c->out_bytes >= 100000) {
|
||||
|
||||
static struct timeval ptimeout = { QUERY_TIMEOUT, 0};
|
||||
event_add (q->ev, &ptimeout);
|
||||
|
||||
/*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);
|
||||
}
|
||||
|
24
queries.h
24
queries.h
@ -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);
|
||||
|
||||
|
27
structures.c
27
structures.c
@ -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) {
|
||||
|
11
tgl-inner.h
Normal file
11
tgl-inner.h
Normal file
@ -0,0 +1,11 @@
|
||||
#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
|
17
tgl.c
17
tgl.c
@ -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);
|
||||
}
|
||||
|
52
tgl.h
52
tgl.h
@ -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
|
||||
|
46
tools.c
46
tools.c
@ -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");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
4
tools.h
4
tools.h
@ -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);
|
||||
|
30
tree.h
30
tree.h
@ -32,7 +32,7 @@ struct tree_ ## X_NAME { \
|
||||
int y;\
|
||||
};\
|
||||
\
|
||||
struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
|
||||
static inline struct 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) {\
|
||||
static inline struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\
|
||||
static inline struct 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) {\
|
||||
static inline struct 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) {\
|
||||
static inline struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\
|
||||
static inline struct 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) { \
|
||||
static inline struct 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); \
|
||||
|
728
updates.c
Normal file
728
updates.c
Normal file
@ -0,0 +1,728 @@
|
||||
#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);
|
||||
}
|
15
updates.h
Normal file
15
updates.h
Normal file
@ -0,0 +1,15 @@
|
||||
#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
|
Loading…
Reference in New Issue
Block a user