From c01a5c0527b7c49d4b10f5d525de060feb2b37f2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 24 Dec 2023 17:51:30 +0900 Subject: [PATCH] siphash24: introduce siphash24_compress_typesafe() macro To prevent copy-and-paste mistake. This also introduce in_addr_hash_func(). No functional change, just refactoring. --- coccinelle/siphash24.cocci | 6 ++ src/basic/ether-addr-util.c | 6 +- src/basic/hash-funcs.c | 8 +-- src/basic/in-addr-util.c | 13 +++- src/basic/in-addr-util.h | 1 + src/basic/pidref.c | 2 +- src/basic/siphash24.h | 7 +- src/basic/stat-util.c | 4 +- src/core/bpf-foreign.c | 4 +- src/core/socket.c | 6 +- src/core/timer.c | 4 +- src/libsystemd-network/lldp-neighbor.c | 8 +-- src/libsystemd-network/sd-dhcp-server.c | 2 +- src/libsystemd/sd-event/sd-event.c | 4 +- src/libsystemd/sd-id128/id128-util.c | 4 +- src/libsystemd/sd-journal/catalog.c | 2 +- src/network/netdev/vlan.c | 4 +- src/network/networkd-address-generation.c | 6 +- src/network/networkd-address.c | 12 ++-- src/network/networkd-ndisc.c | 6 +- src/network/networkd-neighbor.c | 4 +- src/network/networkd-nexthop.c | 2 +- src/network/networkd-queue.c | 8 +-- src/network/networkd-route.c | 38 +++++----- src/network/networkd-routing-policy-rule.c | 38 +++++----- src/network/tc/qdisc.c | 4 +- src/network/tc/tclass.c | 4 +- src/resolve/resolved-dns-answer.c | 2 +- src/resolve/resolved-dns-packet.c | 2 +- src/resolve/resolved-dns-rr.c | 84 +++++++++++----------- src/resolve/resolved-dns-server.c | 8 +-- src/resolve/resolved-dns-stub.c | 18 ++--- src/shared/conf-parser.c | 2 +- src/shared/in-addr-prefix-util.c | 6 +- src/shared/netif-sriov.c | 2 +- src/sleep/battery-capacity.c | 2 +- src/storagetm/storagetm.c | 6 +- src/test/test-prioq.c | 2 +- 38 files changed, 178 insertions(+), 163 deletions(-) create mode 100644 coccinelle/siphash24.cocci diff --git a/coccinelle/siphash24.cocci b/coccinelle/siphash24.cocci new file mode 100644 index 00000000000..a9afd90aa60 --- /dev/null +++ b/coccinelle/siphash24.cocci @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +@@ +expression p, s; +@@ +- siphash24_compress(&p, sizeof(p), s); ++ siphash24_compress_typesafe(p, s); diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c index 12c256a474e..4bf91f690fd 100644 --- a/src/basic/ether-addr-util.c +++ b/src/basic/ether-addr-util.c @@ -59,8 +59,8 @@ void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) { assert(p); assert(state); - siphash24_compress(&p->length, sizeof(p->length), state); - siphash24_compress(p->bytes, p->length, state); + siphash24_compress_typesafe(p->length, state); + siphash24_compress_safe(p->bytes, p->length, state); } DEFINE_HASH_OPS(hw_addr_hash_ops, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare); @@ -106,7 +106,7 @@ int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b) { } static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *state) { - siphash24_compress(p, sizeof(struct ether_addr), state); + siphash24_compress_typesafe(*p, state); } DEFINE_HASH_OPS(ether_addr_hash_ops, struct ether_addr, ether_addr_hash_func, ether_addr_compare); diff --git a/src/basic/hash-funcs.c b/src/basic/hash-funcs.c index 5fac4671857..251ee4f069d 100644 --- a/src/basic/hash-funcs.c +++ b/src/basic/hash-funcs.c @@ -33,7 +33,7 @@ void path_hash_func(const char *q, struct siphash *state) { /* if path is absolute, add one "/" to the hash. */ if (path_is_absolute(q)) - siphash24_compress("/", 1, state); + siphash24_compress_byte('/', state); for (;;) { const char *e; @@ -67,7 +67,7 @@ DEFINE_HASH_OPS_FULL(path_hash_ops_free_free, void, free); void trivial_hash_func(const void *p, struct siphash *state) { - siphash24_compress(&p, sizeof(p), state); + siphash24_compress_typesafe(p, state); } int trivial_compare_func(const void *a, const void *b) { @@ -93,7 +93,7 @@ const struct hash_ops trivial_hash_ops_free_free = { }; void uint64_hash_func(const uint64_t *p, struct siphash *state) { - siphash24_compress(p, sizeof(uint64_t), state); + siphash24_compress_typesafe(*p, state); } int uint64_compare_func(const uint64_t *a, const uint64_t *b) { @@ -104,7 +104,7 @@ DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func #if SIZEOF_DEV_T != 8 void devt_hash_func(const dev_t *p, struct siphash *state) { - siphash24_compress(p, sizeof(dev_t), state); + siphash24_compress_typesafe(*p, state); } #endif diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index ee4ea67ac63..8bd9c75d596 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -922,12 +922,19 @@ int in_addr_prefix_from_string_auto_internal( } +void in_addr_hash_func(const union in_addr_union *u, int family, struct siphash *state) { + assert(u); + assert(state); + + siphash24_compress(u->bytes, FAMILY_ADDRESS_SIZE(family), state); +} + void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state) { assert(a); assert(state); - siphash24_compress(&a->family, sizeof(a->family), state); - siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); + siphash24_compress_typesafe(a->family, state); + in_addr_hash_func(&a->address, a->family, state); } int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y) { @@ -960,7 +967,7 @@ void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) { assert(addr); assert(state); - siphash24_compress(addr, sizeof(*addr), state); + siphash24_compress_typesafe(*addr, state); } int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) { diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 12720ca92f2..9fae3cae453 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -185,6 +185,7 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) { * See also oss-fuzz#11344. */ #define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} }) +void in_addr_hash_func(const union in_addr_union *u, int family, struct siphash *state); void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state); int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y); void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state); diff --git a/src/basic/pidref.c b/src/basic/pidref.c index d3821c1f544..cf1c165b605 100644 --- a/src/basic/pidref.c +++ b/src/basic/pidref.c @@ -303,7 +303,7 @@ bool pidref_is_self(const PidRef *pidref) { } static void pidref_hash_func(const PidRef *pidref, struct siphash *state) { - siphash24_compress(&pidref->pid, sizeof(pidref->pid), state); + siphash24_compress_typesafe(pidref->pid, state); } static int pidref_compare_func(const PidRef *a, const PidRef *b) { diff --git a/src/basic/siphash24.h b/src/basic/siphash24.h index 72147a99040..2ef4a0498a8 100644 --- a/src/basic/siphash24.h +++ b/src/basic/siphash24.h @@ -22,15 +22,16 @@ struct siphash { void siphash24_init(struct siphash *state, const uint8_t k[static 16]); void siphash24_compress(const void *in, size_t inlen, struct siphash *state); #define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state)) +#define siphash24_compress_typesafe(in, state) \ + siphash24_compress(&(in), sizeof(typeof(in)), (state)) static inline void siphash24_compress_boolean(bool in, struct siphash *state) { - uint8_t i = in; - siphash24_compress(&i, sizeof i, state); + siphash24_compress_byte(in, state); } static inline void siphash24_compress_usec_t(usec_t in, struct siphash *state) { uint64_t u = htole64(in); - siphash24_compress(&u, sizeof u, state); + siphash24_compress_typesafe(u, state); } static inline void siphash24_compress_safe(const void *in, size_t inlen, struct siphash *state) { diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 1783c6eb74d..9bcd63d3e94 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -476,8 +476,8 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) { } void inode_hash_func(const struct stat *q, struct siphash *state) { - siphash24_compress(&q->st_dev, sizeof(q->st_dev), state); - siphash24_compress(&q->st_ino, sizeof(q->st_ino), state); + siphash24_compress_typesafe(q->st_dev, state); + siphash24_compress_typesafe(q->st_ino, state); } int inode_compare_func(const struct stat *a, const struct stat *b) { diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c index cff2f617fb0..909d34b5dff 100644 --- a/src/core/bpf-foreign.c +++ b/src/core/bpf-foreign.c @@ -45,8 +45,8 @@ static int bpf_foreign_key_compare_func(const BPFForeignKey *a, const BPFForeign } static void bpf_foreign_key_hash_func(const BPFForeignKey *p, struct siphash *h) { - siphash24_compress(&p->prog_id, sizeof(p->prog_id), h); - siphash24_compress(&p->attach_type, sizeof(p->attach_type), h); + siphash24_compress_typesafe(p->prog_id, h); + siphash24_compress_typesafe(p->attach_type, h); } DEFINE_PRIVATE_HASH_OPS_FULL(bpf_foreign_by_key_hash_ops, diff --git a/src/core/socket.c b/src/core/socket.c index 93faccf6ffc..e539e2ca0be 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -406,11 +406,11 @@ static void peer_address_hash_func(const SocketPeer *s, struct siphash *state) { assert(s); if (s->peer.sa.sa_family == AF_INET) - siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state); + siphash24_compress_typesafe(s->peer.in.sin_addr, state); else if (s->peer.sa.sa_family == AF_INET6) - siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state); + siphash24_compress_typesafe(s->peer.in6.sin6_addr, state); else if (s->peer.sa.sa_family == AF_VSOCK) - siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state); + siphash24_compress_typesafe(s->peer.vm.svm_cid, state); else assert_not_reached(); } diff --git a/src/core/timer.c b/src/core/timer.c index 19358c76654..771e134523b 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -192,9 +192,9 @@ static uint64_t timer_get_fixed_delay_hash(Timer *t) { } siphash24_init(&state, hash_key); - siphash24_compress(&machine_id, sizeof(sd_id128_t), &state); + siphash24_compress_typesafe(machine_id, &state); siphash24_compress_boolean(MANAGER_IS_SYSTEM(UNIT(t)->manager), &state); - siphash24_compress(&uid, sizeof(uid_t), &state); + siphash24_compress_typesafe(uid, &state); siphash24_compress_string(UNIT(t)->id, &state); return siphash24_finalize(&state); diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c index af61c9b096b..2cac77f4728 100644 --- a/src/libsystemd-network/lldp-neighbor.c +++ b/src/libsystemd-network/lldp-neighbor.c @@ -14,10 +14,10 @@ static void lldp_neighbor_id_hash_func(const LLDPNeighborID *id, struct siphash assert(id); assert(state); - siphash24_compress(id->chassis_id, id->chassis_id_size, state); - siphash24_compress(&id->chassis_id_size, sizeof(id->chassis_id_size), state); - siphash24_compress(id->port_id, id->port_id_size, state); - siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state); + siphash24_compress_safe(id->chassis_id, id->chassis_id_size, state); + siphash24_compress_typesafe(id->chassis_id_size, state); + siphash24_compress_safe(id->port_id, id->port_id_size, state); + siphash24_compress_typesafe(id->port_id_size, state); } int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y) { diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index fcc5b74364e..7eaca0bb710 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -132,7 +132,7 @@ void client_id_hash_func(const DHCPClientId *id, struct siphash *state) { assert(id->length > 0); assert(id->data); - siphash24_compress(&id->length, sizeof(id->length), state); + siphash24_compress_typesafe(id->length, state); siphash24_compress(id->data, id->length, state); } diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 288798a0dcc..214974be0c8 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -2231,8 +2231,8 @@ static int inode_data_compare(const struct inode_data *x, const struct inode_dat static void inode_data_hash_func(const struct inode_data *d, struct siphash *state) { assert(d); - siphash24_compress(&d->dev, sizeof(d->dev), state); - siphash24_compress(&d->ino, sizeof(d->ino), state); + siphash24_compress_typesafe(d->dev, state); + siphash24_compress_typesafe(d->ino, state); } DEFINE_PRIVATE_HASH_OPS(inode_data_hash_ops, struct inode_data, inode_data_hash_func, inode_data_compare); diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index dbe4d201505..69fc1bf07e5 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -191,11 +191,11 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) { } void id128_hash_func(const sd_id128_t *p, struct siphash *state) { - siphash24_compress(p, sizeof(sd_id128_t), state); + siphash24_compress_typesafe(*p, state); } int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) { - return memcmp(a, b, 16); + return memcmp(a, b, sizeof(sd_id128_t)); } sd_id128_t id128_make_v4_uuid(sd_id128_t id) { diff --git a/src/libsystemd/sd-journal/catalog.c b/src/libsystemd/sd-journal/catalog.c index 832b678bf33..cb500607720 100644 --- a/src/libsystemd/sd-journal/catalog.c +++ b/src/libsystemd/sd-journal/catalog.c @@ -55,7 +55,7 @@ typedef struct CatalogItem { } CatalogItem; static void catalog_hash_func(const CatalogItem *i, struct siphash *state) { - siphash24_compress(&i->id, sizeof(i->id), state); + siphash24_compress_typesafe(i->id, state); siphash24_compress_string(i->language, state); } diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c index 2390206993b..adbba14a6e8 100644 --- a/src/network/netdev/vlan.c +++ b/src/network/netdev/vlan.c @@ -91,8 +91,8 @@ static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlin } static void vlan_qos_maps_hash_func(const struct ifla_vlan_qos_mapping *x, struct siphash *state) { - siphash24_compress(&x->from, sizeof(x->from), state); - siphash24_compress(&x->to, sizeof(x->to), state); + siphash24_compress_typesafe(x->from, state); + siphash24_compress_typesafe(x->to, state); } static int vlan_qos_maps_compare_func(const struct ifla_vlan_qos_mapping *a, const struct ifla_vlan_qos_mapping *b) { diff --git a/src/network/networkd-address-generation.c b/src/network/networkd-address-generation.c index 65f00094780..9a5e2c21739 100644 --- a/src/network/networkd-address-generation.c +++ b/src/network/networkd-address-generation.c @@ -121,7 +121,7 @@ static void generate_stable_private_address_one( if (link->ssid) siphash24_compress_string(link->ssid, &state); - siphash24_compress(&dad_counter, sizeof(uint8_t), &state); + siphash24_compress_typesafe(dad_counter, &state); rid = htole64(siphash24_finalize(&state)); @@ -269,8 +269,8 @@ int radv_generate_addresses(Link *link, Set *tokens, const struct in6_addr *pref } static void ipv6_token_hash_func(const IPv6Token *p, struct siphash *state) { - siphash24_compress(&p->type, sizeof(p->type), state); - siphash24_compress(&p->address, sizeof(p->address), state); + siphash24_compress_typesafe(p->type, state); + siphash24_compress_typesafe(p->address, state); id128_hash_func(&p->secret_key, state); } diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index ad49793a168..bcd3ae66213 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -400,25 +400,25 @@ static int address_ipv4_prefix(const Address *a, struct in_addr *ret) { static void address_hash_func(const Address *a, struct siphash *state) { assert(a); - siphash24_compress(&a->family, sizeof(a->family), state); + siphash24_compress_typesafe(a->family, state); switch (a->family) { case AF_INET: { struct in_addr prefix; - siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); + siphash24_compress_typesafe(a->prefixlen, state); assert_se(address_ipv4_prefix(a, &prefix) >= 0); - siphash24_compress(&prefix, sizeof(prefix), state); + siphash24_compress_typesafe(prefix, state); - siphash24_compress(&a->in_addr.in, sizeof(a->in_addr.in), state); + siphash24_compress_typesafe(a->in_addr.in, state); break; } case AF_INET6: - siphash24_compress(&a->in_addr.in6, sizeof(a->in_addr.in6), state); + siphash24_compress_typesafe(a->in_addr.in6, state); if (in6_addr_is_null(&a->in_addr.in6)) - siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); + siphash24_compress_typesafe(a->prefixlen, state); break; default: diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index ab9eeb13a5d..8aa9f317117 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -635,7 +635,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { } static void ndisc_rdnss_hash_func(const NDiscRDNSS *x, struct siphash *state) { - siphash24_compress(&x->address, sizeof(x->address), state); + siphash24_compress_typesafe(x->address, state); } static int ndisc_rdnss_compare_func(const NDiscRDNSS *a, const NDiscRDNSS *b) { @@ -941,8 +941,8 @@ static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt) static void ndisc_pref64_hash_func(const NDiscPREF64 *x, struct siphash *state) { assert(x); - siphash24_compress(&x->prefix_len, sizeof(x->prefix_len), state); - siphash24_compress(&x->prefix, sizeof(x->prefix), state); + siphash24_compress_typesafe(x->prefix_len, state); + siphash24_compress_typesafe(x->prefix, state); } static int ndisc_pref64_compare_func(const NDiscPREF64 *a, const NDiscPREF64 *b) { diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index b9c7875bc4d..e172c564b00 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -90,7 +90,7 @@ static int neighbor_dup(const Neighbor *neighbor, Neighbor **ret) { static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) { assert(neighbor); - siphash24_compress(&neighbor->family, sizeof(neighbor->family), state); + siphash24_compress_typesafe(neighbor->family, state); if (!IN_SET(neighbor->family, AF_INET, AF_INET6)) /* treat any other address family as AF_UNSPEC */ @@ -98,7 +98,7 @@ static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) /* Equality of neighbors are given by the destination address. * See neigh_lookup() in the kernel. */ - siphash24_compress(&neighbor->in_addr, FAMILY_ADDRESS_SIZE(neighbor->family), state); + in_addr_hash_func(&neighbor->in_addr, neighbor->family, state); } static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index b4c101f2e85..1ab56a8ffdb 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -107,7 +107,7 @@ static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) { assert(nexthop); assert(state); - siphash24_compress(&nexthop->id, sizeof(nexthop->id), state); + siphash24_compress_typesafe(nexthop->id, state); } static int nexthop_compare_func(const NextHop *a, const NextHop *b) { diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 91e874c6fad..14cd3d93b7b 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -58,16 +58,16 @@ static void request_hash_func(const Request *req, struct siphash *state) { assert(req); assert(state); - siphash24_compress(&req->type, sizeof(req->type), state); + siphash24_compress_typesafe(req->type, state); if (req->type != REQUEST_TYPE_NEXTHOP) { siphash24_compress_boolean(req->link, state); if (req->link) - siphash24_compress(&req->link->ifindex, sizeof(req->link->ifindex), state); + siphash24_compress_typesafe(req->link->ifindex, state); } - siphash24_compress(&req->hash_func, sizeof(req->hash_func), state); - siphash24_compress(&req->compare_func, sizeof(req->compare_func), state); + siphash24_compress_typesafe(req->hash_func, state); + siphash24_compress_typesafe(req->compare_func, state); if (req->hash_func) req->hash_func(req->userdata, state); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index c0189ae899a..ac7cd434917 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -115,37 +115,37 @@ Route *route_free(Route *route) { static void route_hash_func(const Route *route, struct siphash *state) { assert(route); - siphash24_compress(&route->family, sizeof(route->family), state); + siphash24_compress_typesafe(route->family, state); switch (route->family) { case AF_INET: case AF_INET6: - siphash24_compress(&route->dst_prefixlen, sizeof(route->dst_prefixlen), state); - siphash24_compress(&route->dst, FAMILY_ADDRESS_SIZE(route->family), state); + siphash24_compress_typesafe(route->dst_prefixlen, state); + in_addr_hash_func(&route->dst, route->family, state); - siphash24_compress(&route->src_prefixlen, sizeof(route->src_prefixlen), state); - siphash24_compress(&route->src, FAMILY_ADDRESS_SIZE(route->family), state); + siphash24_compress_typesafe(route->src_prefixlen, state); + in_addr_hash_func(&route->src, route->family, state); - siphash24_compress(&route->gw_family, sizeof(route->gw_family), state); + siphash24_compress_typesafe(route->gw_family, state); if (IN_SET(route->gw_family, AF_INET, AF_INET6)) { - siphash24_compress(&route->gw, FAMILY_ADDRESS_SIZE(route->gw_family), state); - siphash24_compress(&route->gw_weight, sizeof(route->gw_weight), state); + in_addr_hash_func(&route->gw, route->gw_family, state); + siphash24_compress_typesafe(route->gw_weight, state); } - siphash24_compress(&route->prefsrc, FAMILY_ADDRESS_SIZE(route->family), state); + in_addr_hash_func(&route->prefsrc, route->family, state); - siphash24_compress(&route->tos, sizeof(route->tos), state); - siphash24_compress(&route->priority, sizeof(route->priority), state); - siphash24_compress(&route->table, sizeof(route->table), state); - siphash24_compress(&route->protocol, sizeof(route->protocol), state); - siphash24_compress(&route->scope, sizeof(route->scope), state); - siphash24_compress(&route->type, sizeof(route->type), state); + siphash24_compress_typesafe(route->tos, state); + siphash24_compress_typesafe(route->priority, state); + siphash24_compress_typesafe(route->table, state); + siphash24_compress_typesafe(route->protocol, state); + siphash24_compress_typesafe(route->scope, state); + siphash24_compress_typesafe(route->type, state); - siphash24_compress(&route->initcwnd, sizeof(route->initcwnd), state); - siphash24_compress(&route->initrwnd, sizeof(route->initrwnd), state); + siphash24_compress_typesafe(route->initcwnd, state); + siphash24_compress_typesafe(route->initrwnd, state); - siphash24_compress(&route->advmss, sizeof(route->advmss), state); - siphash24_compress(&route->nexthop_id, sizeof(route->nexthop_id), state); + siphash24_compress_typesafe(route->advmss, state); + siphash24_compress_typesafe(route->nexthop_id, state); break; default: diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 0cb5831ea3a..6324b044983 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -156,33 +156,33 @@ static int routing_policy_rule_dup(const RoutingPolicyRule *src, RoutingPolicyRu static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) { assert(rule); - siphash24_compress(&rule->family, sizeof(rule->family), state); + siphash24_compress_typesafe(rule->family, state); switch (rule->family) { case AF_INET: case AF_INET6: - siphash24_compress(&rule->from, FAMILY_ADDRESS_SIZE(rule->family), state); - siphash24_compress(&rule->from_prefixlen, sizeof(rule->from_prefixlen), state); + in_addr_hash_func(&rule->from, rule->family, state); + siphash24_compress_typesafe(rule->from_prefixlen, state); - siphash24_compress(&rule->to, FAMILY_ADDRESS_SIZE(rule->family), state); - siphash24_compress(&rule->to_prefixlen, sizeof(rule->to_prefixlen), state); + in_addr_hash_func(&rule->to, rule->family, state); + siphash24_compress_typesafe(rule->to_prefixlen, state); siphash24_compress_boolean(rule->invert_rule, state); - siphash24_compress(&rule->tos, sizeof(rule->tos), state); - siphash24_compress(&rule->type, sizeof(rule->type), state); - siphash24_compress(&rule->fwmark, sizeof(rule->fwmark), state); - siphash24_compress(&rule->fwmask, sizeof(rule->fwmask), state); - siphash24_compress(&rule->priority, sizeof(rule->priority), state); - siphash24_compress(&rule->table, sizeof(rule->table), state); - siphash24_compress(&rule->suppress_prefixlen, sizeof(rule->suppress_prefixlen), state); - siphash24_compress(&rule->suppress_ifgroup, sizeof(rule->suppress_ifgroup), state); - - siphash24_compress(&rule->ipproto, sizeof(rule->ipproto), state); - siphash24_compress(&rule->protocol, sizeof(rule->protocol), state); - siphash24_compress(&rule->sport, sizeof(rule->sport), state); - siphash24_compress(&rule->dport, sizeof(rule->dport), state); - siphash24_compress(&rule->uid_range, sizeof(rule->uid_range), state); + siphash24_compress_typesafe(rule->tos, state); + siphash24_compress_typesafe(rule->type, state); + siphash24_compress_typesafe(rule->fwmark, state); + siphash24_compress_typesafe(rule->fwmask, state); + siphash24_compress_typesafe(rule->priority, state); + siphash24_compress_typesafe(rule->table, state); + siphash24_compress_typesafe(rule->suppress_prefixlen, state); + siphash24_compress_typesafe(rule->suppress_ifgroup, state); + + siphash24_compress_typesafe(rule->ipproto, state); + siphash24_compress_typesafe(rule->protocol, state); + siphash24_compress_typesafe(rule->sport, state); + siphash24_compress_typesafe(rule->dport, state); + siphash24_compress_typesafe(rule->uid_range, state); siphash24_compress_string(rule->iif, state); siphash24_compress_string(rule->oif, state); diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index f20f410497b..75bcbbf01d9 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -155,8 +155,8 @@ static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) { assert(qdisc); assert(state); - siphash24_compress(&qdisc->handle, sizeof(qdisc->handle), state); - siphash24_compress(&qdisc->parent, sizeof(qdisc->parent), state); + siphash24_compress_typesafe(qdisc->handle, state); + siphash24_compress_typesafe(qdisc->parent, state); siphash24_compress_string(qdisc_get_tca_kind(qdisc), state); } diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c index 0a5fec02343..ab8f79ac5bf 100644 --- a/src/network/tc/tclass.c +++ b/src/network/tc/tclass.c @@ -125,8 +125,8 @@ static void tclass_hash_func(const TClass *tclass, struct siphash *state) { assert(tclass); assert(state); - siphash24_compress(&tclass->classid, sizeof(tclass->classid), state); - siphash24_compress(&tclass->parent, sizeof(tclass->parent), state); + siphash24_compress_typesafe(tclass->classid, state); + siphash24_compress_typesafe(tclass->parent, state); siphash24_compress_string(tclass_get_tca_kind(tclass), state); } diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index bf023a77e44..254f8362d3a 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -26,7 +26,7 @@ static void dns_answer_item_hash_func(const DnsAnswerItem *a, struct siphash *st assert(a); assert(state); - siphash24_compress(&a->ifindex, sizeof(a->ifindex), state); + siphash24_compress_typesafe(a->ifindex, state); dns_resource_record_hash_func(a->rr, state); } diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 991a1be4584..c1c88550d5b 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -2550,7 +2550,7 @@ int dns_packet_patch_ttls(DnsPacket *p, usec_t timestamp) { static void dns_packet_hash_func(const DnsPacket *s, struct siphash *state) { assert(s); - siphash24_compress(&s->size, sizeof(s->size), state); + siphash24_compress_typesafe(s->size, state); siphash24_compress(DNS_PACKET_DATA((DnsPacket*) s), s->size, state); } diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 00f7beacc8f..2bdcc7c1dcd 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -293,8 +293,8 @@ static void dns_resource_key_hash_func(const DnsResourceKey *k, struct siphash * assert(k); dns_name_hash_func(dns_resource_key_name(k), state); - siphash24_compress(&k->class, sizeof(k->class), state); - siphash24_compress(&k->type, sizeof(k->type), state); + siphash24_compress_typesafe(k->class, state); + siphash24_compress_typesafe(k->type, state); } static int dns_resource_key_compare_func(const DnsResourceKey *x, const DnsResourceKey *y) { @@ -1327,9 +1327,9 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash * switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) { case DNS_TYPE_SRV: - siphash24_compress(&rr->srv.priority, sizeof(rr->srv.priority), state); - siphash24_compress(&rr->srv.weight, sizeof(rr->srv.weight), state); - siphash24_compress(&rr->srv.port, sizeof(rr->srv.port), state); + siphash24_compress_typesafe(rr->srv.priority, state); + siphash24_compress_typesafe(rr->srv.weight, state); + siphash24_compress_typesafe(rr->srv.port, state); dns_name_hash_func(rr->srv.name, state); break; @@ -1358,59 +1358,59 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash * } case DNS_TYPE_A: - siphash24_compress(&rr->a.in_addr, sizeof(rr->a.in_addr), state); + siphash24_compress_typesafe(rr->a.in_addr, state); break; case DNS_TYPE_AAAA: - siphash24_compress(&rr->aaaa.in6_addr, sizeof(rr->aaaa.in6_addr), state); + siphash24_compress_typesafe(rr->aaaa.in6_addr, state); break; case DNS_TYPE_SOA: dns_name_hash_func(rr->soa.mname, state); dns_name_hash_func(rr->soa.rname, state); - siphash24_compress(&rr->soa.serial, sizeof(rr->soa.serial), state); - siphash24_compress(&rr->soa.refresh, sizeof(rr->soa.refresh), state); - siphash24_compress(&rr->soa.retry, sizeof(rr->soa.retry), state); - siphash24_compress(&rr->soa.expire, sizeof(rr->soa.expire), state); - siphash24_compress(&rr->soa.minimum, sizeof(rr->soa.minimum), state); + siphash24_compress_typesafe(rr->soa.serial, state); + siphash24_compress_typesafe(rr->soa.refresh, state); + siphash24_compress_typesafe(rr->soa.retry, state); + siphash24_compress_typesafe(rr->soa.expire, state); + siphash24_compress_typesafe(rr->soa.minimum, state); break; case DNS_TYPE_MX: - siphash24_compress(&rr->mx.priority, sizeof(rr->mx.priority), state); + siphash24_compress_typesafe(rr->mx.priority, state); dns_name_hash_func(rr->mx.exchange, state); break; case DNS_TYPE_LOC: - siphash24_compress(&rr->loc.version, sizeof(rr->loc.version), state); - siphash24_compress(&rr->loc.size, sizeof(rr->loc.size), state); - siphash24_compress(&rr->loc.horiz_pre, sizeof(rr->loc.horiz_pre), state); - siphash24_compress(&rr->loc.vert_pre, sizeof(rr->loc.vert_pre), state); - siphash24_compress(&rr->loc.latitude, sizeof(rr->loc.latitude), state); - siphash24_compress(&rr->loc.longitude, sizeof(rr->loc.longitude), state); - siphash24_compress(&rr->loc.altitude, sizeof(rr->loc.altitude), state); + siphash24_compress_typesafe(rr->loc.version, state); + siphash24_compress_typesafe(rr->loc.size, state); + siphash24_compress_typesafe(rr->loc.horiz_pre, state); + siphash24_compress_typesafe(rr->loc.vert_pre, state); + siphash24_compress_typesafe(rr->loc.latitude, state); + siphash24_compress_typesafe(rr->loc.longitude, state); + siphash24_compress_typesafe(rr->loc.altitude, state); break; case DNS_TYPE_SSHFP: - siphash24_compress(&rr->sshfp.algorithm, sizeof(rr->sshfp.algorithm), state); - siphash24_compress(&rr->sshfp.fptype, sizeof(rr->sshfp.fptype), state); + siphash24_compress_typesafe(rr->sshfp.algorithm, state); + siphash24_compress_typesafe(rr->sshfp.fptype, state); siphash24_compress_safe(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, state); break; case DNS_TYPE_DNSKEY: - siphash24_compress(&rr->dnskey.flags, sizeof(rr->dnskey.flags), state); - siphash24_compress(&rr->dnskey.protocol, sizeof(rr->dnskey.protocol), state); - siphash24_compress(&rr->dnskey.algorithm, sizeof(rr->dnskey.algorithm), state); + siphash24_compress_typesafe(rr->dnskey.flags, state); + siphash24_compress_typesafe(rr->dnskey.protocol, state); + siphash24_compress_typesafe(rr->dnskey.algorithm, state); siphash24_compress_safe(rr->dnskey.key, rr->dnskey.key_size, state); break; case DNS_TYPE_RRSIG: - siphash24_compress(&rr->rrsig.type_covered, sizeof(rr->rrsig.type_covered), state); - siphash24_compress(&rr->rrsig.algorithm, sizeof(rr->rrsig.algorithm), state); - siphash24_compress(&rr->rrsig.labels, sizeof(rr->rrsig.labels), state); - siphash24_compress(&rr->rrsig.original_ttl, sizeof(rr->rrsig.original_ttl), state); - siphash24_compress(&rr->rrsig.expiration, sizeof(rr->rrsig.expiration), state); - siphash24_compress(&rr->rrsig.inception, sizeof(rr->rrsig.inception), state); - siphash24_compress(&rr->rrsig.key_tag, sizeof(rr->rrsig.key_tag), state); + siphash24_compress_typesafe(rr->rrsig.type_covered, state); + siphash24_compress_typesafe(rr->rrsig.algorithm, state); + siphash24_compress_typesafe(rr->rrsig.labels, state); + siphash24_compress_typesafe(rr->rrsig.original_ttl, state); + siphash24_compress_typesafe(rr->rrsig.expiration, state); + siphash24_compress_typesafe(rr->rrsig.inception, state); + siphash24_compress_typesafe(rr->rrsig.key_tag, state); dns_name_hash_func(rr->rrsig.signer, state); siphash24_compress_safe(rr->rrsig.signature, rr->rrsig.signature_size, state); break; @@ -1423,30 +1423,30 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash * break; case DNS_TYPE_DS: - siphash24_compress(&rr->ds.key_tag, sizeof(rr->ds.key_tag), state); - siphash24_compress(&rr->ds.algorithm, sizeof(rr->ds.algorithm), state); - siphash24_compress(&rr->ds.digest_type, sizeof(rr->ds.digest_type), state); + siphash24_compress_typesafe(rr->ds.key_tag, state); + siphash24_compress_typesafe(rr->ds.algorithm, state); + siphash24_compress_typesafe(rr->ds.digest_type, state); siphash24_compress_safe(rr->ds.digest, rr->ds.digest_size, state); break; case DNS_TYPE_NSEC3: - siphash24_compress(&rr->nsec3.algorithm, sizeof(rr->nsec3.algorithm), state); - siphash24_compress(&rr->nsec3.flags, sizeof(rr->nsec3.flags), state); - siphash24_compress(&rr->nsec3.iterations, sizeof(rr->nsec3.iterations), state); + siphash24_compress_typesafe(rr->nsec3.algorithm, state); + siphash24_compress_typesafe(rr->nsec3.flags, state); + siphash24_compress_typesafe(rr->nsec3.iterations, state); siphash24_compress_safe(rr->nsec3.salt, rr->nsec3.salt_size, state); siphash24_compress_safe(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, state); /* FIXME: We leave the bitmaps out */ break; case DNS_TYPE_TLSA: - siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state); - siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state); - siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state); + siphash24_compress_typesafe(rr->tlsa.cert_usage, state); + siphash24_compress_typesafe(rr->tlsa.selector, state); + siphash24_compress_typesafe(rr->tlsa.matching_type, state); siphash24_compress_safe(rr->tlsa.data, rr->tlsa.data_size, state); break; case DNS_TYPE_CAA: - siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state); + siphash24_compress_typesafe(rr->caa.flags, state); string_hash_func(rr->caa.tag, state); siphash24_compress_safe(rr->caa.value, rr->caa.value_size, state); break; diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index b7db83965b2..957e6618b44 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -751,10 +751,10 @@ size_t dns_server_get_mtu(DnsServer *s) { static void dns_server_hash_func(const DnsServer *s, struct siphash *state) { assert(s); - siphash24_compress(&s->family, sizeof(s->family), state); - siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state); - siphash24_compress(&s->port, sizeof(s->port), state); - siphash24_compress(&s->ifindex, sizeof(s->ifindex), state); + siphash24_compress_typesafe(s->family, state); + in_addr_hash_func(&s->address, s->family, state); + siphash24_compress_typesafe(s->port, state); + siphash24_compress_typesafe(s->ifindex, state); siphash24_compress_string(s->server_name, state); } diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index f43e1f8b617..2a3c1edbba7 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -27,10 +27,10 @@ static int manager_dns_stub_fd(Manager *m, int family, const union in_addr_union static void dns_stub_listener_extra_hash_func(const DnsStubListenerExtra *a, struct siphash *state) { assert(a); - siphash24_compress(&a->mode, sizeof(a->mode), state); - siphash24_compress(&a->family, sizeof(a->family), state); - siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); - siphash24_compress(&a->port, sizeof(a->port), state); + siphash24_compress_typesafe(a->mode, state); + siphash24_compress_typesafe(a->family, state); + in_addr_hash_func(&a->address, a->family, state); + siphash24_compress_typesafe(a->port, state); } static int dns_stub_listener_extra_compare_func(const DnsStubListenerExtra *a, const DnsStubListenerExtra *b) { @@ -94,11 +94,11 @@ DnsStubListenerExtra *dns_stub_listener_extra_free(DnsStubListenerExtra *p) { static void stub_packet_hash_func(const DnsPacket *p, struct siphash *state) { assert(p); - siphash24_compress(&p->protocol, sizeof(p->protocol), state); - siphash24_compress(&p->family, sizeof(p->family), state); - siphash24_compress(&p->sender, sizeof(p->sender), state); - siphash24_compress(&p->ipproto, sizeof(p->ipproto), state); - siphash24_compress(&p->sender_port, sizeof(p->sender_port), state); + siphash24_compress_typesafe(p->protocol, state); + siphash24_compress_typesafe(p->family, state); + siphash24_compress_typesafe(p->sender, state); + siphash24_compress_typesafe(p->ipproto, state); + siphash24_compress_typesafe(p->sender_port, state); siphash24_compress(DNS_PACKET_HEADER(p), sizeof(DnsPacketHeader), state); /* We don't bother hashing the full packet here, just the header */ diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 59a529d4bcb..5d4500cb05b 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -797,7 +797,7 @@ bool stats_by_path_equal(Hashmap *a, Hashmap *b) { static void config_section_hash_func(const ConfigSection *c, struct siphash *state) { siphash24_compress_string(c->filename, state); - siphash24_compress(&c->line, sizeof(c->line), state); + siphash24_compress_typesafe(c->line, state); } static int config_section_compare_func(const ConfigSection *x, const ConfigSection *y) { diff --git a/src/shared/in-addr-prefix-util.c b/src/shared/in-addr-prefix-util.c index 7c0033d7f9b..edccca5a5b9 100644 --- a/src/shared/in-addr-prefix-util.c +++ b/src/shared/in-addr-prefix-util.c @@ -59,9 +59,9 @@ static void in_addr_prefix_hash_func(const struct in_addr_prefix *a, struct siph assert(a); assert(state); - siphash24_compress(&a->family, sizeof(a->family), state); - siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); - siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); + siphash24_compress_typesafe(a->family, state); + siphash24_compress_typesafe(a->prefixlen, state); + in_addr_hash_func(&a->address, a->family, state); } static int in_addr_prefix_compare_func(const struct in_addr_prefix *x, const struct in_addr_prefix *y) { diff --git a/src/shared/netif-sriov.c b/src/shared/netif-sriov.c index 7559b0d00ce..20e175edcd3 100644 --- a/src/shared/netif-sriov.c +++ b/src/shared/netif-sriov.c @@ -84,7 +84,7 @@ void sr_iov_hash_func(const SRIOV *sr_iov, struct siphash *state) { assert(sr_iov); assert(state); - siphash24_compress(&sr_iov->vf, sizeof(sr_iov->vf), state); + siphash24_compress_typesafe(sr_iov->vf, state); } int sr_iov_compare_func(const SRIOV *s1, const SRIOV *s2) { diff --git a/src/sleep/battery-capacity.c b/src/sleep/battery-capacity.c index 62a0746bac6..7627a97b28a 100644 --- a/src/sleep/battery-capacity.c +++ b/src/sleep/battery-capacity.c @@ -68,7 +68,7 @@ static int siphash24_compress_id128( if (r < 0) return log_debug_errno(r, "Failed to get %s ID: %m", name); - siphash24_compress(&id, sizeof(sd_id128_t), state); + siphash24_compress_typesafe(id, state); return 0; } diff --git a/src/storagetm/storagetm.c b/src/storagetm/storagetm.c index a482daabefb..b28924a8b45 100644 --- a/src/storagetm/storagetm.c +++ b/src/storagetm/storagetm.c @@ -587,7 +587,7 @@ static uint16_t calculate_start_port(const char *name, int ip_family) { /* Use some fixed key Lennart pulled from /dev/urandom, so that we are deterministic */ siphash24_init(&state, SD_ID128_MAKE(d1,0b,67,b5,e2,b7,4a,91,8d,6b,27,b6,35,c1,9f,d9).bytes); siphash24_compress_string(name, &state); - siphash24_compress(&ip_family, sizeof(ip_family), &state); + siphash24_compress_typesafe(ip_family, &state); nr = 1024U + siphash24_finalize(&state) % (0xFFFFU - 1024U); SET_FLAG(nr, 1, ip_family == AF_INET6); /* Lowest bit reflects family */ @@ -790,8 +790,8 @@ static void device_hash_func(const struct stat *q, struct siphash *state) { if (S_ISBLK(q->st_mode) || S_ISCHR(q->st_mode)) { mode_t m = q->st_mode & S_IFMT; - siphash24_compress(&m, sizeof(m), state); - siphash24_compress(&q->st_rdev, sizeof(q->st_rdev), state); + siphash24_compress_typesafe(m, state); + siphash24_compress_typesafe(q->st_rdev, state); return; } diff --git a/src/test/test-prioq.c b/src/test/test-prioq.c index 540863c2ff5..d1b1ce9170a 100644 --- a/src/test/test-prioq.c +++ b/src/test/test-prioq.c @@ -54,7 +54,7 @@ static int test_compare(const struct test *x, const struct test *y) { } static void test_hash(const struct test *x, struct siphash *state) { - siphash24_compress(&x->value, sizeof(x->value), state); + siphash24_compress_typesafe(x->value, state); } DEFINE_PRIVATE_HASH_OPS(test_hash_ops, struct test, test_hash, test_compare); -- 2.47.3