void remove_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len) { struct sockaddr_map_entry *pos; struct sockaddr_map_entry *entry; unsigned int hash = hash_name((char *) sa, sa_len); entry = sockaddr_to_sockaddr_map_entry(sa, sa_len); if (!entry) return; rwlock_wr_lock(&sockaddr_map_lock); pos = remove_hash(hash, entry, entry->next, &sockaddr_mapper); while (pos && pos->next && pos->next != entry) pos = pos->next; if (pos && pos->next && pos->next == entry) pos->next = entry->next; memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce)); memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce)); entry->proto = NULL; entry->next = NULL; xfree(entry->sa); xfree(entry); rwlock_unlock(&sockaddr_map_lock); }
static int register_user_by_sockaddr(struct sockaddr_storage *sa, size_t sa_len, struct curve25519_proto *proto) { void **pos; struct sockaddr_map_entry *entry; unsigned int hash = hash_name((char *) sa, sa_len); rwlock_wr_lock(&sockaddr_map_lock); entry = xzmalloc(sizeof(*entry)); entry->sa = xmemdupz(sa, sa_len); entry->sa_len = sa_len; entry->proto = proto; pos = insert_hash(hash, entry, &sockaddr_mapper); if (pos) { entry->next = (*pos); (*pos) = entry; } rwlock_unlock(&sockaddr_map_lock); return 0; }
void trie_cleanup(void) { rwlock_wr_lock(&tree_lock); ptree_free(tree); rwlock_unlock(&tree_lock); rwlock_destroy(&tree_lock); }
void remove_user_by_socket(int fd) { struct sock_map_entry *pos; struct sock_map_entry *entry = socket_to_sock_map_entry(fd); if (!entry) return; rwlock_wr_lock(&sock_map_lock); pos = remove_hash(entry->fd, entry, entry->next, &sock_mapper); while (pos && pos->next && pos->next != entry) pos = pos->next; if (pos && pos->next && pos->next == entry) pos->next = entry->next; memset(entry->proto->enonce, 0, sizeof(entry->proto->enonce)); memset(entry->proto->dnonce, 0, sizeof(entry->proto->dnonce)); entry->proto = NULL; entry->next = NULL; xfree(entry); rwlock_unlock(&sock_map_lock); }
void parse_userfile_and_generate_user_store_or_die(char *homedir) { FILE *fp; char path[PATH_MAX], buff[512]; int line = 1, ret, fd; memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", homedir, FILE_CLIENTS); rwlock_init(&store_lock); rwlock_wr_lock(&store_lock); fp = fopen(path, "r"); if (!fp) panic("Cannot open client file!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; /* A comment. Skip this line */ if (buff[0] == '#' || buff[0] == '\n') { memset(buff, 0, sizeof(buff)); line++; continue; } ret = parse_line(buff, homedir); if (ret < 0) panic("Cannot parse line %d from clients!\n", line); line++; memset(buff, 0, sizeof(buff)); } fclose(fp); if (store == NULL) panic("No registered clients found!\n"); rwlock_unlock(&store_lock); init_sock_mapper(); init_sockaddr_mapper(); /* * Pubkey is also used as a hmac of the initial packet to check * the integrity of the packet, so that we know if it's just random * garbage or a 'valid' packet. Again, just for the integrity! */ memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", homedir, FILE_PUBKEY); fd = open_or_die(path, O_RDONLY); ret = read(fd, token, sizeof(token)); if (ret != crypto_auth_hmacsha512256_KEYBYTES) panic("Cannot read public key!\n"); close(fd); }
static void destroy_sockaddr_mapper(void) { rwlock_wr_lock(&sockaddr_map_lock); for_each_hash(&sockaddr_mapper, cleanup_batch_sockaddr_mapper); free_hash(&sockaddr_mapper); rwlock_unlock(&sockaddr_map_lock); rwlock_destroy(&sockaddr_map_lock); }
static void init_sockaddr_mapper(void) { rwlock_init(&sockaddr_map_lock); rwlock_wr_lock(&sockaddr_map_lock); memset(&sockaddr_mapper, 0, sizeof(sockaddr_mapper)); init_hash(&sockaddr_mapper); rwlock_unlock(&sockaddr_map_lock); }
void destroy_cpusched(void) { rwlock_wr_lock(&map_lock); xfree(cpu_assigned); cpu_len = 0; for_each_hash(&mapper, cleanup_batch); free_hash(&mapper); rwlock_unlock(&map_lock); rwlock_destroy(&map_lock); }
void init_cpusched(unsigned int cpus) { rwlock_init(&map_lock); rwlock_wr_lock(&map_lock); cpu_len = cpus; cpu_assigned = xzmalloc(cpus * sizeof(*cpu_assigned)); memset(&mapper, 0, sizeof(mapper)); init_hash(&mapper); rwlock_unlock(&map_lock); }
void destroy_serv_store(void) { struct server_store *elem, *nelem = NULL; rwlock_wr_lock(&store_lock); selected = NULL; elem = store; while (elem) { nelem = elem->next; elem->next = NULL; server_store_free(elem); elem = nelem; } rwlock_unlock(&store_lock); rwlock_destroy(&store_lock); }
void trie_addr_remove_addr(struct sockaddr_storage *addr, size_t alen) { int found = 1; struct patricia_node *n = NULL; rwlock_wr_lock(&tree_lock); while (found) { ptree_get_key_addr(addr, alen, tree, &n); if (n) { ptree_del_entry(n->key, n->klen, &tree); n = NULL; } else found = 0; } rwlock_unlock(&tree_lock); }
void trie_addr_remove(int fd) { int found = 1; struct patricia_node *n = NULL; rwlock_wr_lock(&tree_lock); while (found) { ptree_get_key(fd, tree, &n); if (n) { ptree_del_entry(n->key, n->klen, &tree); n = NULL; } else found = 0; } rwlock_unlock(&tree_lock); }
void destroy_user_store(void) { struct user_store *elem, *nelem = NULL; rwlock_wr_lock(&store_lock); elem = store; while (elem) { nelem = elem->next; elem->next = NULL; user_store_free(elem); elem = nelem; } rwlock_unlock(&store_lock); rwlock_destroy(&store_lock); destroy_sock_mapper(); destroy_sockaddr_mapper(); }
static int register_user_by_socket(int fd, struct curve25519_proto *proto) { void **pos; struct sock_map_entry *entry; rwlock_wr_lock(&sock_map_lock); entry = xzmalloc(sizeof(*entry)); entry->fd = fd; entry->proto = proto; pos = insert_hash(entry->fd, entry, &sock_mapper); if (pos) { entry->next = (*pos); (*pos) = entry; } rwlock_unlock(&sock_map_lock); return 0; }
void parse_userfile_and_generate_serv_store_or_die(char *homedir) { FILE *fp; char path[PATH_MAX], buff[1024]; int line = 1, ret; memset(path, 0, sizeof(path)); slprintf(path, sizeof(path), "%s/%s", homedir, FILE_SERVERS); rwlock_init(&store_lock); rwlock_wr_lock(&store_lock); fp = fopen(path, "r"); if (!fp) panic("Cannot open server file!\n"); memset(buff, 0, sizeof(buff)); while (fgets(buff, sizeof(buff), fp) != NULL) { buff[sizeof(buff) - 1] = 0; /* A comment. Skip this line */ if (buff[0] == '#' || buff[0] == '\n') { memset(buff, 0, sizeof(buff)); line++; continue; } ret = parse_line(buff, homedir); if (ret < 0) panic("Cannot parse line %d from clients!\n", line); line++; memset(buff, 0, sizeof(buff)); } fclose(fp); if (store == NULL) panic("No registered servers found!\n"); rwlock_unlock(&store_lock); }
int trie_addr_maybe_update(char *buff, size_t len, int ipv4, int fd, struct sockaddr_storage *addr, size_t alen) { int ret; void *data; size_t dlen; struct ipv4hdr *hdr4 = (void *) buff; struct ipv6hdr *hdr6 = (void *) buff; data = ipv4 ? (void *) &hdr4->h_saddr : (void *) &hdr6->saddr; dlen = ipv4 ? sizeof(hdr4->h_saddr) : sizeof(hdr6->saddr); if (unlikely((ipv4 && ((struct ipv4hdr *) buff)->h_version != 4) || (!ipv4 && ((struct ipv6hdr *) buff)->version != 6))) return -1; rwlock_wr_lock(&tree_lock); ret = ptree_add_entry(data, dlen, fd, addr, alen, &tree); rwlock_unlock(&tree_lock); return ret; }
void unregister_socket(int fd) { struct map_entry *pos; struct map_entry *entry = socket_to_map_entry(fd); if (!entry == 0 && errno == ENOENT) return; rwlock_wr_lock(&map_lock); cpu_assigned[entry->cpu]--; pos = remove_hash(entry->fd, entry, entry->next, &mapper); while (pos && pos->next && pos->next != entry) pos = pos->next; if (pos && pos->next && pos->next == entry) pos->next = entry->next; entry->next = NULL; xfree(entry); rwlock_unlock(&map_lock); }
unsigned int register_socket(int fd) { void **pos; struct map_entry *entry; rwlock_wr_lock(&map_lock); entry = xzmalloc(sizeof(*entry)); entry->fd = fd; entry->cpu = get_appropriate_cpu(); cpu_assigned[entry->cpu]++; pos = insert_hash(entry->fd, entry, &mapper); if (pos) { entry->next = (*pos); (*pos) = entry; } rwlock_unlock(&map_lock); return entry->cpu; }