| 1 | /* |
| 2 | This file is part of Mtproto-proxy Library. |
| 3 | |
| 4 | Mtproto-proxy Library is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as published by |
| 6 | the Free Software Foundation, either version 2 of the License, or |
| 7 | (at your option) any later version. |
| 8 | |
| 9 | Mtproto-proxy Library is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | GNU Lesser General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU Lesser General Public License |
| 15 | along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>. |
| 16 | |
| 17 | Copyright 2013 Vkontakte Ltd |
| 18 | 2013 Vitaliy Valtman |
| 19 | 2013 Anton Maydell |
| 20 | |
| 21 | Copyright 2014 Telegram Messenger Inc |
| 22 | 2014 Vitaly Valtman |
| 23 | 2014 Anton Maydell |
| 24 | |
| 25 | Copyright 2015-2016 Telegram Messenger Inc |
| 26 | 2015-2016 Vitaliy Valtman |
| 27 | */ |
| 28 | #pragma once |
| 29 | |
| 30 | #include "common/tl-parse.h" |
| 31 | #include "common/precise-time.h" |
| 32 | |
| 33 | struct stats_buffer; |
| 34 | struct tl_act_extra; |
| 35 | |
| 36 | struct query_work_params { |
| 37 | struct event_timer ev; |
| 38 | enum tl_type type; |
| 39 | struct process_id pid; |
| 40 | struct raw_message src; |
| 41 | struct tl_query_header *h; |
| 42 | struct raw_message *result; |
| 43 | int error_code; |
| 44 | int answer_sent; |
| 45 | int wait_coord; |
| 46 | char *error; |
| 47 | void *wait_pos; |
| 48 | //void *wait_time; |
| 49 | struct paramed_type *P; |
| 50 | long long start_rdtsc; |
| 51 | long long total_work_rdtsc; |
| 52 | job_t all_list; |
| 53 | int fd; |
| 54 | int generation; |
| 55 | }; |
| 56 | |
| 57 | //extern struct tl_act_extra *(*tl_parse_function)(struct tl_in_state *tlio_in, long long actor_id); |
| 58 | typedef void (*tl_query_result_fun_t)(struct tl_in_state *tlio_in, struct tl_query_header *h); |
| 59 | //extern void (*tl_stat_function)(struct tl_out_state *tlio_out); |
| 60 | //extern int (*tl_get_op_function)(struct tl_in_state *tlio_in); |
| 61 | |
| 62 | void tl_query_result_fun_set (tl_query_result_fun_t func, int query_type_id); |
| 63 | long long tl_generate_next_qid (int query_type_id); |
| 64 | |
| 65 | int default_tl_rpcs_execute (connection_job_t c, int op, int len); |
| 66 | int default_tl_tcp_rpcs_execute (connection_job_t c, int op, struct raw_message *raw); |
| 67 | int default_tl_close_conn (connection_job_t c, int who); |
| 68 | int tl_store_stats (struct tl_out_state *tlio_out, const char *s, int raw); |
| 69 | extern char *tl_engine_name; |
| 70 | void register_custom_op_cb (unsigned op, void (*func)(struct tl_in_state *tlio_in, struct query_work_params *params)); |
| 71 | void engine_work_rpc_req_result (struct tl_in_state *tlio_in, struct query_work_params *params); |
| 72 | void tl_engine_store_stats (struct tl_out_state *tlio_out); |
| 73 | |
| 74 | const char *op_to_string (int op); |
| 75 | |
| 76 | void tl_restart_all_ready (void); |
| 77 | void tl_default_act_free (struct tl_act_extra *); |
| 78 | |
| 79 | |
| 80 | int engine_check_allow_query (unsigned flags); |
| 81 | int tl_query_act (connection_job_t c, int op, int len); |
| 82 | int tl_query_act_tcp (connection_job_t c, int op, struct raw_message *raw); |
| 83 | |
| 84 | struct { |
| 85 | int ; |
| 86 | int ; |
| 87 | int ; |
| 88 | int ; |
| 89 | int ; |
| 90 | int ; |
| 91 | unsigned long long ; |
| 92 | long long ; |
| 93 | long long ; |
| 94 | struct tl_out_state *; |
| 95 | int (*)(job_t, struct tl_act_extra *data); |
| 96 | void (*)(struct tl_act_extra *data); |
| 97 | struct tl_act_extra *(*)(struct tl_act_extra *data); |
| 98 | struct tl_query_header *; |
| 99 | struct raw_message **; |
| 100 | char **; |
| 101 | job_t ; |
| 102 | int *; |
| 103 | int [0]; |
| 104 | }; |
| 105 | |
| 106 | static inline struct tl_act_extra * (void *buf, int size, int (*act)(job_t, struct tl_act_extra *)) { |
| 107 | struct tl_act_extra * = (struct tl_act_extra *)buf; |
| 108 | memset (extra, 0, sizeof (*extra)); |
| 109 | extra->size = size + (int)sizeof (*extra); |
| 110 | extra->flags = 0; |
| 111 | extra->act = act; |
| 112 | extra->free = 0; |
| 113 | extra->dup = 0; |
| 114 | extra->start_rdtsc = rdtsc (); |
| 115 | extra->cpu_rdtsc = 0; |
| 116 | return extra; |
| 117 | } |
| 118 | |
| 119 | #define QUERY_ALLOW_REPLICA_GET 1 |
| 120 | #define QUERY_ALLOW_REPLICA_SET 2 |
| 121 | #define QUERY_ALLOW_UNINIT 4 |
| 122 | |
| 123 | #define TL_PARSE_FUN_EX(tname,fname,dname,qtype,...) \ |
| 124 | static struct tl_act_extra *fname (struct tl_in_state *tlio_in, ## __VA_ARGS__) { \ |
| 125 | struct tl_act_extra *extra = tl_act_extra_init (stats_buff, sizeof (tname), dname); \ |
| 126 | tname *e __attribute__ ((unused)); \ |
| 127 | e = (void *)extra->extra; \ |
| 128 | extra->type = qtype; \ |
| 129 | extra->subclass = -1; \ |
| 130 | |
| 131 | #define TL_PARSE_FUN(name,...) TL_PARSE_FUN_EX(struct tl_ ## name,tl_ ## name,tl_do_ ## name,__VA_ARGS__) |
| 132 | #define TL_PARSE_FUN_GET(name,...) TL_PARSE_FUN_EX(struct tl_ ## name,tl_ ## name,tl_do_ ## name, QUERY_ALLOW_REPLICA_GET | QUERY_ALLOW_REPLICA_SET, ## __VA_ARGS__) |
| 133 | #define TL_PARSE_FUN_GET_ONLY(name,...) TL_PARSE_FUN_EX(struct tl_ ## name,tl_ ## name,tl_do_ ## name, QUERY_ALLOW_REPLICA_GET, ## __VA_ARGS__) |
| 134 | #define TL_PARSE_FUN_SET(name,...) TL_PARSE_FUN_EX(struct tl_ ## name,tl_ ## name,tl_do_ ## name, QUERY_ALLOW_REPLICA_SET, ## __VA_ARGS__) |
| 135 | |
| 136 | #define TL_PARSE_FUN_END \ |
| 137 | tl_fetch_end (); \ |
| 138 | if (tl_fetch_error ()) { \ |
| 139 | return 0; \ |
| 140 | } \ |
| 141 | return extra; \ |
| 142 | } |
| 143 | |
| 144 | /* ${engine}-interface-structures.h must contain #pragma pack(push,4) for use TL_DEFAULT_PARSE_FUN macro */ |
| 145 | #define TL_DEFAULT_PARSE_FUN(name,qtype) \ |
| 146 | TL_PARSE_FUN(name, qtype) \ |
| 147 | if (tlf_check (tlio_in, sizeof (*e)) < 0) { tl_fetch_set_error_format (TL_ERROR_NOT_ENOUGH_DATA, "Not enougth data"); return 0; } \ |
| 148 | tl_fetch_raw_data (e, sizeof (*e)); \ |
| 149 | TL_PARSE_FUN_END |
| 150 | |
| 151 | #define TL_DEFAULT_PARSE_FUN_GET_ONLY(name) TL_DEFAULT_PARSE_FUN(name,QUERY_ALLOW_REPLICA_GET) |
| 152 | #define TL_DEFAULT_PARSE_FUN_GET(name) TL_DEFAULT_PARSE_FUN(name,QUERY_ALLOW_REPLICA_GET | QUERY_ALLOW_REPLICA_SET) |
| 153 | #define TL_DEFAULT_PARSE_FUN_SET(name) TL_DEFAULT_PARSE_FUN(name,QUERY_ALLOW_REPLICA_SET) |
| 154 | |
| 155 | #define TL_DO_FUN_EX(tname,dname) \ |
| 156 | static int dname (job_t this_query_job, struct tl_act_extra *extra) { \ |
| 157 | tname *e = (void *)extra->extra; \ |
| 158 | struct tl_out_state *tlio_out __attribute__ ((unused)); \ |
| 159 | tlio_out = extra->tlio_out; \ |
| 160 | |
| 161 | #define TL_DO_FUN_DECL_EX(tname,dname) \ |
| 162 | static int dname (job_t this_query_job, struct tl_act_extra *extra); |
| 163 | |
| 164 | #define TL_DO_FUN(name) TL_DO_FUN_EX(struct tl_ ## name __attribute__ ((unused)), tl_do_ ## name); |
| 165 | #define TL_DO_FUN_DECL(name) TL_DO_FUN_DECL_EX(struct tl_ ## name __attribute__ ((unused)), tl_do_ ## name); |
| 166 | |
| 167 | #define TL_DO_PUBLIC_FUN_EX(tname,dname) \ |
| 168 | int dname (job_t this_query_job, struct tl_act_extra *extra) { \ |
| 169 | tname *e = (void *)extra->extra; \ |
| 170 | struct tl_out_state *tlio_out = extra->tlio_out; \ |
| 171 | |
| 172 | #define TL_DO_PUBLIC_FUN_DECL_EX(tname,dname) \ |
| 173 | int dname (job_t this_query_job, struct tl_act_extra *extra); |
| 174 | |
| 175 | #define TL_DO_PUBLIC_FUN(name) TL_DO_PUBLIC_FUN_EX(struct tl_ ## name __attribute__ ((unused)), tl_do_ ## name); |
| 176 | #define TL_DO_PUBLIC_FUN_DECL(name) TL_DO_PUBLIC_FUN_DECL_EX(struct tl_ ## name __attribute__ ((unused)), tl_do_ ## name); |
| 177 | |
| 178 | #define TL_DO_FUN_END \ |
| 179 | return 0; \ |
| 180 | } |
| 181 | |