pex-msg: fix memory leak on fread fail in pex_msg_update_request_init
[project/unetd.git] / host.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #ifndef __UNETD_HOST_H
6 #define __UNETD_HOST_H
7
8 enum peer_endpoint_type {
9 ENDPOINT_TYPE_STATIC,
10 ENDPOINT_TYPE_PEX,
11 ENDPOINT_TYPE_ENDPOINT_NOTIFY,
12 ENDPOINT_TYPE_ENDPOINT_PORT_NOTIFY,
13 __ENDPOINT_TYPE_MAX,
14 };
15
16 struct network_peer {
17 struct vlist_node node;
18 uint8_t key[CURVE25519_KEY_SIZE];
19 union network_addr local_addr;
20 const char *endpoint;
21 struct blob_attr *ipaddr;
22 struct blob_attr *subnet;
23 int port;
24 int pex_port;
25 bool dynamic;
26
27 struct {
28 int connect_attempt;
29 bool connected;
30 bool handshake;
31 bool has_local_ep_addr;
32 bool pinged;
33 union network_addr local_ep_addr;
34 union network_endpoint endpoint;
35
36 uint8_t next_endpoint_idx;
37 union network_endpoint next_endpoint[__ENDPOINT_TYPE_MAX];
38 uint64_t last_ep_update;
39
40 uint64_t rx_bytes;
41 uint64_t last_handshake;
42 uint64_t last_request;
43 uint64_t last_query_sent;
44
45 int idle;
46 int num_net_queries;
47 } state;
48 };
49
50 struct network_dynamic_peer {
51 struct list_head list;
52
53 struct network_peer peer;
54 };
55
56 struct network_host {
57 struct avl_node node;
58
59 const char *gateway;
60 struct network_peer peer;
61 };
62
63 struct network_group {
64 struct avl_node node;
65 const char *name;
66
67 int n_members;
68 struct network_host **members;
69 };
70
71 static inline const char *network_host_name(struct network_host *host)
72 {
73 if (!host)
74 return "(none)";
75
76 return host->node.key;
77 }
78
79 static inline bool network_host_is_peer(struct network_host *host)
80 {
81 return !!host->peer.node.avl.key;
82 }
83
84 static inline const char *network_peer_name(struct network_peer *peer)
85 {
86 struct network_host *host;
87
88 if (!peer || peer->dynamic)
89 return "(none)";
90
91 host = container_of(peer, struct network_host, peer);
92 return network_host_name(host);
93 }
94
95
96 static inline bool
97 network_host_uses_peer_route(struct network_host *host, struct network *net,
98 struct network_peer *peer)
99 {
100 if (&host->peer == peer || host == net->net_config.local_host)
101 return false;
102
103 if (net->net_config.local_host->gateway &&
104 !strcmp(net->net_config.local_host->gateway, network_peer_name(peer)))
105 return true;
106
107 if (!host->gateway)
108 return false;
109
110 return !strcmp(host->gateway, network_peer_name(peer));
111 }
112
113 #define for_each_routed_host(cur_host, net, peer) \
114 avl_for_each_element(&(net)->hosts, cur_host, node) \
115 if (network_host_uses_peer_route(host, net, peer))
116
117
118 void network_hosts_update_start(struct network *net);
119 void network_hosts_update_done(struct network *net);
120 void network_hosts_add(struct network *net, struct blob_attr *hosts);
121 void network_hosts_reload_dynamic_peers(struct network *net);
122
123 void network_hosts_init(struct network *net);
124 void network_hosts_free(struct network *net);
125
126 #endif