From: pcarana Date: Fri, 29 Mar 2019 19:51:06 +0000 (-0600) Subject: Remove clients on communication errors X-Git-Tag: v0.0.2~52^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=33b73d4bea5301b04d6f94e47b21da3d06446d73;p=thirdparty%2FFORT-validator.git Remove clients on communication errors --- diff --git a/src/clients.c b/src/clients.c index 7c957dd6..45c9144c 100644 --- a/src/clients.c +++ b/src/clients.c @@ -134,6 +134,30 @@ client_destroy(struct client *client) /* Didn't allocate something, so do nothing */ } +void +clients_forget(int fd) +{ + struct clientsdb *new_db; + struct client *ptr; + + new_db = malloc(sizeof(struct clientsdb)); + if (new_db == NULL) { + warnx("Couldn't allocate new clients DB"); + return; + } + clientsdb_init(new_db); + read_lock(&rlock, &wlock, &rcounter); + ARRAYLIST_FOREACH(&clients_db, ptr) + if (ptr->fd != fd) + clientsdb_add(new_db, ptr); + read_unlock(&rlock, &wlock, &rcounter); + + sem_wait(&wlock); + clients_db = *new_db; + sem_post(&wlock); + free(new_db); +} + void clients_db_destroy(void) { diff --git a/src/clients.h b/src/clients.h index 976343e6..b80be4c3 100644 --- a/src/clients.h +++ b/src/clients.h @@ -15,9 +15,10 @@ struct client { }; int clients_db_init(void); -int update_client(int fd, struct sockaddr_storage *, u_int8_t); +int update_client(int, struct sockaddr_storage *, u_int8_t); size_t client_list(struct client **); +void clients_forget(int); void clients_db_destroy(void); #endif /* SRC_CLIENTS_H_ */ diff --git a/src/rtr/rtr.c b/src/rtr/rtr.c index 85b5cdd4..2189f27a 100644 --- a/src/rtr/rtr.c +++ b/src/rtr/rtr.c @@ -117,6 +117,15 @@ handle_accept_result(int client_fd, int err) return VERDICT_EXIT; } +static void * +end_client(int client_fd, const struct pdu_metadata *meta, void *pdu) +{ + if (meta != NULL && pdu != NULL) + meta->destructor(pdu); + clients_forget(client_fd); + return NULL; +} + /* * The client socket threads' entry routine. * @@ -137,15 +146,14 @@ client_thread_cb(void *param_void) while (loop) { /* For each PDU... */ err = pdu_load(param.client_fd, &pdu, &meta, &rtr_version); if (err) - return NULL; + return end_client(param.client_fd, NULL, NULL); /* Protocol Version Negotiation */ if (rtr_version != RTR_VERSION_SUPPORTED) { err_pdu_send(param.client_fd, RTR_VERSION_SUPPORTED, ERR_PDU_UNSUP_PROTO_VERSION, (struct pdu_header *) pdu, NULL); - meta->destructor(pdu); - return NULL; + return end_client(param.client_fd, meta, pdu); } /* RTR Version ready, now update client */ err = update_client(param.client_fd, ¶m.client_addr, @@ -158,14 +166,13 @@ client_thread_cb(void *param_void) : ERR_PDU_UNEXPECTED_PROTO_VERSION), (struct pdu_header *) pdu, NULL); } - meta->destructor(pdu); - return NULL; + return end_client(param.client_fd, meta, pdu); } err = meta->handle(param.client_fd, pdu); meta->destructor(pdu); if (err) - return NULL; + return end_client(param.client_fd, NULL, NULL); } return NULL; /* Unreachable. */