]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Remove clients on communication errors
authorpcarana <pc.moreno2099@gmail.com>
Fri, 29 Mar 2019 19:51:06 +0000 (13:51 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Fri, 29 Mar 2019 19:51:06 +0000 (13:51 -0600)
src/clients.c
src/clients.h
src/rtr/rtr.c

index 7c957dd63951da01ed224b383fce0083ea47207d..45c9144c49860b6bc6a8650f6fc45a809e2ec8ca 100644 (file)
@@ -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)
 {
index 976343e6d1e7ddaf3c42d23a6a854491d0dc014f..b80be4c38618c47753fe0fe5dbac14d099d4f579 100644 (file)
@@ -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_ */
index 85b5cdd49d301f9252803a17d52139271f2e8447..2189f27abb2fc4d1036d70c3381572b3dd82e5aa 100644 (file)
@@ -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, &param.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. */