diff options
author | Test_User <hax@andrewyu.org> | 2024-06-15 14:16:50 -0400 |
---|---|---|
committer | Test_User <hax@andrewyu.org> | 2024-06-15 14:16:50 -0400 |
commit | 88f9b2248bfb016514e340ee5eb81df7337fcc94 (patch) | |
tree | e206d68ce2dddd539f0694b85e04e2a49337b700 | |
parent | 8dca8643675830723d37f064d5417fb3e035385e (diff) | |
download | haxircd-88f9b2248bfb016514e340ee5eb81df7337fcc94.tar.gz haxircd-88f9b2248bfb016514e340ee5eb81df7337fcc94.zip |
Improvements and the start of reloadable modules
-rw-r--r-- | Makefile | 55 | ||||
-rw-r--r-- | config.h | 5 | ||||
-rw-r--r-- | general_network.c | 29 | ||||
-rw-r--r-- | general_network.h | 4 | ||||
-rwxr-xr-x | haxserv.so | bin | 0 -> 950584 bytes | |||
-rw-r--r-- | main.c | 108 | ||||
-rw-r--r-- | protocols.c | 2 | ||||
-rw-r--r-- | protocols.h | 2 | ||||
-rw-r--r-- | protocols/inspircd2.c | 275 | ||||
-rw-r--r-- | protocols/inspircd2.h | 2 | ||||
-rw-r--r-- | psuedoclients.c | 35 | ||||
-rw-r--r-- | psuedoclients.h | 9 | ||||
-rw-r--r-- | psuedoclients/haxserv.c | 51 | ||||
-rw-r--r-- | psuedoclients/haxserv.h | 4 | ||||
-rwxr-xr-x | psuedoclients/haxserv.so | bin | 0 -> 111408 bytes | |||
-rw-r--r-- | real_main.c | 133 | ||||
-rw-r--r-- | server_network.c | 33 |
17 files changed, 424 insertions, 323 deletions
@@ -150,7 +150,8 @@ USE_CLIENT = 0 USE_GNUTLS = 0 USE_SERVER = 0 -OFILES = config.o general_network.o haxstring_utils.o main.o table.o +OFILES = config.o general_network.o haxstring_utils.o real_main.o table.o +SOFILES = ifeq ($(PLAINTEXT_CLIENT),1) CFLAGS += -DUSE_PLAINTEXT_CLIENT @@ -199,7 +200,7 @@ endif ifeq ($(HAXSERV_PSUEDOCLIENT),1) -OFILES += psuedoclients/haxserv.o +SOFILES += psuedoclients/haxserv.so CFLAGS += -DUSE_HAXSERV_PSUEDOCLIENT USE_PSUEDOCLIENTS = 1 endif @@ -260,65 +261,73 @@ endif -DEPS = $(shell $(CC) $(CFLAGS) -M -MT $(1).o $(1).c | sed -z 's/\\\n //g') .makeopts Makefile +DEPS = $(shell $(CC) $(CFLAGS) -M -MT $(1).$(2) $(1).c | sed -z 's/\\\n //g') .makeopts Makefile .PHONY: all clean -all: haxserv +all: haxserv $(SOFILES) haxserv haxserv.so -haxserv: $(OFILES) .makeopts Makefile - $(CC) $(OFILES) -o $@ $(LDFLAGS) +haxserv: main.c + $(CC) main.c -o haxserv + +haxserv.so: $(OFILES) .makeopts Makefile + $(CC) $(OFILES) -shared -o $@ $(LDFLAGS) %.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +%.so: %.c + $(CC) $(CFLAGS) -shared -fPIC $< -o $@ + +$(call DEPS,config,o) -$(call DEPS,config) +$(call DEPS,general_network,o) -$(call DEPS,general_network) +$(call DEPS,haxstring_utils,o) -$(call DEPS,haxstring_utils) +$(call DEPS,real_main,o) -$(call DEPS,main) +$(call DEPS,main,o) -$(call DEPS,protocols) +$(call DEPS,protocols,o) -$(call DEPS,table) +$(call DEPS,table,o) ifeq ($(USE_PLAINTEXT),1) -$(call DEPS,plaintext_network) +$(call DEPS,plaintext_network,o) endif ifeq ($(USE_GNUTLS),1) -$(call DEPS,gnutls_network) +$(call DEPS,gnutls_network,o) endif ifeq ($(USE_OPENSSL),1) -$(call DEPS,openssl_network) +$(call DEPS,openssl_network,o) endif ifeq ($(USE_CLIENT),1) -$(call DEPS,client_network) +$(call DEPS,client_network,o) endif ifeq ($(USE_SERVER),1) -$(call DEPS,server_network) +$(call DEPS,server_network,o) endif ifeq ($(USE_PROTOCOLS),1) -$(call DEPS,protocols) +$(call DEPS,protocols,o) endif ifeq ($(INSPIRCD2_PROTOCOL),1) -$(call DEPS,protocols/inspircd2) +$(call DEPS,protocols/inspircd2,o) endif ifeq ($(USE_PSUEDOCLIENTS),1) -$(call DEPS,psuedoclients) +$(call DEPS,psuedoclients,o) endif ifeq ($(HAXSERV_PSUEDOCLIENT),1) -$(call DEPS,psuedoclients/haxserv) +$(call DEPS,psuedoclients/haxserv,so) endif clean: - $(RM) -r haxserv *.o protocols/*.o psuedoclients/*.o + $(RM) -r haxserv *.o *.so protocols/*.o protocols/*.so psuedoclients/*.o psuedoclients/*.so @@ -77,8 +77,9 @@ extern char *OPENSSL_KEY_PATH; // = "/etc/keys/key.pem", or 0 #endif #ifdef USE_SERVER -extern unsigned short SERVER_PORTS[NUM_NET_TYPES][NUM_PROTOCOLS]; // = 7000 -extern size_t SERVER_LISTEN[NUM_NET_TYPES][NUM_PROTOCOLS]; // = 16 +extern unsigned short SERVER_PORTS[NUM_NET_TYPES][NUM_PROTOCOLS]; // = {7000, ...}; +extern size_t SERVER_LISTEN[NUM_NET_TYPES][NUM_PROTOCOLS]; // = {16, ...}; +extern char SERVER_INCOMING[NUM_NET_TYPES][NUM_PROTOCOLS]; // = {1, ...}; #endif #ifdef USE_HAXSERV_PSUEDOCLIENT diff --git a/general_network.c b/general_network.c index a5251c6..8889b75 100644 --- a/general_network.c +++ b/general_network.c @@ -27,7 +27,9 @@ // OTHER DEALINGS IN THE SOFTWARE. #include <arpa/inet.h> +#include <dlfcn.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> @@ -122,6 +124,8 @@ struct table server_list = {0}; struct table user_list = {0}; struct table channel_list = {0}; +struct server_info *self; + int resolve(struct string address, struct string port, struct sockaddr *sockaddr) { // NULL isn't really valid in this anyways so... just checking it and replacing with null-terminated for now for (size_t i = 0; i < address.len; i++) @@ -202,6 +206,8 @@ int init_general_network(void) { own_info->latency = (struct timeval){0}; own_info->latency_valid = 1; + self = own_info; + user_list.array = malloc(0); channel_list.array = malloc(0); @@ -718,3 +724,26 @@ int notice(struct string from, struct string sender, struct string target, struc return 0; } + +int do_trivial_reloads(void) { +#ifdef USE_PSUEDOCLIENTS +#ifdef USE_HAXSERV_PSUEDOCLIENT + if (reload_psuedoclients[HAXSERV_PSUEDOCLIENT]) { + if (psuedoclients[HAXSERV_PSUEDOCLIENT].pre_reload() != 0) + return 1; + dlclose(psuedoclients[HAXSERV_PSUEDOCLIENT].dl_handle); + psuedoclients[HAXSERV_PSUEDOCLIENT].dl_handle = dlopen("psuedoclients/haxserv.so", RTLD_NOW | RTLD_LOCAL); + if (!psuedoclients[HAXSERV_PSUEDOCLIENT].dl_handle) { + puts(dlerror()); + abort(); // TODO: Ugh... + } + + psuedoclients[HAXSERV_PSUEDOCLIENT].post_reload = dlsym(psuedoclients[HAXSERV_PSUEDOCLIENT].dl_handle, "haxserv_psuedoclient_post_reload"); + if (psuedoclients[HAXSERV_PSUEDOCLIENT].post_reload() != 0) { + abort(); // TODO: Ugh... + } + } +#endif +#endif + return 0; +} diff --git a/general_network.h b/general_network.h index 889e653..def220c 100644 --- a/general_network.h +++ b/general_network.h @@ -133,6 +133,8 @@ int kick_channel(struct string from, struct string source, struct channel_info * int privmsg(struct string from, struct string sender, struct string target, struct string msg); int notice(struct string from, struct string sender, struct string target, struct string msg); +int do_trivial_reloads(void); + extern char casemap[UCHAR_MAX+1]; #define CASEMAP(x) (casemap[(unsigned char)x]) @@ -152,3 +154,5 @@ extern struct network networks[NUM_NET_TYPES]; extern struct table server_list; extern struct table user_list; extern struct table channel_list; + +extern struct server_info *self; diff --git a/haxserv.so b/haxserv.so Binary files differnew file mode 100755 index 0000000..b90a4ec --- /dev/null +++ b/haxserv.so @@ -1,4 +1,4 @@ -// "Main" file for haxserv +// One of the code files for HaxServ // // Written by: Test_User <hax@andrewyu.org> // @@ -26,108 +26,16 @@ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include <signal.h> -#include <pthread.h> - -#include "config.h" -#include "general_network.h" -#include "main.h" - -#ifdef USE_PLAINTEXT -#include "plaintext_network.h" -#endif -#ifdef USE_GNUTLS -#include "gnutls_network.h" -#endif -#ifdef USE_OPENSSL -#include "openssl_network.h" -#endif - -#ifdef USE_SERVER -#include "server_network.h" -#endif -#ifdef USE_CLIENT -#include "client_network.h" -#endif - -#ifdef USE_INSPIRCD2_PROTOCOL -#include "protocols/inspircd2.h" -#endif - -#ifdef USE_PSUEDOCLIENTS -#include "psuedoclients.h" -#endif - -#ifdef USE_HAXSERV_PSUEDOCLIENT -#include "psuedoclients/haxserv.h" -#endif - -pthread_attr_t pthread_attr; -pthread_mutexattr_t pthread_mutexattr; - -pthread_mutex_t state_lock = PTHREAD_MUTEX_INITIALIZER; +#include <dlfcn.h> +#include <stdio.h> int main(void) { - if (init_general_network() != 0) - return 1; - -#ifdef USE_PLAINTEXT - if (init_plaintext_network() != 0) // there's not really anything to do ahead of time with plain tcp networking, this is just here for consistency - return 1; -#endif - -#ifdef USE_GNUTLS - if (init_gnutls_network() != 0) - return 1; -#endif - -#ifdef USE_OPENSSL - if (init_openssl_network() != 0) - return 1; -#endif - -#ifdef USE_SERVER - if (init_server_network() != 0) + void *dl_handle = dlopen("./haxserv.so", RTLD_NOW | RTLD_GLOBAL); + if (!dl_handle) { + puts(dlerror()); return 1; -#endif - -#ifdef USE_CLIENT - if (init_client_network() != 0) - return 1; -#endif - -#ifdef USE_PSUEDOCLIENTS - if (init_psuedoclients() != 0) - return 1; -#endif - - { - struct sigaction tmp = { - .sa_handler = SIG_IGN, - }; - sigaction(SIGPIPE, &tmp, 0); } - if (pthread_attr_init(&pthread_attr) != 0) - return 1; - - if (pthread_mutexattr_init(&pthread_mutexattr) != 0) - return 1; - - if (pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED) != 0) // shouldn't actually happen - return 1; - -#ifdef USE_CLIENT - if (start_client_network() != 0) - return 1; -#endif - -#ifdef USE_SERVER - if (start_server_network() != 0) - return 1; -#endif - - pthread_exit(0); - - return 0; + int (*real_main)(void) = dlsym(dl_handle, "real_main"); + return real_main(); } diff --git a/protocols.c b/protocols.c index 55fb238..6ccf69c 100644 --- a/protocols.c +++ b/protocols.c @@ -41,6 +41,8 @@ struct protocol protocols[NUM_PROTOCOLS] = { .autoconnect = inspircd2_protocol_autoconnect, .update_propagations = inspircd2_protocol_update_propagations, + .propagate = inspircd2_protocol_propagate, + .propagate_new_server = inspircd2_protocol_propagate_new_server, .propagate_unlink_server = inspircd2_protocol_propagate_unlink_server, diff --git a/protocols.h b/protocols.h index 4665dad..915bb96 100644 --- a/protocols.h +++ b/protocols.h @@ -38,6 +38,8 @@ struct protocol { void * (*autoconnect)(void *config); void (*update_propagations)(void); + 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_unlink_server)(struct string from, struct server_info *a, struct server_info *b, size_t protocol); diff --git a/protocols/inspircd2.c b/protocols/inspircd2.c index c8d944c..9bd40b9 100644 --- a/protocols/inspircd2.c +++ b/protocols/inspircd2.c @@ -391,6 +391,7 @@ void * inspircd2_protocol_connection(void *type) { inspircd2_protocol_handle_connection_unlock_next: WRITES(2, STRING("\n")); + do_trivial_reloads(); pthread_mutex_unlock(&state_lock); memmove(full_msg.data, full_msg.data + msg_len + 1, full_msg.len - msg_len - 1); full_msg.len -= msg_len + 1; @@ -407,7 +408,7 @@ void * inspircd2_protocol_connection(void *type) { if (ready) { pthread_mutex_lock(&(state_lock)); - unlink_server(config->sid, get_table_index(server_list, config->sid), get_table_index(server_list, SID), INSPIRCD2_PROTOCOL); + unlink_server(config->sid, get_table_index(server_list, config->sid), self, INSPIRCD2_PROTOCOL); pthread_mutex_unlock(&(state_lock)); } @@ -469,7 +470,6 @@ void inspircd2_protocol_update_propagations_inner(struct server_info *source) { } void inspircd2_protocol_update_propagations(void) { - struct server_info *self = get_table_index(server_list, SID); for (size_t i = 0; i < server_list.len; i++) { struct server_info *other = server_list.array[i].ptr; if (other->protocol == INSPIRCD2_PROTOCOL) { @@ -480,7 +480,7 @@ void inspircd2_protocol_update_propagations(void) { inspircd2_protocol_update_propagations_inner(self); } -void inspircd2_protocol_propagate(struct string from, struct server_info *self, struct string msg) { +void inspircd2_protocol_propagate(struct string from, struct string msg) { for (size_t i = 0; i < self->connected_to.len; i++) { struct server_info *adjacent = self->connected_to.array[i].ptr; if (adjacent->protocol != INSPIRCD2_PROTOCOL || STRING_EQ(from, adjacent->sid)) @@ -492,41 +492,39 @@ void inspircd2_protocol_propagate(struct string from, struct server_info *self, // [:source] SERVER <name> <password> <always 0> <sid> <fullname> void inspircd2_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); + inspircd2_protocol_propagate(from, STRING(":")); if (info->protocol == INSPIRCD2_PROTOCOL) - inspircd2_protocol_propagate(from, self, attached_to); + inspircd2_protocol_propagate(from, attached_to); else // Just pretend servers connected via a different protocol are connected directly to us - inspircd2_protocol_propagate(from, self, SID); + inspircd2_protocol_propagate(from, SID); - inspircd2_protocol_propagate(from, self, STRING(" SERVER ")); - inspircd2_protocol_propagate(from, self, info->name); - inspircd2_protocol_propagate(from, self, STRING(" * 0 ")); - inspircd2_protocol_propagate(from, self, info->sid); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, info->fullname); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(" SERVER ")); + inspircd2_protocol_propagate(from, info->name); + inspircd2_protocol_propagate(from, STRING(" * 0 ")); + inspircd2_protocol_propagate(from, info->sid); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, info->fullname); + inspircd2_protocol_propagate(from, STRING("\n")); - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, info->sid); - inspircd2_protocol_propagate(from, self, STRING(" BURST ")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, info->sid); + inspircd2_protocol_propagate(from, STRING(" BURST ")); time_t current = time(0); struct string current_time; char err = unsigned_to_str((size_t)current, ¤t_time); if (current < 0 || err) { - inspircd2_protocol_propagate(from, self, STRING("1")); + inspircd2_protocol_propagate(from, STRING("1")); } else { - inspircd2_protocol_propagate(from, self, current_time); + inspircd2_protocol_propagate(from, current_time); free(current_time.data); } - inspircd2_protocol_propagate(from, self, STRING("\n:")); - inspircd2_protocol_propagate(from, self, info->sid); - inspircd2_protocol_propagate(from, self, STRING(" ENDBURST\n")); + inspircd2_protocol_propagate(from, STRING("\n:")); + inspircd2_protocol_propagate(from, info->sid); + inspircd2_protocol_propagate(from, STRING(" ENDBURST\n")); } // [:source] SQUIT <sid> [<reason>?] @@ -543,159 +541,139 @@ void inspircd2_protocol_propagate_unlink_server(struct string from, struct serve return; } - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); + inspircd2_protocol_propagate(from, STRING(":")); if (protocol == INSPIRCD2_PROTOCOL) - inspircd2_protocol_propagate(from, self, source->sid); + inspircd2_protocol_propagate(from, source->sid); else - inspircd2_protocol_propagate(from, self, SID); - inspircd2_protocol_propagate(from, self, STRING(" SQUIT ")); - inspircd2_protocol_propagate(from, self, target->sid); - inspircd2_protocol_propagate(from, self, STRING(" :\n")); + inspircd2_protocol_propagate(from, SID); + inspircd2_protocol_propagate(from, STRING(" SQUIT ")); + inspircd2_protocol_propagate(from, target->sid); + inspircd2_protocol_propagate(from, STRING(" :\n")); } // [:source] UID <UID> <nick_ts> <nick> <host> <vhost> <ident> <address> <user_ts> <modes> [<mode args>] <fullname> void inspircd2_protocol_propagate_new_user(struct string from, struct user_info *info) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, info->server); - inspircd2_protocol_propagate(from, self, STRING(" UID ")); - inspircd2_protocol_propagate(from, self, info->uid); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->nick_ts_str); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->nick); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->host); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->vhost); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->ident); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->address); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, info->user_ts_str); - inspircd2_protocol_propagate(from, self, STRING(" + :")); - inspircd2_protocol_propagate(from, self, info->fullname); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, info->server); + inspircd2_protocol_propagate(from, STRING(" UID ")); + inspircd2_protocol_propagate(from, info->uid); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->nick_ts_str); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->nick); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->host); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->vhost); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->ident); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->address); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, info->user_ts_str); + inspircd2_protocol_propagate(from, STRING(" + :")); + inspircd2_protocol_propagate(from, info->fullname); + inspircd2_protocol_propagate(from, STRING("\n")); } // :source NICK <nick> <timestamp> void inspircd2_protocol_propagate_rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp, struct string timestamp_str) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, user->uid); - inspircd2_protocol_propagate(from, self, STRING(" NICK ")); - inspircd2_protocol_propagate(from, self, nick); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, timestamp_str); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, user->uid); + inspircd2_protocol_propagate(from, STRING(" NICK ")); + inspircd2_protocol_propagate(from, nick); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, timestamp_str); + inspircd2_protocol_propagate(from, STRING("\n")); } // :source QUIT [<reason>?] void inspircd2_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, info->uid); - inspircd2_protocol_propagate(from, self, STRING(" QUIT :")); - inspircd2_protocol_propagate(from, self, reason); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, info->uid); + inspircd2_protocol_propagate(from, STRING(" QUIT :")); + inspircd2_protocol_propagate(from, reason); + inspircd2_protocol_propagate(from, STRING("\n")); } // [:source] KILL <target> [<reason>?] void inspircd2_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, source); - inspircd2_protocol_propagate(from, self, STRING(" KILL ")); - inspircd2_protocol_propagate(from, self, info->uid); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, reason); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, source); + inspircd2_protocol_propagate(from, STRING(" KILL ")); + inspircd2_protocol_propagate(from, info->uid); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, reason); + inspircd2_protocol_propagate(from, STRING("\n")); } // :source OPERTYPE <type> void inspircd2_protocol_propagate_oper_user(struct string from, struct user_info *user, struct string type) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, user->uid); - inspircd2_protocol_propagate(from, self, STRING(" OPERTYPE :")); - inspircd2_protocol_propagate(from, self, type); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, user->uid); + inspircd2_protocol_propagate(from, STRING(" OPERTYPE :")); + inspircd2_protocol_propagate(from, type); + inspircd2_protocol_propagate(from, STRING("\n")); } // [:source] FJOIN <channel> <timestamp> <modes> [<mode args>] <userlist: modes,uid [...]> void inspircd2_protocol_propagate_set_channel(struct string from, struct channel_info *channel, char is_new_server, size_t user_count, struct user_info **users) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, SID); - inspircd2_protocol_propagate(from, self, STRING(" FJOIN ")); - inspircd2_protocol_propagate(from, self, channel->name); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, channel->channel_ts_str); - inspircd2_protocol_propagate(from, self, STRING(" + :")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, SID); + inspircd2_protocol_propagate(from, STRING(" FJOIN ")); + inspircd2_protocol_propagate(from, channel->name); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, channel->channel_ts_str); + inspircd2_protocol_propagate(from, STRING(" + :")); for (size_t x = 0; x < user_count; x++) { - inspircd2_protocol_propagate(from, self, STRING(",")); - inspircd2_protocol_propagate(from, self, users[x]->uid); + inspircd2_protocol_propagate(from, STRING(",")); + inspircd2_protocol_propagate(from, users[x]->uid); if (x != channel->user_list.len - 1) - inspircd2_protocol_propagate(from, self, STRING(" ")); + inspircd2_protocol_propagate(from, STRING(" ")); } - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING("\n")); } // [:source] FJOIN <channel> <timestamp> <modes> [<mode args>] <userlist: modes,uid [...]> void inspircd2_protocol_propagate_join_channel(struct string from, struct channel_info *channel, size_t user_count, struct user_info **users) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, SID); - inspircd2_protocol_propagate(from, self, STRING(" FJOIN ")); - inspircd2_protocol_propagate(from, self, channel->name); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, channel->channel_ts_str); - inspircd2_protocol_propagate(from, self, STRING(" + :")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, SID); + inspircd2_protocol_propagate(from, STRING(" FJOIN ")); + inspircd2_protocol_propagate(from, channel->name); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, channel->channel_ts_str); + inspircd2_protocol_propagate(from, STRING(" + :")); for (size_t x = 0; x < user_count; x++) { - inspircd2_protocol_propagate(from, self, STRING(",")); - inspircd2_protocol_propagate(from, self, users[x]->uid); + inspircd2_protocol_propagate(from, STRING(",")); + inspircd2_protocol_propagate(from, users[x]->uid); if (x != channel->user_list.len - 1) - inspircd2_protocol_propagate(from, self, STRING(" ")); + inspircd2_protocol_propagate(from, STRING(" ")); } - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING("\n")); } // :source PART <channel> [<reason>] void inspircd2_protocol_propagate_part_channel(struct string from, struct channel_info *channel, struct user_info *user, struct string reason) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, user->uid); - inspircd2_protocol_propagate(from, self, STRING(" PART ")); - inspircd2_protocol_propagate(from, self, channel->name); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, reason); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, user->uid); + inspircd2_protocol_propagate(from, STRING(" PART ")); + inspircd2_protocol_propagate(from, channel->name); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, reason); + inspircd2_protocol_propagate(from, STRING("\n")); } // [:source] KICK <channel> <user> [<reason>] void inspircd2_protocol_propagate_kick_channel(struct string from, struct string source, struct channel_info *channel, struct user_info *user, struct string reason) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, source); - inspircd2_protocol_propagate(from, self, STRING(" KICK ")); - inspircd2_protocol_propagate(from, self, channel->name); - inspircd2_protocol_propagate(from, self, STRING(" ")); - inspircd2_protocol_propagate(from, self, user->uid); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, reason); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, source); + inspircd2_protocol_propagate(from, STRING(" KICK ")); + inspircd2_protocol_propagate(from, channel->name); + inspircd2_protocol_propagate(from, STRING(" ")); + inspircd2_protocol_propagate(from, user->uid); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, reason); + inspircd2_protocol_propagate(from, STRING("\n")); } // [:source] PRIVMSG <target> <message> @@ -726,15 +704,13 @@ void inspircd2_protocol_propagate_privmsg(struct string from, struct string sour networks[adjacent->net].send(adjacent->handle, STRING("\n")); } else { // TODO: Trim target list for channels as well - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, source); - inspircd2_protocol_propagate(from, self, STRING(" PRIVMSG ")); - inspircd2_protocol_propagate(from, self, target); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, msg); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, source); + inspircd2_protocol_propagate(from, STRING(" PRIVMSG ")); + inspircd2_protocol_propagate(from, target); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, msg); + inspircd2_protocol_propagate(from, STRING("\n")); } } @@ -766,15 +742,13 @@ void inspircd2_protocol_propagate_notice(struct string from, struct string sourc networks[adjacent->net].send(adjacent->handle, STRING("\n")); } else { // TODO: Trim target list for channels as well - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(from, self, STRING(":")); - inspircd2_protocol_propagate(from, self, source); - inspircd2_protocol_propagate(from, self, STRING(" NOTICE ")); - inspircd2_protocol_propagate(from, self, target); - inspircd2_protocol_propagate(from, self, STRING(" :")); - inspircd2_protocol_propagate(from, self, msg); - inspircd2_protocol_propagate(from, self, STRING("\n")); + inspircd2_protocol_propagate(from, STRING(":")); + inspircd2_protocol_propagate(from, source); + inspircd2_protocol_propagate(from, STRING(" NOTICE ")); + inspircd2_protocol_propagate(from, target); + inspircd2_protocol_propagate(from, STRING(" :")); + inspircd2_protocol_propagate(from, msg); + inspircd2_protocol_propagate(from, STRING("\n")); } } @@ -840,7 +814,6 @@ void inspircd2_protocol_introduce_servers_to_inner(size_t net, void *handle, str } void inspircd2_protocol_introduce_servers_to(size_t net, void *handle) { - struct server_info *self = get_table_index(server_list, SID); for (size_t i = 0; i < self->connected_to.len; i++) { struct server_info *info = self->connected_to.array[i].ptr; if (info->protocol == INSPIRCD2_PROTOCOL) { // This server hasn't been added to the list yet, so no need to check for that diff --git a/protocols/inspircd2.h b/protocols/inspircd2.h index 3309582..47df9a6 100644 --- a/protocols/inspircd2.h +++ b/protocols/inspircd2.h @@ -41,7 +41,7 @@ void * inspircd2_protocol_connection(void *type); void * inspircd2_protocol_autoconnect(void *type); void inspircd2_protocol_update_propagations(void); -void inspircd2_protocol_propagate(struct string from, struct server_info *self, struct string msg); +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_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); diff --git a/psuedoclients.c b/psuedoclients.c index 3b0a83b..b5d88a0 100644 --- a/psuedoclients.c +++ b/psuedoclients.c @@ -26,30 +26,31 @@ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. +#include <dlfcn.h> +#include <stdio.h> + #include "haxstring.h" #include "psuedoclients.h" -#ifdef USE_HAXSERV_PSUEDOCLIENT -#include "psuedoclients/haxserv.h" -#endif - -struct psuedoclient psuedoclients[NUM_PSUEDOCLIENTS] = { -#ifdef USE_HAXSERV_PSUEDOCLIENT - [HAXSERV_PSUEDOCLIENT] = { - .init = haxserv_psuedoclient_init, +struct psuedoclient psuedoclients[NUM_PSUEDOCLIENTS] = {0}; - .allow_kill = haxserv_psuedoclient_allow_kill, - .allow_kick = haxserv_psuedoclient_allow_kick, - - .handle_privmsg = haxserv_psuedoclient_handle_privmsg, - }, -#endif -}; +char reload_psuedoclients[NUM_PSUEDOCLIENTS] = {0}; int init_psuedoclients(void) { #ifdef USE_HAXSERV_PSUEDOCLIENT - if (psuedoclients[HAXSERV_PSUEDOCLIENT].init() != 0) - return 1; + { + void *dl_handle = dlopen("psuedoclients/haxserv.so", RTLD_NOW | RTLD_LOCAL); + if (!dl_handle) { + puts(dlerror()); + return 1; + } + + psuedoclients[HAXSERV_PSUEDOCLIENT].dl_handle = dl_handle; + psuedoclients[HAXSERV_PSUEDOCLIENT].init = dlsym(dl_handle, "haxserv_psuedoclient_init"); + + if (psuedoclients[HAXSERV_PSUEDOCLIENT].init() != 0) + return 1; + } #endif return 0; diff --git a/psuedoclients.h b/psuedoclients.h index 68653ad..db720e3 100644 --- a/psuedoclients.h +++ b/psuedoclients.h @@ -30,8 +30,13 @@ #include "general_network.h" struct psuedoclient { + void *dl_handle; + int (*init)(void); + int (*pre_reload)(void); + int (*post_reload)(void); + int (*allow_kill)(struct string from, struct string source, struct user_info *user, struct string reason); int (*allow_kick)(struct string from, struct string source, struct channel_info *channel, struct user_info *user, struct string reason); @@ -44,6 +49,8 @@ int init_psuedoclients(void); #define HAXSERV_PSUEDOCLIENT 0 #endif -#define NUM_PSUEDOCLIENTS +#define NUM_PSUEDOCLIENTS 1 extern struct psuedoclient psuedoclients[NUM_PSUEDOCLIENTS]; + +extern char reload_psuedoclients[NUM_PSUEDOCLIENTS]; diff --git a/psuedoclients/haxserv.c b/psuedoclients/haxserv.c index e4da682..0613a11 100644 --- a/psuedoclients/haxserv.c +++ b/psuedoclients/haxserv.c @@ -26,6 +26,7 @@ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. +#include <dlfcn.h> #include <stddef.h> #include <stdlib.h> #include <time.h> @@ -38,8 +39,8 @@ #include "haxserv.h" -#ifdef USE_INSPIRCD2_PROTOCOL -#include "../protocols/inspircd2.h" +#ifdef USE_PROTOCOLS +#include "../protocols.h" #endif struct table haxserv_psuedoclient_commands = {0}; @@ -67,7 +68,12 @@ int haxserv_psuedoclient_init(void) { return 1; } + return haxserv_psuedoclient_post_reload(); +} + +int haxserv_psuedoclient_post_reload(void) { haxserv_psuedoclient_commands.array = malloc(0); + haxserv_psuedoclient_prefixes.array = malloc(0); if (set_table_index(&haxserv_psuedoclient_commands, STRING("HELP"), &haxserv_psuedoclient_help_command_def) != 0) return 1; @@ -91,6 +97,29 @@ int haxserv_psuedoclient_init(void) { haxserv_psuedoclient_spam_command_def.privs = HAXSERV_REQUIRED_OPER_TYPE; if (set_table_index(&haxserv_psuedoclient_commands, STRING("SPAM"), &haxserv_psuedoclient_spam_command_def) != 0) return 1; + haxserv_psuedoclient_spam_command_def.privs = HAXSERV_REQUIRED_OPER_TYPE; + if (set_table_index(&haxserv_psuedoclient_commands, STRING("RELOAD"), &haxserv_psuedoclient_reload_command_def) != 0) + return 1; + + psuedoclients[HAXSERV_PSUEDOCLIENT].init = haxserv_psuedoclient_init; + + psuedoclients[HAXSERV_PSUEDOCLIENT].post_reload = haxserv_psuedoclient_post_reload; + psuedoclients[HAXSERV_PSUEDOCLIENT].pre_reload = haxserv_psuedoclient_pre_reload; + + psuedoclients[HAXSERV_PSUEDOCLIENT].allow_kill = haxserv_psuedoclient_allow_kill; + psuedoclients[HAXSERV_PSUEDOCLIENT].allow_kick = haxserv_psuedoclient_allow_kick; + + psuedoclients[HAXSERV_PSUEDOCLIENT].handle_privmsg = haxserv_psuedoclient_handle_privmsg; + + return 0; +} + +int haxserv_psuedoclient_pre_reload(void) { + clear_table(&haxserv_psuedoclient_commands); + clear_table(&haxserv_psuedoclient_prefixes); + + free(haxserv_psuedoclient_commands.array); + free(haxserv_psuedoclient_prefixes.array); return 0; } @@ -397,10 +426,8 @@ struct command_def haxserv_psuedoclient_clear_command_def = { #ifdef USE_INSPIRCD2_PROTOCOL int haxserv_psuedoclient_raw_inspircd2_command(struct string from, struct string sender, struct string original_message, struct string respond_to, size_t argc, struct string *argv) { - struct server_info *self = get_table_index(server_list, SID); - - inspircd2_protocol_propagate(SID, self, original_message); - inspircd2_protocol_propagate(SID, self, STRING("\n")); + protocols[INSPIRCD2_PROTOCOL].propagate(SID, original_message); + protocols[INSPIRCD2_PROTOCOL].propagate(SID, STRING("\n")); return 0; } @@ -537,3 +564,15 @@ struct command_def haxserv_psuedoclient_spam_command_def = { .aligned_name = STRING("spam "), .name = STRING("spam"), }; + +int haxserv_psuedoclient_reload_command(struct string from, struct string sender, struct string original_message, struct string respond_to, size_t argc, struct string *argv) { + reload_psuedoclients[HAXSERV_PSUEDOCLIENT] = 1; + + return 0; +} +struct command_def haxserv_psuedoclient_reload_command_def = { + .func = haxserv_psuedoclient_reload_command, + .summary = STRING("Reloads a module."), + .aligned_name = STRING("reload "), + .name = STRING("reload"), +}; diff --git a/psuedoclients/haxserv.h b/psuedoclients/haxserv.h index 6d6a7c0..f2f785e 100644 --- a/psuedoclients/haxserv.h +++ b/psuedoclients/haxserv.h @@ -39,6 +39,9 @@ struct command_def { int haxserv_psuedoclient_init(void); +int haxserv_psuedoclient_post_reload(void); +int haxserv_psuedoclient_pre_reload(void); + int haxserv_psuedoclient_allow_kill(struct string from, struct string source, struct user_info *user, struct string reason); int haxserv_psuedoclient_allow_kick(struct string from, struct string source, struct channel_info *channel, struct user_info *user, struct string reason); @@ -55,3 +58,4 @@ extern struct command_def haxserv_psuedoclient_raw_inspircd2_command_def; #endif extern struct command_def haxserv_psuedoclient_kill_command_def; extern struct command_def haxserv_psuedoclient_spam_command_def; +extern struct command_def haxserv_psuedoclient_reload_command_def; diff --git a/psuedoclients/haxserv.so b/psuedoclients/haxserv.so Binary files differnew file mode 100755 index 0000000..1b8b3a8 --- /dev/null +++ b/psuedoclients/haxserv.so diff --git a/real_main.c b/real_main.c new file mode 100644 index 0000000..6548449 --- /dev/null +++ b/real_main.c @@ -0,0 +1,133 @@ +// "Main" file for haxserv +// +// Written by: Test_User <hax@andrewyu.org> +// +// This is free and unencumbered software released into the public +// domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. +// +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#include <signal.h> +#include <pthread.h> + +#include "config.h" +#include "general_network.h" +#include "main.h" + +#ifdef USE_PLAINTEXT +#include "plaintext_network.h" +#endif +#ifdef USE_GNUTLS +#include "gnutls_network.h" +#endif +#ifdef USE_OPENSSL +#include "openssl_network.h" +#endif + +#ifdef USE_SERVER +#include "server_network.h" +#endif +#ifdef USE_CLIENT +#include "client_network.h" +#endif + +#ifdef USE_INSPIRCD2_PROTOCOL +#include "protocols/inspircd2.h" +#endif + +#ifdef USE_PSUEDOCLIENTS +#include "psuedoclients.h" +#endif + +#ifdef USE_HAXSERV_PSUEDOCLIENT +#include "psuedoclients/haxserv.h" +#endif + +pthread_attr_t pthread_attr; +pthread_mutexattr_t pthread_mutexattr; + +pthread_mutex_t state_lock = PTHREAD_MUTEX_INITIALIZER; + +int real_main(void) { + if (init_general_network() != 0) + return 1; + +#ifdef USE_PLAINTEXT + if (init_plaintext_network() != 0) // there's not really anything to do ahead of time with plain tcp networking, this is just here for consistency + return 1; +#endif + +#ifdef USE_GNUTLS + if (init_gnutls_network() != 0) + return 1; +#endif + +#ifdef USE_OPENSSL + if (init_openssl_network() != 0) + return 1; +#endif + +#ifdef USE_SERVER + if (init_server_network() != 0) + return 1; +#endif + +#ifdef USE_CLIENT + if (init_client_network() != 0) + return 1; +#endif + +#ifdef USE_PSUEDOCLIENTS + if (init_psuedoclients() != 0) + return 1; +#endif + + { + struct sigaction tmp = { + .sa_handler = SIG_IGN, + }; + sigaction(SIGPIPE, &tmp, 0); + } + + if (pthread_attr_init(&pthread_attr) != 0) + return 1; + + if (pthread_mutexattr_init(&pthread_mutexattr) != 0) + return 1; + + if (pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED) != 0) // shouldn't actually happen + return 1; + +#ifdef USE_CLIENT + if (start_client_network() != 0) + return 1; +#endif + +#ifdef USE_SERVER + if (start_server_network() != 0) + return 1; +#endif + + pthread_exit(0); + + return 0; +} diff --git a/server_network.c b/server_network.c index 1afd370..bf9e442 100644 --- a/server_network.c +++ b/server_network.c @@ -95,15 +95,17 @@ int start_server_network_threads(size_t net) { pthread_t trash; // Not actually used, so discard struct server_network_info *type; #ifdef USE_INSPIRCD2_PROTOCOL - type = malloc(sizeof(*type)); - if (!type) - return 1; - type->net_type = net; - type->protocol = INSPIRCD2_PROTOCOL; - type->is_incoming = 1; - if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { - free(type); - return 1; + if (SERVER_INCOMING[net][INSPIRCD2_PROTOCOL]) { + type = malloc(sizeof(*type)); + if (!type) + return 1; + type->net_type = net; + type->protocol = INSPIRCD2_PROTOCOL; + type->is_incoming = 1; + if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { + free(type); + return 1; + } } #endif return 0; @@ -118,19 +120,6 @@ void * server_accept_thread(void *type) { protocol = t->protocol; } - // Check if there is actually an incoming server connection configured using this net+protocol, and if not just return from this thread; some excess may have been spawned - { - char found = 0; - for (size_t i = 0; i < SERVER_CONFIG_LEN; i++) { - if (SERVER_CONFIG[i].protocol == protocol && !(SERVER_CONFIG[i].autoconnect)) { // TODO: Don't make autoconnect conflict with incoming connections - found = 1; - break; - } - } - if (!found) - return 0; - } - int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listen_fd < 0) return 0; |