550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen/* weak users supported in protocol */
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen/* director ring remove supported */
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen/* quit reason supported */
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen/* user-kick supported */
eb209d12e3b1cfed564c35cf19fdb1bf7fcc6811Timo Sirainen/* options supported in handshake */
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen/* user tags supported */
a5ddfd7a8b473f73135b93d5e081e470a87f0f7eTimo Sirainen/* up/down state is tracked */
ae32667c54480d329eed994b3defab89cd76c077Timo Sirainen/* user tag version 2 supported */
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen/* user-kick-alt supported */
05b7b8f14426b5fe5d016940eb5916033f0bc841Timo Sirainen/* Users are sent as "U" command in handshake */
b3e36790ca9e16d022118012b46ed50f73a45046Timo Sirainen/* USER event with timestamp supported */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen/* Minimum time between even attempting to communicate with a director that
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen failed due to a protocol error. */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen#define DIRECTOR_PROTOCOL_FAILURE_RETRY_SECS 60
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* User isn't being killed */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* We're still killing the user's connections */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* Like above, but our left side already announced it was finished
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen with killing its user connections */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* We're done killing, but we have to wait for the left side to
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen finish killing its user connections before sending USER-KILLED to
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen our right side */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* We're done killing, but waiting for USER-KILLED-EVERYWHERE
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen notification until this state gets reset. */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* Waiting for the flush socket to finish. */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* Wait for a while for the user connections to actually die. Note that
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen only at this stage we can be sure that all the directors know about
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen the user move (although it could be earlier if we added a new
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen USER-MOVED notification). */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* NOTE: remember to update also user_kill_state_names[] */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainenextern const char *user_kill_state_names[USER_KILL_STATE_DELAY+1];
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainentypedef void director_state_change_callback_t(struct director *dir);
3e0c0a269390de8495e8f6ecaed59a823221480eAki Tuomitypedef director_state_change_callback_t director_kick_callback_t;
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen/* When a user gets freed, the kill_ctx may still be left alive. It's also
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen possible for the user to come back, in which case the kill_ctx is usually
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen NULL, but another kill could have also started. The previous kill_ctx is
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen valid only if it matches the current user's kill_ctx. */
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen#define DIRECTOR_KILL_CONTEXT_IS_VALID(user, ctx) \
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen /* Move timeout to make sure user's connections won't silently hang
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen indefinitely if there is some trouble moving it. */
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen /* these are set only for director_flush_socket handling: */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* IP and port of this director. self_host->ip/port must equal these. */
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen /* left and right connections are set only after they have finished
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen handshaking. until then they're in the connections list, although
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen updates are still sent to them during handshaking if the USER list
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen /* all director connections */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct director_connection *) connections;
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen /* current mail hosts */
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen /* original mail hosts configured in config file.
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen this is used only for doveadm lookups */
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen /* Number of users currently being moved */
5754fa860405e9af20c38981942f6aa97ce3158dTimo Sirainen /* Number of users currently being kicked */
4dc8d682c855ca78db8874e04302e885465c1d65Timo Sirainen /* Number of requests currently delayed */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* these requests are waiting for directors to be in synced */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct director_request *) pending_requests;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director_state_change_callback_t *state_change_callback;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* director hosts are sorted by IP (and port) */
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainen unsigned int last_sync_sent_ring_change_counter;
3dc72a40e457658caa3c033fb6b3418d16e9fd21Timo Sirainen /* Timestamp when the last SYNC was initiated by us */
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen /* the lowest minor version supported by the ring */
3dc72a40e457658caa3c033fb6b3418d16e9fd21Timo Sirainen /* Timestamp when ring became synced or unsynced the last time */
3dc72a40e457658caa3c033fb6b3418d16e9fd21Timo Sirainen /* How many milliseconds it took for the last SYNC to travel through
ece0a20249ce26208db3415ba2e79423678856f8Timo Sirainen uint64_t ring_traffic_input, ring_traffic_output;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* director ring handshaking is complete.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen director can start serving clients. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Create a new director. If listen_ip specifies an actual IP, it's used with
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen listen_port for finding ourself from the director_servers setting.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen listen_port is used regardless by director_host_add_from_string() for hosts
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen without specified port. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainendirector_init(const struct director_settings *set,
009217abb57a24a4076092e8e4e165545747839eStephan Bosch const struct ip_addr *listen_ip, in_port_t listen_port,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Start connecting to other directors */
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainenvoid director_connect(struct director *dir, const char *reason);
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainenvoid director_set_ring_handshaked(struct director *dir);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid director_set_ring_synced(struct director *dir);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenvoid director_set_ring_unsynced(struct director *dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_set_state_changed(struct director *dir);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenvoid director_sync_send(struct director *dir, struct director_host *host,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen unsigned int timestamp, unsigned int hosts_hash);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenbool director_resend_sync(struct director *dir);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid director_notify_ring_added(struct director_host *added_host,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid director_ring_remove(struct director_host *removed_host,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_host(struct director *dir, struct director_host *src,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid director_resend_hosts(struct director *dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_remove_host(struct director *dir, struct director_host *src,
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainenvoid director_flush_host(struct director *dir, struct director_host *src,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_user(struct director *dir, struct director_host *src,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenvoid director_update_user_weak(struct director *dir, struct director_host *src,
f5d82a4b87a9b17894e1869cfe8b1a90afbced59Timo Sirainenvoid director_kill_user(struct director *dir, struct director_host *src,
ce8d63810932f48176304ed08cd8b7652c4a8addTimo Sirainen struct mail_host *old_host, bool forced_kick);
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainenvoid director_move_user(struct director *dir, struct director_host *src,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen unsigned int username_hash, struct mail_host *host)
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainenvoid director_kick_user(struct director *dir, struct director_host *src,
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen struct director_host *orig_src, const char *username)
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainenvoid director_kick_user_alt(struct director *dir, struct director_host *src,
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainenvoid director_kick_user_hash(struct director *dir, struct director_host *src,
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainenvoid director_user_killed(struct director *dir, unsigned int username_hash);
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainenvoid director_user_killed_everywhere(struct director *dir,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenvoid director_user_weak(struct director *dir, struct user *user);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid director_sync_freeze(struct director *dir);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Send data to all directors using both left and right connections
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen (unless they're the same). */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid director_update_send(struct director *dir, struct director_host *src,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const char *cmd);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid director_update_send_version(struct director *dir,
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainenint director_connect_host(struct director *dir, struct director_host *host,
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainen const char *reason);
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainendirector_get_username_hash(struct director *dir, const char *username,
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainen unsigned int *hash_r);
1df39b899804fd1dbc560f75382364822935c857Timo Sirainenvoid dir_debug(const char *fmt, ...) ATTR_FORMAT(1, 2);
14660f677e16a5c36f3c43e9e64f5e021fda627bTimo Sirainendirector_iterate_users_init(struct director *dir, bool iter_until_current_tail);
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainenstruct user *director_iterate_users_next(struct director_user_iter *iter);