From 75c3f063cf96fc403291affb00289743553475d1 Mon Sep 17 00:00:00 2001 From: Kouya Heika Date: Tue, 21 Apr 2026 02:24:00 -0500 Subject: [PATCH] Add icon field to service, fix ping calculation, longer backoff for domain name resolution, make service deinit function --- src/services.c | 89 +++++++++++++++++++++++++------------------------- src/services.h | 2 ++ 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/services.c b/src/services.c index ffb20cd..2f250e6 100644 --- a/src/services.c +++ b/src/services.c @@ -8,7 +8,7 @@ #define POLLRDHUP 0x2000 #endif -uint8_t report_queued = 0; +uint8_t report_queued = 1; uint64_t queued_time = 0; Vector services; Vector status_timeline; // of StatusPeroid* @@ -37,7 +37,7 @@ void* run_endpoint(void* endpoint) { if (ret != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret)); queue_report((struct EndpointStatus){ self, DOWN, -1.0 }); - sleep(self->backoff); + sleep(self->backoff*2); // sleep longer to avoid spamming for DNS lookup continue; } } @@ -50,9 +50,6 @@ void* run_endpoint(void* endpoint) { int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); - struct timespec connect_start; - clock_gettime(CLOCK_REALTIME_ALARM, &connect_start); - int ret = connect(fd, rp->ai_addr, rp->ai_addrlen); int error = 0; if (strcmp(self->scheme, "tcp") == 0) { @@ -103,15 +100,7 @@ void* run_endpoint(void* endpoint) { } } } - if (fd > 0) { - struct timespec now; - clock_gettime(CLOCK_REALTIME_ALARM, &now); - - double ping = (now.tv_sec - connect_start.tv_sec) * 1000.0 + (now.tv_nsec - connect_start.tv_nsec) / 1000000.0; - - self->sockfd = fd; - self->last_errno = 0; - } + self->sockfd = fd; } if (self->sockfd < 0) { @@ -122,9 +111,8 @@ void* run_endpoint(void* endpoint) { queue_report((struct EndpointStatus){ self, DOWN, -1.0 }); sleep(self->backoff); continue; - } + } else self->last_errno = 0; } - struct pollfd pfd = { .fd = self->sockfd, .events = POLLIN | POLLERR | POLLHUP | POLLRDHUP }; int pollret = poll(&pfd, 1, (self->backoff > 0 ? self->backoff * 1000 : 10000)); @@ -138,19 +126,22 @@ void* run_endpoint(void* endpoint) { if (recv(self->sockfd, NULL, sizeof(NULL), MSG_DONTWAIT | MSG_PEEK) < 0) { close(self->sockfd); self->sockfd = -1; + sleep(self->backoff); continue; } } - if ((pfd.revents & (POLLERR | POLLHUP | POLLRDHUP)) || pfd.events & POLLRDHUP) { + if (pfd.revents & (POLLERR | POLLHUP | POLLRDHUP)) { close(self->sockfd); self->sockfd = -1; + sleep(self->backoff); continue; } if (strcmp(self->scheme, "udp") == 0 && send(self->sockfd, NULL, 0, 0) < 0) { close(self->sockfd); self->sockfd = -1; + sleep(self->backoff); continue; } @@ -158,8 +149,17 @@ void* run_endpoint(void* endpoint) { time_t now = time(NULL); if (now - self->last_check >= self->backoff) { self->last_check = now; - queue_report((struct EndpointStatus){ self, UP, self->last_ping }); + + double ping = 0.0; + if (strcmp(self->scheme, "udp") != 0) { + struct tcp_info info = {0}; socklen_t len = sizeof(info); + if (getsockopt(self->sockfd, IPPROTO_TCP, TCP_INFO, &info, &len) == 0) { + ping = info.tcpi_rtt / 1000.0; + } + } + queue_report((struct EndpointStatus){ self, UP, ping }); } + sleep(self->backoff); continue; } @@ -268,25 +268,11 @@ uint8_t add_endpoint(struct Service* self, const char* uri) { return 0; } -enum State get_state(struct Service** self) { - Iterator it = vector_begin(&(*self)->endpoints); - Iterator end = vector_end(&(*self)->endpoints); - int up_count = 0; int total_count = (*self)->endpoints.size; - for (; !iterator_equals(&it, &end); iterator_increment(&it)) { - struct Endpoint* endpoint = *(struct Endpoint**)iterator_get(&it); - if (endpoint->last_state == UP) - up_count++; - } - if (up_count == total_count) return UP; - else if (up_count == 0) return DOWN; - else return PARTIAL; -} - void report() { if (status_timeline.size + 1 >= status_timeline.capacity) vector_pop_front(&status_timeline); // remove (what should be) oldest entry - struct StatusPeroid* peroid = malloc(512); + struct StatusPeroid* peroid = malloc(sizeof(struct StatusPeroid)); peroid->time = queued_time; vector_setup(&peroid->server_statuses, services.size, sizeof(struct ServerStatus*)); @@ -305,7 +291,7 @@ struct ServerStatus* update_server_status(struct Service** self) { struct Service* service = *self; double pings[service->endpoints.size] = {}; - struct ServerStatus* server_status = malloc(512); + struct ServerStatus* server_status = malloc(sizeof(struct ServerStatus)); server_status->service = service; enum State service_state = DOWN; @@ -322,28 +308,43 @@ struct ServerStatus* update_server_status(struct Service** self) { pings[index] = estatus.ping = endpoint->last_ping; vector_push_back(&server_status->endpoint_statuses, &estatus); if (index == 0) service_state = endpoint->last_state; - else if ((endpoint->last_state == DOWN && service_state == UP) || (endpoint->last_state == UP && service_state == DOWN)) - service_state = PARTIAL; + else if ( + ((endpoint->last_state == DOWN || endpoint->last_state == NONE) && service_state == UP) || + (endpoint->last_state == UP && (service_state == DOWN || service_state == NONE)) + ) service_state = PARTIAL; index++; } + if (service_state == NONE) + service_state = DOWN; + size_t pings_len = index; double ping_sum = 0; - double avg_ping; - if (pings_len > 0) { - for (int i = 0; i < sizeof(pings)/sizeof(double); i++) - if (pings[i] >= 0) { - ping_sum+=pings[i]; - pings_len--; - } + double avg_ping = 0.0; + for (int i = 0; i < pings_len; i++) + if (pings[i] >= 0) + ping_sum+=pings[i]; + if (ping_sum != 0 || pings_len != 0) avg_ping = ping_sum / pings_len; - } else avg_ping = -1.0; server_status->state = service_state; server_status->ping = avg_ping; return server_status; } +void deinit_service(struct Service** self) { + struct Service* service = *self; + Iterator it = vector_begin(&service->endpoints); + Iterator end = vector_end(&service->endpoints); + for (; !iterator_equals(&it, &end); iterator_increment(&it)) { + struct Endpoint* endpoint = *(struct Endpoint**)iterator_get(&it); + endpoint->enabled = 0; + int ret = pthread_join(endpoint->thread, NULL); + if (ret != 0) + fprintf(stderr, "Thread joining encountered an error: %d\n", ret); + } +} + const char* state_text(enum State state) { switch (state) { case NONE: return "NONE"; diff --git a/src/services.h b/src/services.h index fef321d..dc1d086 100644 --- a/src/services.h +++ b/src/services.h @@ -30,6 +30,7 @@ void load_service(struct Service** self); uint8_t add_endpoint(struct Service* self, const char* uri); enum State get_state(struct Service** self); struct ServerStatus* update_server_status(struct Service** self); +void deinit_service(struct Service** self); const char* state_text(enum State state); struct StatusPeroid { @@ -71,6 +72,7 @@ struct Endpoint { struct Service { char* id; char* name; + char* icon; char* text; Vector endpoints; enum State last_state;