#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];
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;
- union network_endpoint next_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;
};
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 = container_of(peer, struct network_host, 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)
+{
+ if (&host->peer == peer || 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 (!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);