diff --git a/binlog.c b/binlog.c index 139bcb0..3166f87 100644 --- a/binlog.c +++ b/binlog.c @@ -39,7 +39,6 @@ #include "net.h" #include "include.h" #include "mtproto-client.h" -#include "loop.h" #include "tgl.h" #include "auto.h" @@ -52,7 +51,7 @@ static int binlog_buffer[BINLOG_BUFFER_SIZE]; static int *rptr; static int *wptr; -static int binlog_fd; +//static int tgl_state.binlog_fd; static int in_replay_log; // should be used ONLY for DEBUG @@ -516,6 +515,16 @@ static int fetch_comb_binlog_encr_chat_update_seq (void *extra) { return 0; } +static int fetch_comb_binlog_encr_chat_set_seq (void *extra) { + tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); + tgl_peer_t *_U = tgl_peer_get (id); + assert (_U); + _U->encr_chat.in_seq_no = fetch_int (); + _U->encr_chat.last_in_seq_no = fetch_int (); + _U->encr_chat.out_seq_no = fetch_int (); + return 0; +} + static int fetch_comb_binlog_encr_chat_init (void *extra) { tgl_peer_t *P = talloc0 (sizeof (*P)); P->id = TGL_MK_ENCR_CHAT (fetch_int ()); @@ -1312,6 +1321,7 @@ static void replay_log_event (void) { FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_accepted) FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_key) FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_update_seq) + FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_seq) FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_init) FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_create) @@ -1467,14 +1477,14 @@ void tgl_replay_log (void) { static int b_packet_buffer[PACKET_BUFFER_SIZE]; void tgl_reopen_binlog_for_writing (void) { - binlog_fd = open (get_binlog_file_name (), O_WRONLY); - if (binlog_fd < 0) { + tgl_state.binlog_fd = open (get_binlog_file_name (), O_WRONLY); + if (tgl_state.binlog_fd < 0) { perror ("binlog open"); exit (2); } - assert (lseek (binlog_fd, binlog_pos, SEEK_SET) == binlog_pos); - if (flock (binlog_fd, LOCK_EX | LOCK_NB) < 0) { + assert (lseek (tgl_state.binlog_fd, binlog_pos, SEEK_SET) == binlog_pos); + if (flock (tgl_state.binlog_fd, LOCK_EX | LOCK_NB) < 0) { perror ("get lock"); exit (2); } @@ -1493,8 +1503,8 @@ static void add_log_event (const int *data, int len) { assert (rptr == wptr); } if (tgl_state.binlog_enabled) { - assert (binlog_fd > 0); - assert (write (binlog_fd, data, len) == len); + assert (tgl_state.binlog_fd > 0); + assert (write (tgl_state.binlog_fd, data, len) == len); } in_ptr = in; in_end = end; @@ -1805,6 +1815,16 @@ void bl_do_encr_chat_update_seq (struct tgl_secret_chat *E, int in_seq_no, int o add_log_event (ev, 16); } +void bl_do_encr_chat_set_seq (struct tgl_secret_chat *E, int in_seq_no, int last_in_seq_no, int out_seq_no) { + int *ev = alloc_log_event (20); + ev[0] = CODE_binlog_encr_chat_set_seq; + ev[1] = tgl_get_peer_id (E->id); + ev[2] = in_seq_no; + ev[3] = last_in_seq_no; + ev[4] = out_seq_no; + add_log_event (ev, 20); +} + void bl_do_set_dh_params (int root, unsigned char prime[], int version) { int *ev = alloc_log_event (268); ev[0] = CODE_binlog_set_dh_params; diff --git a/binlog.h b/binlog.h index 9b200b3..858752c 100644 --- a/binlog.h +++ b/binlog.h @@ -52,6 +52,7 @@ void bl_do_encr_chat_accepted (struct tgl_secret_chat *U, const unsigned char g_ void bl_do_encr_chat_set_key (struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint); void bl_do_encr_chat_init (int id, int user_id, unsigned char random[], unsigned char g_a[]); void bl_do_encr_chat_update_seq (struct tgl_secret_chat *E, int in_seq_no, int out_seq_no); +void bl_do_encr_chat_set_seq (struct tgl_secret_chat *E, int in_seq_no, int last_in_seq_no, int out_seq_no); void bl_do_dc_signed (int id); void bl_do_set_working_dc (int num); diff --git a/binlog.tl b/binlog.tl index 37bb2c3..9557b0c 100644 --- a/binlog.tl +++ b/binlog.tl @@ -43,6 +43,7 @@ binlog.encrChatSetState id:int state:int = binlog.Update; binlog.encrChatSetKey id:int key:64*[int] fingerprint:long = binlog.Update; binlog.encrChatUpdateSeq id:int in_seq_no:int out_seq_no:int = binlog.Update; +binlog.encrChatSetSeq id:int in_seq_no:int last_in_seq_no:int out_seq_no:int = binlog.Update; binlog.chatCreate id:int flags:int title:string user_num:int date:int version:int photo_big:%binlog.FileLocation photo_small:%binlog.FileLocation = binlog.Update; binlog.chatChangeFlags id:int set_flags:int clear_flags:int = binlog.Update; diff --git a/interface.c b/interface.c index eec3f85..087e7cf 100644 --- a/interface.c +++ b/interface.c @@ -1726,6 +1726,9 @@ void print_message_gw (struct tgl_message *M) { lua_new_msg (M); #endif if (!binlog_read) { return; } + if (tgl_get_peer_type (M->to_id) == TGL_PEER_ENCR_CHAT) { + write_secret_chat_file (); + } if (alert_sound) { play_sound (); } diff --git a/loop.c b/loop.c index f6dcb54..50f177a 100644 --- a/loop.c +++ b/loop.c @@ -458,6 +458,9 @@ void write_secret_chat (tgl_peer_t *_P, void *extra) { assert (write (fd, &P->state, 4) == 4); assert (write (fd, &P->key_fingerprint, 8) == 8); assert (write (fd, &P->key, 256) == 256); + assert (write (fd, &P->in_seq_no, 4) == 4); + assert (write (fd, &P->last_in_seq_no, 4) == 4); + assert (write (fd, &P->out_seq_no, 4) == 4); } void write_secret_chat_file (void) { @@ -466,7 +469,7 @@ void write_secret_chat_file (void) { assert (secret_chat_fd >= 0); int x = SECRET_CHAT_FILE_MAGIC; assert (write (secret_chat_fd, &x, 4) == 4); - x = 0; + x = 1; assert (write (secret_chat_fd, &x, 4) == 4); // version assert (write (secret_chat_fd, &x, 4) == 4); // num @@ -559,7 +562,7 @@ void read_auth_file (void) { close (auth_file_fd); } -void read_secret_chat (int fd) { +void read_secret_chat (int fd, int v) { int id, l, user_id, admin_id, date, ttl, layer, state; long long access_hash, key_fingerprint; static char s[1000]; @@ -578,6 +581,12 @@ void read_secret_chat (int fd) { assert (read (fd, &state, 4) == 4); assert (read (fd, &key_fingerprint, 8) == 8); assert (read (fd, &key, 256) == 256); + int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0; + if (v >= 1) { + assert (read (fd, &in_seq_no, 4) == 4); + assert (read (fd, &last_in_seq_no, 4) == 4); + assert (read (fd, &out_seq_no, 4) == 4); + } bl_do_encr_chat_create (id, user_id, admin_id, s, l); struct tgl_secret_chat *P = (void *)tgl_peer_get (TGL_MK_ENCR_CHAT (id)); @@ -588,6 +597,9 @@ void read_secret_chat (int fd) { bl_do_encr_chat_set_access_hash (P, access_hash); bl_do_encr_chat_set_state (P, state); bl_do_encr_chat_set_key (P, key, key_fingerprint); + if (v >= 1) { + bl_do_encr_chat_set_seq (P, in_seq_no, last_in_seq_no, out_seq_no); + } } void read_secret_chat_file (void) { @@ -598,12 +610,13 @@ void read_secret_chat_file (void) { int x; if (read (secret_chat_fd, &x, 4) < 4) { close (secret_chat_fd); return; } if (x != SECRET_CHAT_FILE_MAGIC) { close (secret_chat_fd); return; } - assert (read (secret_chat_fd, &x, 4) == 4); - assert (!x); // version + int v = 0; + assert (read (secret_chat_fd, &v, 4) == 4); + assert (v == 0 || v == 1); // version assert (read (secret_chat_fd, &x, 4) == 4); assert (x >= 0); while (x --> 0) { - read_secret_chat (secret_chat_fd); + read_secret_chat (secret_chat_fd, v); } close (secret_chat_fd); } diff --git a/mtproto-client.c b/mtproto-client.c index 1dab523..f3e079b 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -90,7 +90,6 @@ static inline unsigned __builtin_bswap32(unsigned x) { #endif //int verbosity; -static int auth_success; //static enum tgl_dc_state c_state; //extern int binlog_enabled; //extern int disable_auto_accept; @@ -713,7 +712,6 @@ static int process_auth_complete (struct connection *c UU, char *packet, int len D->state = st_authorized; //return 1; vlogprintf (E_DEBUG, "Auth success\n"); - auth_success ++; if (temp_key) { //D->flags |= 2; @@ -1308,13 +1306,8 @@ void tglmp_on_start (void) { pk_fingerprint = tgl_do_compute_rsa_key_fingerprint (pubKey); } -//int auth_ok (void) { -// return auth_success; -//} - void tgl_dc_authorize (struct tgl_dc *DC) { //c_state = 0; - //auth_success = 0; if (!DC->sessions[0]) { tglmp_dc_create_session (DC); } diff --git a/queries.c b/queries.c index ebc10e1..b973758 100644 --- a/queries.c +++ b/queries.c @@ -39,7 +39,6 @@ #include "tree.h" #include "mtproto-common.h" //#include "telegram.h" -#include "loop.h" #include "structures.h" //#include "interface.h" //#include "net.h" diff --git a/structures.c b/structures.c index 3f0570b..f995fcc 100644 --- a/structures.c +++ b/structures.c @@ -28,7 +28,6 @@ #include "mtproto-common.h" //#include "telegram.h" #include "tree.h" -#include "loop.h" #include #include #include @@ -41,10 +40,6 @@ #define sha1 SHA1 -#ifndef TGL_MAX_PEER_NUM -# define TGL_MAX_PEER_NUM 100000 -#endif - static int id_cmp (struct tgl_message *M1, struct tgl_message *M2); #define peer_cmp(a,b) (tgl_cmp_peer_id (a->id, b->id)) #define peer_cmp_name(a,b) (strcmp (a->print_name, b->print_name)) @@ -53,24 +48,8 @@ DEFINE_TREE(peer_by_name,tgl_peer_t *,peer_cmp_name,0) DEFINE_TREE(message,struct tgl_message *,id_cmp,0) -static struct tgl_message message_list = { - .next_use = &message_list, - .prev_use = &message_list -}; -static struct tree_peer *tgl_peer_tree; -static struct tree_peer_by_name *peer_by_name_tree; -static struct tree_message *message_tree; -static struct tree_message *message_unsent_tree; -static int users_allocated; -static int chats_allocated; -static int messages_allocated; -static int peer_num; -static int encr_chats_allocated; -static int geo_chats_allocated; - -static tgl_peer_t *Peers[TGL_MAX_PEER_NUM]; @@ -1330,6 +1309,7 @@ void tglf_fetch_encrypted_message (struct tgl_message *M) { if (!drop) { if (in_seq_no >= 0 && out_seq_no >= 0) { bl_do_encr_chat_update_seq ((void *)P, in_seq_no / 2 + 1, out_seq_no / 2); + assert (P->encr_chat.in_seq_no == in_seq_no / 2 + 1); } } } @@ -1360,17 +1340,30 @@ static int id_cmp (struct tgl_message *M1, struct tgl_message *M2) { else { return 0; } } +static void increase_peer_size (void) { + if (tgl_state.peer_num == tgl_state.peer_size) { + int new_size = tgl_state.peer_size ? 2 * tgl_state.peer_size : 10; + int old_size = tgl_state.peer_size; + if (old_size) { + tgl_state.Peers = trealloc (tgl_state.Peers, old_size * sizeof (void *), new_size * sizeof (void *)); + } else { + tgl_state.Peers = talloc (new_size * sizeof (void *)); + } + tgl_state.peer_size = new_size; + } +} + struct tgl_user *tglf_fetch_alloc_user (void) { int data[2]; prefetch_data (data, 8); tgl_peer_t *U = tgl_peer_get (TGL_MK_USER (data[1])); if (!U) { - users_allocated ++; + tgl_state.users_allocated ++; U = talloc0 (sizeof (*U)); U->id = TGL_MK_USER (data[1]); - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, U, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = U; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, U, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = U; } tglf_fetch_user (&U->user); return &U->user; @@ -1383,10 +1376,10 @@ struct tgl_secret_chat *tglf_fetch_alloc_encrypted_chat (void) { if (!U) { U = talloc0 (sizeof (*U)); U->id = TGL_MK_ENCR_CHAT (data[1]); - encr_chats_allocated ++; - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, U, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = U; + tgl_state.encr_chats_allocated ++; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, U, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = U; } tglf_fetch_encrypted_chat (&U->encr_chat); return &U->encr_chat; @@ -1400,13 +1393,13 @@ struct tgl_user *tglf_fetch_alloc_user_full (void) { tglf_fetch_user_full (&U->user); return &U->user; } else { - users_allocated ++; + tgl_state.users_allocated ++; U = talloc0 (sizeof (*U)); U->id = TGL_MK_USER (data[2]); - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, U, lrand48 ()); + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, U, lrand48 ()); tglf_fetch_user_full (&U->user); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = U; + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = U; return &U->user; } } @@ -1426,8 +1419,8 @@ struct tgl_message *tglf_fetch_alloc_message (void) { struct tgl_message *tglf_fetch_alloc_geo_message (void) { struct tgl_message *M = talloc (sizeof (*M)); tglf_tglf_fetch_geo_message (M); - struct tgl_message *M1 = tree_lookup_message (message_tree, M); - messages_allocated ++; + struct tgl_message *M1 = tree_lookup_message (tgl_state.message_tree, M); + tgl_state.messages_allocated ++; if (M1) { tglm_message_del_use (M1); tglm_message_del_peer (M1); @@ -1436,12 +1429,12 @@ struct tgl_message *tglf_fetch_alloc_geo_message (void) { tfree (M, sizeof (*M)); tglm_message_add_use (M1); tglm_message_add_peer (M1); - messages_allocated --; + tgl_state.messages_allocated --; return M1; } else { tglm_message_add_use (M); tglm_message_add_peer (M); - message_tree = tree_insert_message (message_tree, M, lrand48 ()); + tgl_state.message_tree = tree_insert_message (tgl_state.message_tree, M, lrand48 ()); return M; } } @@ -1455,7 +1448,7 @@ struct tgl_message *tglf_fetch_alloc_encrypted_message (void) { M = talloc0 (sizeof (*M)); M->id = *(long long *)(data + 1); tglm_message_insert_tree (M); - messages_allocated ++; + tgl_state.messages_allocated ++; assert (tgl_message_get (M->id) == M); } tglf_fetch_encrypted_message (M); @@ -1471,7 +1464,7 @@ struct tgl_message *tglf_fetch_alloc_message_short (void) { M = talloc0 (sizeof (*M)); M->id = data[0]; tglm_message_insert_tree (M); - messages_allocated ++; + tgl_state.messages_allocated ++; } tglf_fetch_message_short (M); return M; @@ -1486,7 +1479,7 @@ struct tgl_message *tglf_fetch_alloc_message_short_chat (void) { M = talloc0 (sizeof (*M)); M->id = data[0]; tglm_message_insert_tree (M); - messages_allocated ++; + tgl_state.messages_allocated ++; } tglf_fetch_message_short_chat (M); return M; @@ -1497,12 +1490,12 @@ struct tgl_chat *tglf_fetch_alloc_chat (void) { prefetch_data (data, 8); tgl_peer_t *U = tgl_peer_get (TGL_MK_CHAT (data[1])); if (!U) { - chats_allocated ++; + tgl_state.chats_allocated ++; U = talloc0 (sizeof (*U)); U->id = TGL_MK_CHAT (data[1]); - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, U, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = U; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, U, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = U; } tglf_fetch_chat (&U->chat); return &U->chat; @@ -1516,37 +1509,37 @@ struct tgl_chat *tglf_fetch_alloc_chat_full (void) { tglf_fetch_chat_full (&U->chat); return &U->chat; } else { - chats_allocated ++; + tgl_state.chats_allocated ++; U = talloc0 (sizeof (*U)); U->id = TGL_MK_CHAT (data[2]); - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, U, lrand48 ()); + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, U, lrand48 ()); tglf_fetch_chat_full (&U->chat); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = U; + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = U; return &U->chat; } } /* }}} */ void tglp_insert_encrypted_chat (tgl_peer_t *P) { - encr_chats_allocated ++; - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, P, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = P; + tgl_state.encr_chats_allocated ++; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, P, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = P; } void tglp_insert_user (tgl_peer_t *P) { - users_allocated ++; - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, P, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = P; + tgl_state.users_allocated ++; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, P, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = P; } void tglp_insert_chat (tgl_peer_t *P) { - chats_allocated ++; - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, P, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = P; + tgl_state.chats_allocated ++; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, P, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = P; } void tgl_insert_empty_user (int uid) { @@ -1737,8 +1730,8 @@ void tglm_message_del_use (struct tgl_message *M) { } void tglm_message_add_use (struct tgl_message *M) { - M->next_use = message_list.next_use; - M->prev_use = &message_list; + M->next_use = tgl_state.message_list.next_use; + M->prev_use = &tgl_state.message_list; M->next_use->prev_use = M; M->prev_use->next_use = M; } @@ -1756,21 +1749,21 @@ void tglm_message_add_peer (struct tgl_message *M) { P->id = id; switch (tgl_get_peer_type (id)) { case TGL_PEER_USER: - users_allocated ++; + tgl_state.users_allocated ++; break; case TGL_PEER_CHAT: - chats_allocated ++; + tgl_state.chats_allocated ++; break; case TGL_PEER_GEO_CHAT: - geo_chats_allocated ++; + tgl_state.geo_chats_allocated ++; break; case TGL_PEER_ENCR_CHAT: - encr_chats_allocated ++; + tgl_state.encr_chats_allocated ++; break; } - tgl_peer_tree = tree_insert_peer (tgl_peer_tree, P, lrand48 ()); - assert (peer_num < TGL_MAX_PEER_NUM); - Peers[peer_num ++] = P; + tgl_state.peer_tree = tree_insert_peer (tgl_state.peer_tree, P, lrand48 ()); + increase_peer_size (); + tgl_state.Peers[tgl_state.peer_num ++] = P; } if (!P->last) { P->last = M; @@ -1824,24 +1817,24 @@ struct tgl_message *tglm_message_alloc (long long id) { struct tgl_message *M = talloc0 (sizeof (*M)); M->id = id; tglm_message_insert_tree (M); - messages_allocated ++; + tgl_state.messages_allocated ++; return M; } void tglm_update_message_id (struct tgl_message *M, long long id) { - message_tree = tree_delete_message (message_tree, M); + tgl_state.message_tree = tree_delete_message (tgl_state.message_tree, M); M->id = id; - message_tree = tree_insert_message (message_tree, M, lrand48 ()); + tgl_state.message_tree = tree_insert_message (tgl_state.message_tree, M, lrand48 ()); } void tglm_message_insert_tree (struct tgl_message *M) { assert (M->id); - message_tree = tree_insert_message (message_tree, M, lrand48 ()); + tgl_state.message_tree = tree_insert_message (tgl_state.message_tree, M, lrand48 ()); } void tglm_message_remove_tree (struct tgl_message *M) { assert (M->id); - message_tree = tree_delete_message (message_tree, M); + tgl_state.message_tree = tree_delete_message (tgl_state.message_tree, M); } void tglm_message_insert (struct tgl_message *M) { @@ -1850,11 +1843,11 @@ void tglm_message_insert (struct tgl_message *M) { } void tglm_message_insert_unsent (struct tgl_message *M) { - message_unsent_tree = tree_insert_message (message_unsent_tree, M, lrand48 ()); + tgl_state.message_unsent_tree = tree_insert_message (tgl_state.message_unsent_tree, M, lrand48 ()); } void tglm_message_remove_unsent (struct tgl_message *M) { - message_unsent_tree = tree_delete_message (message_unsent_tree, M); + tgl_state.message_unsent_tree = tree_delete_message (tgl_state.message_unsent_tree, M); } static void __send_msg (struct tgl_message *M) { @@ -1870,48 +1863,48 @@ static void __send_msg (struct tgl_message *M) { } void tglm_send_all_unsent (void ) { - tree_act_message (message_unsent_tree, __send_msg); + tree_act_message (tgl_state.message_unsent_tree, __send_msg); } /* }}} */ void tglp_peer_insert_name (tgl_peer_t *P) { - peer_by_name_tree = tree_insert_peer_by_name (peer_by_name_tree, P, lrand48 ()); + tgl_state.peer_by_name_tree = tree_insert_peer_by_name (tgl_state.peer_by_name_tree, P, lrand48 ()); } void tglp_peer_delete_name (tgl_peer_t *P) { - peer_by_name_tree = tree_delete_peer_by_name (peer_by_name_tree, P); + tgl_state.peer_by_name_tree = tree_delete_peer_by_name (tgl_state.peer_by_name_tree, P); } tgl_peer_t *tgl_peer_get (tgl_peer_id_t id) { static tgl_peer_t U; U.id = id; - return tree_lookup_peer (tgl_peer_tree, &U); + return tree_lookup_peer (tgl_state.peer_tree, &U); } struct tgl_message *tgl_message_get (long long id) { struct tgl_message M; M.id = id; - return tree_lookup_message (message_tree, &M); + return tree_lookup_message (tgl_state.message_tree, &M); } tgl_peer_t *tgl_peer_get_by_name (const char *s) { static tgl_peer_t P; P.print_name = (void *)s; - tgl_peer_t *R = tree_lookup_peer_by_name (peer_by_name_tree, &P); + tgl_peer_t *R = tree_lookup_peer_by_name (tgl_state.peer_by_name_tree, &P); return R; } void tgl_peer_iterator_ex (void (*it)(tgl_peer_t *P, void *extra), void *extra) { - tree_act_ex_peer (tgl_peer_tree, it, extra); + tree_act_ex_peer (tgl_state.peer_tree, it, extra); } int tgl_complete_user_list (int index, const char *text, int len, char **R) { index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || tgl_get_peer_type (Peers[index]->id) != TGL_PEER_USER)) { + while (index < tgl_state.peer_num && (!tgl_state.Peers[index]->print_name || strncmp (tgl_state.Peers[index]->print_name, text, len) || tgl_get_peer_type (tgl_state.Peers[index]->id) != TGL_PEER_USER)) { index ++; } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + if (index < tgl_state.peer_num) { + *R = strdup (tgl_state.Peers[index]->print_name); assert (*R); return index; } else { @@ -1921,11 +1914,11 @@ int tgl_complete_user_list (int index, const char *text, int len, char **R) { int tgl_complete_chat_list (int index, const char *text, int len, char **R) { index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || tgl_get_peer_type (Peers[index]->id) != TGL_PEER_CHAT)) { + while (index < tgl_state.peer_num && (!tgl_state.Peers[index]->print_name || strncmp (tgl_state.Peers[index]->print_name, text, len) || tgl_get_peer_type (tgl_state.Peers[index]->id) != TGL_PEER_CHAT)) { index ++; } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + if (index < tgl_state.peer_num) { + *R = strdup (tgl_state.Peers[index]->print_name); assert (*R); return index; } else { @@ -1935,11 +1928,11 @@ int tgl_complete_chat_list (int index, const char *text, int len, char **R) { int tgl_complete_encr_chat_list (int index, const char *text, int len, char **R) { index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || tgl_get_peer_type (Peers[index]->id) != TGL_PEER_ENCR_CHAT)) { + while (index < tgl_state.peer_num && (!tgl_state.Peers[index]->print_name || strncmp (tgl_state.Peers[index]->print_name, text, len) || tgl_get_peer_type (tgl_state.Peers[index]->id) != TGL_PEER_ENCR_CHAT)) { index ++; } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + if (index < tgl_state.peer_num) { + *R = strdup (tgl_state.Peers[index]->print_name); assert (*R); return index; } else { @@ -1949,11 +1942,11 @@ int tgl_complete_encr_chat_list (int index, const char *text, int len, char **R) int tgl_complete_peer_list (int index, const char *text, int len, char **R) { index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) { + while (index < tgl_state.peer_num && (!tgl_state.Peers[index]->print_name || strncmp (tgl_state.Peers[index]->print_name, text, len))) { index ++; } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); + if (index < tgl_state.peer_num) { + *R = strdup (tgl_state.Peers[index]->print_name); assert (*R); return index; } else { @@ -1962,13 +1955,13 @@ int tgl_complete_peer_list (int index, const char *text, int len, char **R) { } void tgl_free_all (void) { - tree_act_peer (tgl_peer_tree, tgls_free_peer); - tgl_peer_tree = tree_clear_peer (tgl_peer_tree); - peer_by_name_tree = tree_clear_peer_by_name (peer_by_name_tree); - tree_act_message (message_tree, tgls_free_message); - message_tree = tree_clear_message (message_tree); - tree_act_message (message_unsent_tree, tgls_free_message); - message_unsent_tree = tree_clear_message (message_unsent_tree); + tree_act_peer (tgl_state.peer_tree, tgls_free_peer); + tgl_state.peer_tree = tree_clear_peer (tgl_state.peer_tree); + tgl_state.peer_by_name_tree = tree_clear_peer_by_name (tgl_state.peer_by_name_tree); + tree_act_message (tgl_state.message_tree, tgls_free_message); + tgl_state.message_tree = tree_clear_message (tgl_state.message_tree); + tree_act_message (tgl_state.message_unsent_tree, tgls_free_message); + tgl_state.message_unsent_tree = tree_clear_message (tgl_state.message_unsent_tree); if (tgl_state.encr_prime) { tfree (tgl_state.encr_prime, 256); } @@ -1993,13 +1986,13 @@ int tgl_print_stat (char *s, int len) { return tsnprintf (s, len, "users_allocated\t%d\n" "chats_allocated\t%d\n" - "secret_chats_allocated\t%d\n" + "encr_chats_allocated\t%d\n" "peer_num\t%d\n" "messages_allocated\t%d\n", - users_allocated, - chats_allocated, - encr_chats_allocated, - peer_num, - messages_allocated + tgl_state.users_allocated, + tgl_state.chats_allocated, + tgl_state.encr_chats_allocated, + tgl_state.peer_num, + tgl_state.messages_allocated ); } diff --git a/tgl.c b/tgl.c index 24b0e9d..cca3076 100644 --- a/tgl.c +++ b/tgl.c @@ -78,6 +78,9 @@ void tgl_init (void) { tgl_state.temp_key_expire_time = 100000; } + tgl_state.message_list.next_use = &tgl_state.message_list; + tgl_state.message_list.prev_use = &tgl_state.message_list; + tglmp_on_start (); } diff --git a/tgl.h b/tgl.h index 57bfeca..13ccd99 100644 --- a/tgl.h +++ b/tgl.h @@ -127,6 +127,7 @@ struct tgl_net_methods { #define TGL_MAX_RSA_KEYS_NUM 10 // Do not modify this structure, unless you know what you do + struct tgl_state { int our_id; // ID of logged in user int encr_root; @@ -170,6 +171,24 @@ struct tgl_state { struct bignum_ctx *BN_ctx; struct tgl_allocator allocator; + + struct tree_peer *peer_tree; + struct tree_peer_by_name *peer_by_name_tree; + struct tree_message *message_tree; + struct tree_message *message_unsent_tree; + + int users_allocated; + int chats_allocated; + int messages_allocated; + int peer_num; + int peer_size; + int encr_chats_allocated; + int geo_chats_allocated; + + tgl_peer_t **Peers; + struct tgl_message message_list; + + int binlog_fd; }; extern struct tgl_state tgl_state;