From f097bc9a2db4ac103b20f4680722dc7d46fad7b3 Mon Sep 17 00:00:00 2001 From: Test_User Date: Wed, 24 Jul 2024 04:34:17 -0400 Subject: Fix cross-protocol netsplit propagations --- protocols.c | 12 ++++++++++++ protocols.h | 2 ++ protocols/inspircd2.c | 22 ++++++++++++++++++---- protocols/inspircd2.h | 1 + protocols/inspircd3.c | 25 +++++++++++++++++++++---- protocols/inspircd3.h | 1 + protocols/inspircd4.c | 25 +++++++++++++++++++++---- protocols/inspircd4.h | 1 + server_network.c | 2 ++ 9 files changed, 79 insertions(+), 12 deletions(-) diff --git a/protocols.c b/protocols.c index 63b3171..3ed647d 100644 --- a/protocols.c +++ b/protocols.c @@ -51,6 +51,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .propagate = inspircd2_protocol_propagate, .propagate_new_server = inspircd2_protocol_propagate_new_server, + .propagate_remove_server = inspircd2_protocol_propagate_remove_server, .propagate_unlink_server = inspircd2_protocol_propagate_unlink_server, .propagate_new_user = inspircd2_protocol_propagate_new_user, @@ -114,6 +115,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .propagate = inspircd3_protocol_propagate, .propagate_new_server = inspircd3_protocol_propagate_new_server, + .propagate_remove_server = inspircd3_protocol_propagate_remove_server, .propagate_unlink_server = inspircd3_protocol_propagate_unlink_server, .propagate_new_user = inspircd3_protocol_propagate_new_user, @@ -177,6 +179,7 @@ struct protocol protocols[NUM_PROTOCOLS] = { .propagate = inspircd4_protocol_propagate, .propagate_new_server = inspircd4_protocol_propagate_new_server, + .propagate_remove_server = inspircd4_protocol_propagate_remove_server, .propagate_unlink_server = inspircd4_protocol_propagate_unlink_server, .propagate_new_user = inspircd4_protocol_propagate_new_user, @@ -279,6 +282,15 @@ void protocols_propagate_new_server(struct string from, struct string attached_t protocols[i].propagate_new_server(from, attached_to, info); } } + +void protocols_propagate_remove_server(struct string from, struct server_info *server, struct string reason) { + for (size_t i = 0; i < NUM_PROTOCOLS; i++) { + if (!active_protocols[i]) + continue; + protocols[i].propagate_remove_server(from, server, reason); + } +} + void protocols_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { for (size_t i = 0; i < NUM_PROTOCOLS; i++) { if (!active_protocols[i]) diff --git a/protocols.h b/protocols.h index 21a9d03..c72fb93 100644 --- a/protocols.h +++ b/protocols.h @@ -46,6 +46,7 @@ struct protocol { void (*propagate)(struct string from, struct string msg); void (*propagate_new_server)(struct string from, struct string attached_to, struct server_info *info); + void (*propagate_remove_server)(struct string from, struct server_info *server, struct string reason); void (*propagate_unlink_server)(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void (*propagate_new_user)(struct string from, struct user_info *info); @@ -106,6 +107,7 @@ int protocols_init(void); void protocols_update_propagations(void); void protocols_propagate_new_server(struct string from, struct string attached_to, struct server_info *info); +void protocols_propagate_remove_server(struct string from, struct server_info *server, struct string reason); void protocols_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void protocols_propagate_new_user(struct string from, struct user_info *info); diff --git a/protocols/inspircd2.c b/protocols/inspircd2.c index 7f9c3f3..8b25be5 100644 --- a/protocols/inspircd2.c +++ b/protocols/inspircd2.c @@ -589,8 +589,25 @@ void inspircd2_protocol_propagate_new_server(struct string from, struct string a inspircd2_protocol_propagate(from, STRING(" ENDBURST\n")); } +// [:source] SQUIT [?] +void inspircd2_protocol_propagate_remove_server(struct string from, struct server_info *server, struct string reason) { + if (server->protocol == INSPIRCD2_PROTOCOL) + return; + + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, SID); + inspircd2_protocol_propagate(from, STRING(" SQUIT ")); + inspircd2_protocol_propagate(from, server->sid); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, reason); + inspircd2_protocol_propagate(from, STRING("\n")); +} + // [:source] SQUIT [?] void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { + if (protocol != INSPIRCD2_PROTOCOL) + return; + struct server_info *source; struct server_info *target; if (a->distance == 0 && !STRING_EQ(a->sid, SID)) { @@ -604,10 +621,7 @@ void inspircd2_protocol_propagate_unlink_server(struct string from, struct serve } inspircd2_protocol_propagate(from, STRING(":")); - if (protocol == INSPIRCD2_PROTOCOL) - inspircd2_protocol_propagate(from, source->sid); - else - inspircd2_protocol_propagate(from, SID); + inspircd2_protocol_propagate(from, source->sid); inspircd2_protocol_propagate(from, STRING(" SQUIT ")); inspircd2_protocol_propagate(from, target->sid); inspircd2_protocol_propagate(from, STRING(" :\n")); diff --git a/protocols/inspircd2.h b/protocols/inspircd2.h index b5df434..6caaff3 100644 --- a/protocols/inspircd2.h +++ b/protocols/inspircd2.h @@ -48,6 +48,7 @@ void inspircd2_protocol_update_propagations(void); void inspircd2_protocol_propagate(struct string from, struct string msg); void inspircd2_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info); +void inspircd2_protocol_propagate_remove_server(struct string from, struct server_info *server, struct string reason); void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void inspircd2_protocol_propagate_new_user(struct string from, struct user_info *info); diff --git a/protocols/inspircd3.c b/protocols/inspircd3.c index 7457938..9d09831 100644 --- a/protocols/inspircd3.c +++ b/protocols/inspircd3.c @@ -572,8 +572,28 @@ void inspircd3_protocol_propagate_new_server(struct string from, struct string a inspircd3_protocol_propagate(from, STRING(" ENDBURST\n")); } +// [:source] SQUIT [?] +void inspircd3_protocol_propagate_remove_server(struct string from, struct server_info *server, struct string reason) { + if (server->protocol == INSPIRCD3_PROTOCOL) + return; + + inspircd3_protocol_propagate(from, STRING(":")); + inspircd3_protocol_propagate(from, SID); + inspircd3_protocol_propagate(from, STRING(" SQUIT ")); + inspircd3_protocol_propagate(from, server->sid); + inspircd3_protocol_propagate(from, STRING(" :")); + if (reason.len != 0) + inspircd3_protocol_propagate(from, reason); + else + inspircd3_protocol_propagate(from, STRING(" ")); + inspircd3_protocol_propagate(from, STRING("\n")); +} + // [:source] SQUIT [?] void inspircd3_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { + if (protocol != INSPIRCD3_PROTOCOL) + return; + struct server_info *source; struct server_info *target; if (a->distance == 0 && !STRING_EQ(a->sid, SID)) { @@ -587,10 +607,7 @@ void inspircd3_protocol_propagate_unlink_server(struct string from, struct serve } inspircd3_protocol_propagate(from, STRING(":")); - if (protocol == INSPIRCD3_PROTOCOL) - inspircd3_protocol_propagate(from, source->sid); - else - inspircd3_protocol_propagate(from, SID); + inspircd3_protocol_propagate(from, source->sid); inspircd3_protocol_propagate(from, STRING(" SQUIT ")); inspircd3_protocol_propagate(from, target->sid); inspircd3_protocol_propagate(from, STRING(" : \n")); diff --git a/protocols/inspircd3.h b/protocols/inspircd3.h index 1f3dba4..5631321 100644 --- a/protocols/inspircd3.h +++ b/protocols/inspircd3.h @@ -57,6 +57,7 @@ void inspircd3_protocol_update_propagations(void); void inspircd3_protocol_propagate(struct string from, struct string msg); void inspircd3_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info); +void inspircd3_protocol_propagate_remove_server(struct string from, struct server_info *server, struct string reason); void inspircd3_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void inspircd3_protocol_propagate_new_user(struct string from, struct user_info *info); diff --git a/protocols/inspircd4.c b/protocols/inspircd4.c index 865e630..d62e58b 100644 --- a/protocols/inspircd4.c +++ b/protocols/inspircd4.c @@ -573,8 +573,28 @@ void inspircd4_protocol_propagate_new_server(struct string from, struct string a inspircd4_protocol_propagate(from, STRING(" ENDBURST\n")); } +// [:source] SQUIT [?] +void inspircd4_protocol_propagate_remove_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { + if (server->protocol == INSPIRCD4_PROTOCOL) + return; + + inspircd4_protocol_propagate(from, STRING(":")); + inspircd4_protocol_propagate(from, SID); + inspircd4_protocol_propagate(from, STRING(" SQUIT ")); + inspircd4_protocol_propagate(from, target->sid); + inspircd4_protocol_propagate(from, STRING(" :")); + if (reason.len != 0) + inspircd4_protocol_propagate(from, reason); + else + inspircd4_protocol_propagate(from, STRING(" ")); + inspircd4_protocol_propagate(from, STRING("\n")); +} + // [:source] SQUIT [?] void inspircd4_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { + if (protocol != INSPIRCD4_PROTOCOL) + return; + struct server_info *source; struct server_info *target; if (a->distance == 0 && !STRING_EQ(a->sid, SID)) { @@ -588,10 +608,7 @@ void inspircd4_protocol_propagate_unlink_server(struct string from, struct serve } inspircd4_protocol_propagate(from, STRING(":")); - if (protocol == INSPIRCD4_PROTOCOL) - inspircd4_protocol_propagate(from, source->sid); - else - inspircd4_protocol_propagate(from, SID); + inspircd4_protocol_propagate(from, source->sid); inspircd4_protocol_propagate(from, STRING(" SQUIT ")); inspircd4_protocol_propagate(from, target->sid); inspircd4_protocol_propagate(from, STRING(" : \n")); diff --git a/protocols/inspircd4.h b/protocols/inspircd4.h index 5b23440..7ac2cd7 100644 --- a/protocols/inspircd4.h +++ b/protocols/inspircd4.h @@ -57,6 +57,7 @@ void inspircd4_protocol_update_propagations(void); void inspircd4_protocol_propagate(struct string from, struct string msg); void inspircd4_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info); +void inspircd4_protocol_propagate_remove_server(struct string from, struct server_info *server, struct string reason); void inspircd4_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); void inspircd4_protocol_propagate_new_user(struct string from, struct user_info *info); diff --git a/server_network.c b/server_network.c index 0bfe2e2..a5b78a1 100644 --- a/server_network.c +++ b/server_network.c @@ -285,6 +285,8 @@ void free_server(struct server_info *server) { } void remove_server(struct string from, struct server_info *server, struct string reason) { + protocols_propagate_remove_server(from, server, reason); + while (server->user_list.len != 0) { remove_user(from, server->user_list.array[0].ptr, reason, 0); } -- cgit v1.2.3