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
33struct stats_buffer;
34struct tl_act_extra;
35
36struct 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);
58typedef 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
62void tl_query_result_fun_set (tl_query_result_fun_t func, int query_type_id);
63long long tl_generate_next_qid (int query_type_id);
64
65int default_tl_rpcs_execute (connection_job_t c, int op, int len);
66int default_tl_tcp_rpcs_execute (connection_job_t c, int op, struct raw_message *raw);
67int default_tl_close_conn (connection_job_t c, int who);
68int tl_store_stats (struct tl_out_state *tlio_out, const char *s, int raw);
69extern char *tl_engine_name;
70void register_custom_op_cb (unsigned op, void (*func)(struct tl_in_state *tlio_in, struct query_work_params *params));
71void engine_work_rpc_req_result (struct tl_in_state *tlio_in, struct query_work_params *params);
72void tl_engine_store_stats (struct tl_out_state *tlio_out);
73
74const char *op_to_string (int op);
75
76void tl_restart_all_ready (void);
77void tl_default_act_free (struct tl_act_extra *extra);
78
79
80int engine_check_allow_query (unsigned flags);
81int tl_query_act (connection_job_t c, int op, int len);
82int tl_query_act_tcp (connection_job_t c, int op, struct raw_message *raw);
83
84struct tl_act_extra {
85 int size;
86 int flags;
87 int attempt;
88 int type;
89 int op;
90 int subclass;
91 unsigned long long hash;
92 long long start_rdtsc;
93 long long cpu_rdtsc;
94 struct tl_out_state *tlio_out;
95 int (*act)(job_t, struct tl_act_extra *data);
96 void (*free)(struct tl_act_extra *data);
97 struct tl_act_extra *(*dup)(struct tl_act_extra *data);
98 struct tl_query_header *header;
99 struct raw_message **raw;
100 char **error;
101 job_t extra_ref;
102 int *error_code;
103 int extra[0];
104};
105
106static inline struct tl_act_extra *tl_act_extra_init (void *buf, int size, int (*act)(job_t, struct tl_act_extra *)) {
107 struct tl_act_extra *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,...) \
124static 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