Commit b12ca538 authored by Vysheng's avatar Vysheng

many updates

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