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