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