diff --git a/src/client/stabber.c b/src/client/stabber.c index 46cd6a6..9872c06 100644 --- a/src/client/stabber.c +++ b/src/client/stabber.c @@ -28,3 +28,9 @@ stbbr_for(char *id, char *stream) prime_for(id, stream); return 1; } + +void +stbbr_stop(void) +{ + server_stop(); +} diff --git a/src/server/parser.c b/src/server/parser.c index b8769a0..1948af0 100644 --- a/src/server/parser.c +++ b/src/server/parser.c @@ -95,6 +95,7 @@ void parser_close(void) { XML_ParserFree(parser); + parser = NULL; } void diff --git a/src/server/prime.c b/src/server/prime.c index f221226..01d7151 100644 --- a/src/server/prime.c +++ b/src/server/prime.c @@ -17,9 +17,12 @@ void prime_free_all(void) { free(required_passwd); + required_passwd = NULL; + if (idstubs) { g_hash_table_destroy(idstubs); } + idstubs = NULL; } void diff --git a/src/server/server.c b/src/server/server.c index 8aad494..ee487ba 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -26,9 +26,9 @@ static XMPPClient *client; static void _shutdown(void); -static void _signal_handler(int sig); static int listen_socket; +static pthread_t server_thread; void write_stream(const char * const stanza) @@ -50,7 +50,7 @@ write_stream(const char * const stanza) } else { log_println(""); log_println("Error sending on connection: %s", strerror(errno)); - exit(0); + return; } } @@ -77,7 +77,7 @@ read_stream(void) log_println(""); log_println("%s:%d - Client disconnected.", client->ip, client->port); g_string_free(stream, TRUE); - exit(0); + return -1; } // error @@ -92,7 +92,7 @@ read_stream(void) log_println(""); log_println("Error receiving on connection: %s", strerror(errno)); g_string_free(stream, TRUE); - exit(0); + return -1; } } @@ -104,7 +104,8 @@ read_stream(void) log_print_chars("\n"); log_println("--> Stream end callback fired"); write_stream(STREAM_END); - break; + _shutdown(); + return 0; } memset(buf, 0, sizeof(buf)); } @@ -144,7 +145,7 @@ auth_callback(XMPPStanza *stanza) if (g_strcmp0(client->password, expected_password) != 0) { write_stream(AUTH_FAIL); write_stream(STREAM_END); - exit(0); + return; } write_stream(AUTH_RESP); @@ -172,7 +173,7 @@ _start_server_cb(void* userdata) int res = fcntl(listen_socket, F_SETFL, fcntl(listen_socket, F_GETFL, 0) | O_NONBLOCK); if (res == -1) { log_println("Error setting nonblocking on listen socket: %s", strerror(errno)); - exit(0); + return NULL; } // listen socket read timeout @@ -183,7 +184,7 @@ _start_server_cb(void* userdata) res = setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); if (res < 0) { log_println("Error setting listen socket options: %s", strerror(errno)); - exit(0); + return NULL; } // wait for connection @@ -193,7 +194,7 @@ _start_server_cb(void* userdata) while ((client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, (socklen_t*)&c)) == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { log_println("Accept failed: %s", strerror(errno)); - exit(0); + return NULL; } errno = 0; } @@ -202,7 +203,7 @@ _start_server_cb(void* userdata) res = fcntl(client_socket, F_SETFL, fcntl(client_socket, F_GETFL, 0) | O_NONBLOCK); if (res == -1) { log_println("Error setting nonblocking on client socket: %s", strerror(errno)); - exit(0); + return NULL; } // client socket read timeout @@ -210,7 +211,7 @@ _start_server_cb(void* userdata) res = setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); if (res < 0) { log_println("Error setting client socket options: %s", strerror(errno)); - exit(0); + return NULL; } client = xmppclient_new(client_addr, client_socket); @@ -229,16 +230,12 @@ server_run(int port) log_init(); log_println("Starting on port: %d...", port); - // signal handlers - signal(SIGSTOP, _signal_handler); - signal(SIGINT, _signal_handler); - atexit(_shutdown); - // create listen socket errno = 0; listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (listen_socket == -1) { log_println("Could not create socket: %s", strerror(errno)); + _shutdown(); return -1; } @@ -247,11 +244,20 @@ server_run(int port) server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(port); + int reuse = 1; + int ret = setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); + if (ret == -1) { + log_println("Set socket options failed: %s", strerror(errno)); + _shutdown(); + return -1; + } + // bind socket to port errno = 0; - int ret = bind(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); + ret = bind(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret == -1) { log_println("Bind failed: %s", strerror(errno)); + _shutdown(); return -1; } @@ -260,6 +266,7 @@ server_run(int port) ret = listen(listen_socket, 5); if (ret == -1) { log_println("Listen failed: %s", strerror(errno)); + _shutdown(); return -1; } @@ -268,32 +275,33 @@ server_run(int port) prime_init(); // start client processor thread - pthread_t server_thread; int res = pthread_create(&server_thread, NULL, _start_server_cb, NULL); if (res != 0) { + _shutdown(); return -1; } - pthread_detach(server_thread); return 0; } +void +server_stop(void) +{ + pthread_join(server_thread, NULL); +} + static void _shutdown(void) -{ - _signal_handler(-1); -} - -static void -_signal_handler(int sig) { log_println("SHUTDOWN"); // stanza_show_all(); xmppclient_end_session(client); + client = NULL; + parser_close(); - while (recv(listen_socket, NULL, 1, 0) > 0) {} shutdown(listen_socket, 2); + while (recv(listen_socket, NULL, 1, 0) > 0) {} close(listen_socket); prime_free_all(); diff --git a/src/server/server.h b/src/server/server.h index 3e217e7..6c463b2 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -2,4 +2,5 @@ #define __H_SERVER int server_run(int port); +void server_stop(void); #endif diff --git a/src/server/stanza.c b/src/server/stanza.c index 3f38a2c..af409b9 100644 --- a/src/server/stanza.c +++ b/src/server/stanza.c @@ -192,4 +192,5 @@ void stanza_free_all(void) { g_list_free_full(stanzas, (GDestroyNotify)_stanza_free); + stanzas = NULL; } diff --git a/src/server/xmppclient.c b/src/server/xmppclient.c index 22a1b9c..0a9d55b 100644 --- a/src/server/xmppclient.c +++ b/src/server/xmppclient.c @@ -28,8 +28,8 @@ xmppclient_end_session(XMPPClient *client) { if (client) { if (client->sock) { - while (recv(client->sock, NULL, 1, 0) > 0) {} shutdown(client->sock, 2); + while (recv(client->sock, NULL, 1, 0) > 0) {} close(client->sock); } free(client->ip); diff --git a/stabber.h b/stabber.h index cf8554f..aaf9ad1 100644 --- a/stabber.h +++ b/stabber.h @@ -2,6 +2,7 @@ #define __H_STABBER int stbbr_start(int port); +void stbbr_stop(void); int stbbr_auth_passwd(char *password); void stbbr_for(char *id, char *stream);