1 #ifndef DIRECTOR_H
2 #define DIRECTOR_H
3 
4 #include "net.h"
5 #include "director-settings.h"
6 
7 #define DIRECTOR_VERSION_NAME "director"
8 #define DIRECTOR_VERSION_MAJOR 1
9 #define DIRECTOR_VERSION_MINOR 9
10 
11 /* weak users supported in protocol */
12 #define DIRECTOR_VERSION_WEAK_USERS 1
13 /* director ring remove supported */
14 #define DIRECTOR_VERSION_RING_REMOVE 2
15 /* quit reason supported */
16 #define DIRECTOR_VERSION_QUIT 3
17 /* user-kick supported */
18 #define DIRECTOR_VERSION_USER_KICK 4
19 /* options supported in handshake */
20 #define DIRECTOR_VERSION_OPTIONS 5
21 /* user tags supported */
22 #define DIRECTOR_VERSION_TAGS 5
23 /* up/down state is tracked */
24 #define DIRECTOR_VERSION_UPDOWN 6
25 /* user tag version 2 supported */
26 #define DIRECTOR_VERSION_TAGS_V2 7
27 /* user-kick-alt supported */
28 #define DIRECTOR_VERSION_USER_KICK_ALT 8
29 /* Users are sent as "U" command in handshake */
30 #define DIRECTOR_VERSION_HANDSHAKE_U_CMD 9
31 /* USER event with timestamp supported */
32 #define DIRECTOR_VERSION_USER_TIMESTAMP 9
33 
34 /* Minimum time between even attempting to communicate with a director that
35    failed due to a protocol error. */
36 #define DIRECTOR_PROTOCOL_FAILURE_RETRY_SECS 60
37 
38 struct director;
39 struct mail_host;
40 struct user;
41 struct director_user_init;
42 
43 enum user_kill_state {
44 	/* User isn't being killed */
45 	USER_KILL_STATE_NONE,
46 	/* We're still killing the user's connections */
47 	USER_KILL_STATE_KILLING,
48 	/* Like above, but our left side already announced it was finished
49 	   with killing its user connections */
50 	USER_KILL_STATE_KILLING_NOTIFY_RECEIVED,
51 	/* We're done killing, but we have to wait for the left side to
52 	   finish killing its user connections before sending USER-KILLED to
53 	   our right side */
54 	USER_KILL_STATE_KILLED_WAITING_FOR_NOTIFY,
55 	/* We're done killing, but waiting for USER-KILLED-EVERYWHERE
56 	   notification until this state gets reset. */
57 	USER_KILL_STATE_KILLED_WAITING_FOR_EVERYONE,
58 	/* Waiting for the flush socket to finish. */
59 	USER_KILL_STATE_FLUSHING,
60 	/* Wait for a while for the user connections to actually die. Note that
61 	   only at this stage we can be sure that all the directors know about
62 	   the user move (although it could be earlier if we added a new
63 	   USER-MOVED notification). */
64 	USER_KILL_STATE_DELAY
65 	/* NOTE: remember to update also user_kill_state_names[] */
66 };
67 extern const char *user_kill_state_names[USER_KILL_STATE_DELAY+1];
68 
69 typedef void director_state_change_callback_t(struct director *dir);
70 typedef director_state_change_callback_t director_kick_callback_t;
71 
72 /* When a user gets freed, the kill_ctx may still be left alive. It's also
73    possible for the user to come back, in which case the kill_ctx is usually
74    NULL, but another kill could have also started. The previous kill_ctx is
75    valid only if it matches the current user's kill_ctx. */
76 #define DIRECTOR_KILL_CONTEXT_IS_VALID(user, ctx) \
77 	((user) != NULL && (user)->kill_ctx == ctx)
78 
79 struct director_kill_context {
80 	struct director *dir;
81 	struct mail_tag *tag;
82 	unsigned int username_hash;
83 	struct ip_addr old_host_ip;
84 	unsigned int old_host_vhost_count;
85 	bool old_host_down;
86 	bool kill_is_self_initiated;
87 	bool callback_pending;
88 
89 	enum user_kill_state kill_state;
90 	/* Move timeout to make sure user's connections won't silently hang
91 	   indefinitely if there is some trouble moving it. */
92 	struct timeout *to_move;
93 	/* IPC command to kick the user */
94 	struct ipc_client_cmd *ipc_cmd;
95 
96 	/* these are set only for director_flush_socket handling: */
97 	struct ip_addr host_ip;
98 	struct program_client *pclient;
99 	struct ostream *reply;
100 	char *socket_path;
101 };
102 
103 struct director {
104 	struct event *event;
105 	const struct director_settings *set;
106 
107 	/* IP and port of this director. self_host->ip/port must equal these. */
108 	struct ip_addr self_ip;
109 	in_port_t self_port;
110 
111 	in_port_t test_port;
112 
113 	struct director_host *self_host;
114 	/* left and right connections are set only after they have finished
115 	   handshaking. until then they're in the connections list, although
116 	   updates are still sent to them during handshaking if the USER list
117 	   is long. */
118 	struct director_connection *left, *right;
119 	/* all director connections */
120 	ARRAY(struct director_connection *) connections;
121 	struct timeout *to_reconnect;
122 	struct timeout *to_sync;
123 	struct timeout *to_callback;
124 
125 	/* current mail hosts */
126 	struct mail_host_list *mail_hosts;
127 	/* original mail hosts configured in config file.
128 	   this is used only for doveadm lookups */
129 	struct mail_host_list *orig_config_hosts;
130 	/* Number of users currently being moved */
131 	unsigned int users_moving_count;
132 	/* Number of users currently being kicked */
133 	unsigned int users_kicking_count;
134 	/* Number of requests currently delayed */
135 	unsigned int requests_delayed_count;
136 
137 	/* these requests are waiting for directors to be in synced */
138 	ARRAY(struct director_request *) pending_requests;
139 	struct timeout *to_request;
140 	struct timeout *to_handshake_warning;
141 
142 	director_state_change_callback_t *state_change_callback;
143 	director_kick_callback_t *kick_callback;
144 
145 	/* director hosts are sorted by IP (and port) */
146 	ARRAY(struct director_host *) dir_hosts;
147 	struct timeout *to_remove_dirs;
148 
149 	struct ipc_client *ipc_proxy;
150 	unsigned int sync_seq;
151 	unsigned int ring_change_counter;
152 	unsigned int last_sync_sent_ring_change_counter;
153 	/* Timestamp when the last SYNC was initiated by us */
154 	struct timeval last_sync_start_time;
155 	/* the lowest minor version supported by the ring */
156 	unsigned int ring_min_version;
157 	/* Timestamp when ring became synced or unsynced the last time */
158 	time_t ring_last_sync_time;
159 	/* How many milliseconds it took for the last SYNC to travel through
160 	   the ring. */
161 	unsigned int last_sync_msecs;
162 
163 	time_t ring_first_alone;
164 
165 	uint64_t num_requests, num_incoming_requests;
166 	uint64_t ring_traffic_input, ring_traffic_output;
167 
168 	/* director ring handshaking is complete.
169 	   director can start serving clients. */
170 	bool ring_handshaked:1;
171 	bool ring_handshake_warning_sent:1;
172 	bool ring_synced:1;
173 	bool sync_frozen:1;
174 	bool sync_pending:1;
175 };
176 
177 /* Create a new director. If listen_ip specifies an actual IP, it's used with
178    listen_port for finding ourself from the director_servers setting.
179    listen_port is used regardless by director_host_add_from_string() for hosts
180    without specified port. */
181 struct director *
182 director_init(const struct director_settings *set,
183 	      const struct ip_addr *listen_ip, in_port_t listen_port,
184 	      director_state_change_callback_t *callback,
185 	      director_kick_callback_t *kick_callback);
186 void director_deinit(struct director **dir);
187 void director_find_self(struct director *dir);
188 
189 /* Start connecting to other directors */
190 void director_connect(struct director *dir, const char *reason);
191 
192 void director_set_ring_handshaked(struct director *dir);
193 void director_set_ring_synced(struct director *dir);
194 void director_set_ring_unsynced(struct director *dir);
195 void director_set_state_changed(struct director *dir);
196 void director_sync_send(struct director *dir, struct director_host *host,
197 			uint32_t seq, unsigned int minor_version,
198 			unsigned int timestamp, unsigned int hosts_hash);
199 bool director_resend_sync(struct director *dir);
200 
201 void director_notify_ring_added(struct director_host *added_host,
202 				struct director_host *src, bool log);
203 void director_ring_remove(struct director_host *removed_host,
204 			  struct director_host *src);
205 
206 void director_update_host(struct director *dir, struct director_host *src,
207 			  struct director_host *orig_src,
208 			  struct mail_host *host) ATTR_NULL(3);
209 void director_resend_hosts(struct director *dir);
210 void director_remove_host(struct director *dir, struct director_host *src,
211 			  struct director_host *orig_src,
212 			  struct mail_host *host) ATTR_NULL(2, 3);
213 void director_flush_host(struct director *dir, struct director_host *src,
214 			 struct director_host *orig_src,
215 			 struct mail_host *host) ATTR_NULL(3);
216 void director_update_user(struct director *dir, struct director_host *src,
217 			  struct user *user);
218 void director_update_user_weak(struct director *dir, struct director_host *src,
219 			       struct director_connection *src_conn,
220 			       struct director_host *orig_src,
221 			       struct user *user) ATTR_NULL(3);
222 void director_kill_user(struct director *dir, struct director_host *src,
223 			struct user *user, struct mail_tag *tag,
224 			struct mail_host *old_host, bool forced_kick);
225 void director_move_user(struct director *dir, struct director_host *src,
226 			struct director_host *orig_src,
227 			unsigned int username_hash, struct mail_host *host)
228 	ATTR_NULL(3);
229 void director_kick_user(struct director *dir, struct director_host *src,
230 			struct director_host *orig_src, const char *username)
231 	ATTR_NULL(3);
232 void director_kick_user_alt(struct director *dir, struct director_host *src,
233 			    struct director_host *orig_src,
234 			    const char *field, const char *value)
235 	ATTR_NULL(3);
236 void director_kick_user_hash(struct director *dir, struct director_host *src,
237 			     struct director_host *orig_src,
238 			     unsigned int username_hash,
239 			     const struct ip_addr *except_ip)
240 	ATTR_NULL(3);
241 void director_user_killed(struct director *dir, unsigned int username_hash);
242 void director_user_killed_everywhere(struct director *dir,
243 				     struct director_host *src,
244 				     struct director_host *orig_src,
245 				     unsigned int username_hash) ATTR_NULL(3);
246 void director_user_weak(struct director *dir, struct user *user);
247 
248 void director_sync_freeze(struct director *dir);
249 void director_sync_thaw(struct director *dir);
250 
251 /* Send data to all directors using both left and right connections
252    (unless they're the same). */
253 void director_update_send(struct director *dir, struct director_host *src,
254 			  const char *cmd);
255 void director_update_send_version(struct director *dir,
256 				  struct director_host *src,
257 				  unsigned int min_version, const char *cmd);
258 
259 int director_connect_host(struct director *dir, struct director_host *host,
260 			  const char *reason);
261 
262 bool
263 director_get_username_hash(struct director *dir, const char *username,
264 			   unsigned int *hash_r);
265 
266 void directors_init(void);
267 void directors_deinit(void);
268 
269 struct director_user_iter *
270 director_iterate_users_init(struct director *dir, bool iter_until_current_tail);
271 struct user *director_iterate_users_next(struct director_user_iter *iter);
272 void director_iterate_users_deinit(struct director_user_iter **_iter);
273 
274 #endif
275