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 2009-2013 Vkontakte Ltd |
18 | 2008-2013 Nikolai Durov |
19 | 2008-2013 Andrey Lopatin |
20 | |
21 | Copyright 2014-2016 Telegram Messenger Inc |
22 | 2016 Vitaly Valtman |
23 | */ |
24 | |
25 | #pragma once |
26 | |
27 | #include <netinet/in.h> |
28 | |
29 | #ifndef EPOLLRDHUP |
30 | #define EPOLLRDHUP 0x2000 |
31 | #endif |
32 | |
33 | #define MAX_EVENTS (1 << 19) |
34 | |
35 | #define EVT_READ 4 |
36 | #define EVT_WRITE 2 |
37 | #define EVT_SPEC 1 |
38 | #define EVT_RW (EVT_READ | EVT_WRITE) |
39 | #define EVT_RWX (EVT_READ | EVT_WRITE | EVT_SPEC) |
40 | #define EVT_LEVEL 8 |
41 | #define EVT_OPEN 0x80 |
42 | #define EVT_CLOSED 0x40 |
43 | #define EVT_IN_EPOLL 0x20 |
44 | #define EVT_NEW 0x100 |
45 | #define EVT_NOHUP 0x200 |
46 | #define EVT_FROM_EPOLL 0x400 |
47 | |
48 | #define EVA_CONTINUE 0 |
49 | #define EVA_RERUN -2 |
50 | #define EVA_REMOVE -3 |
51 | #define EVA_DESTROY -5 |
52 | #define EVA_ERROR -8 |
53 | #define EVA_FATAL -666 |
54 | |
55 | #define MAX_UDP_SENDBUF_SIZE (1L << 24) |
56 | #define MAX_UDP_RCVBUF_SIZE (1L << 24) |
57 | |
58 | |
59 | typedef struct event_descr event_t; |
60 | typedef int (*event_handler_t)(int fd, void *data, event_t *ev); |
61 | |
62 | struct event_descr { |
63 | int fd; |
64 | int state; // actions that we should wait for (read/write/special) + status |
65 | int ready; // actions we are ready to do |
66 | int epoll_state; // current state in epoll() |
67 | int epoll_ready; // result of epoll() |
68 | int timeout; // timeout in ms (UNUSED) |
69 | int priority; // priority (0-9) |
70 | int in_queue; // position in heap (0=not in queue) |
71 | long long timestamp; |
72 | long long refcnt; |
73 | event_handler_t work; |
74 | void *data; |
75 | // struct sockaddr_in peer; |
76 | }; |
77 | |
78 | extern double last_epoll_wait_at; |
79 | extern int ev_heap_size; |
80 | extern event_t Events[MAX_EVENTS]; |
81 | |
82 | extern double tot_idle_time, a_idle_time, a_idle_quotient; |
83 | |
84 | int init_epoll (void); |
85 | |
86 | int remove_event_from_heap (event_t *ev, int allow_hole); |
87 | int put_event_into_heap (event_t *ev); |
88 | int put_event_into_heap_tail (event_t *ev, int ts_delta); |
89 | |
90 | int epoll_sethandler (int fd, int prio, event_handler_t handler, void *data); |
91 | int epoll_fetch_events (int timeout); |
92 | int epoll_work (int timeout); |
93 | int epoll_insert (int fd, int flags); |
94 | int epoll_remove (int fd); |
95 | int epoll_close (int fd); |
96 | |
97 | extern int epoll_fd; |
98 | |
99 | //extern volatile unsigned long long pending_signals; |
100 | extern volatile int main_thread_interrupt_status; |
101 | |
102 | //int insert_event_timer (event_timer_t *et); |
103 | //int remove_event_timer (event_timer_t *et); |
104 | //static inline int event_timer_active (event_timer_t *et) { return et->h_idx; } |
105 | //static inline void event_timer_init (event_timer_t *et) { et->h_idx = 0;} |
106 | |
107 | #define PRIVILEGED_TCP_PORTS 1024 |
108 | |
109 | extern int tcp_maximize_buffers; |
110 | extern struct in_addr settings_addr; |
111 | |
112 | #define SM_UDP 1 |
113 | #define SM_IPV6 2 |
114 | #define SM_IPV6_ONLY 4 |
115 | #define SM_LOWPRIO 8 |
116 | #define SM_REUSE 16 |
117 | #define SM_SPECIAL 0x10000 |
118 | #define SM_NOQACK 0x20000 |
119 | #define SM_RAWMSG 0x40000 |
120 | |
121 | int server_socket (int port, struct in_addr in_addr, int backlog, int mode); |
122 | int client_socket (in_addr_t in_addr, int port, int mode); |
123 | int client_socket_ipv6 (const unsigned char in6_addr_ptr[16], int port, int mode); |
124 | |
125 | void maximize_sndbuf (int sfd, int max); |
126 | void maximize_rcvbuf (int sfd, int max); |
127 | |
128 | unsigned get_my_ipv4 (void); |
129 | int get_my_ipv6 (unsigned char ipv6[16]); |
130 | |
131 | union sockaddr_in46 { |
132 | struct sockaddr_in a4; |
133 | struct sockaddr_in6 a6; |
134 | }; |
135 | |
136 | static inline int is_4in6 (const unsigned char ipv6[16]) { return !*((long long *) ipv6) && ((int *) ipv6)[2] == -0x10000; } |
137 | static inline unsigned (const unsigned char ipv6[16]) { return (((unsigned *) ipv6)[3]); } |
138 | static inline void set_4in6 (unsigned char ipv6[16], unsigned ip) { *(long long *) ipv6 = 0; ((int *) ipv6)[2] = -0x10000; ((unsigned *) ipv6)[3] = ip; } |
139 | |
140 | const char *conv_addr (in_addr_t a, char *buf); |
141 | const char *show_ip (unsigned ip); |
142 | const char *conv_addr6 (const unsigned char a[16], char *buf); |
143 | const char *show_ipv6 (const unsigned char ipv6[16]); |
144 | |
145 | extern int epoll_sleep_ns; |
146 | |