unet-cli: strip initial newline in usage message
[project/unetd.git] / host.h
diff --git a/host.h b/host.h
index bf61e75e9f4098c086a4a4375f5273339f5674ec..56d359c7e0580aa9df5243c6bc7ce29c97487416 100644 (file)
--- a/host.h
+++ b/host.h
@@ -5,6 +5,14 @@
 #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];
@@ -13,29 +21,43 @@ struct network_peer {
        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;
 };
 
@@ -49,19 +71,55 @@ struct network_group {
 
 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);