initial commit
[project/unetd.git] / wg.c
1 #include "unetd.h"
2
3 static const struct wg_ops *wg_get_ops(struct network *net)
4 {
5 if (dummy_mode)
6 return &wg_dummy_ops;
7
8 if (wg_user_ops.check(net))
9 return &wg_user_ops;
10
11 #ifdef linux
12 return &wg_linux_ops;
13 #else
14 return NULL;
15 #endif
16 }
17
18 int wg_init_network(struct network *net)
19 {
20 net->wg.ops = wg_get_ops(net);
21
22 if (!net->wg.ops)
23 return -1;
24
25 return net->wg.ops->init(net);
26 }
27
28 void wg_cleanup_network(struct network *net)
29 {
30 if (net->wg.ops)
31 net->wg.ops->cleanup(net);
32 }
33
34 struct network_peer *wg_peer_update_start(struct network *net, const uint8_t *key)
35 {
36 struct network_peer *peer;
37
38 peer = vlist_find(&net->peers, key, peer, node);
39 if (!peer)
40 return NULL;
41
42 peer->state.handshake = false;
43 peer->state.idle++;
44 if (peer->state.idle >= 2 * net->net_config.keepalive)
45 peer->state.connected = false;
46 if (peer->state.idle > net->net_config.keepalive)
47 network_pex_event(net, peer, PEX_EV_PING);
48
49 return peer;
50 }
51
52 void wg_peer_update_done(struct network *net, struct network_peer *peer)
53 {
54 if (peer->state.handshake)
55 network_pex_event(net, peer, PEX_EV_HANDSHAKE);
56 }
57
58 void wg_peer_set_last_handshake(struct network *net, struct network_peer *peer,
59 uint64_t now, uint64_t sec)
60 {
61 if (sec == peer->state.last_handshake)
62 return;
63
64 peer->state.handshake = true;
65 peer->state.last_handshake = sec;
66 sec = now - sec;
67 if (sec <= net->net_config.keepalive) {
68 peer->state.connected = true;
69 if (peer->state.idle > sec)
70 peer->state.idle = sec;
71 }
72 }
73
74 void wg_peer_set_rx_bytes(struct network *net, struct network_peer *peer,
75 uint64_t bytes)
76 {
77 int64_t diff = bytes - peer->state.rx_bytes;
78
79 peer->state.rx_bytes = bytes;
80 if (diff > 0) {
81 peer->state.idle = 0;
82 peer->state.connected = true;
83 }
84 }
85
86 void wg_peer_set_endpoint(struct network *net, struct network_peer *peer,
87 void *data, size_t len)
88 {
89 if (len > sizeof(peer->state.endpoint))
90 return;
91
92 if (!memcmp(&peer->state.endpoint, data, len))
93 return;
94
95 memset(&peer->state.endpoint, 0, sizeof(peer->state.endpoint));
96 memcpy(&peer->state.endpoint, data, len);
97 network_pex_event(net, peer, PEX_EV_ENDPOINT_CHANGE);
98 }