4 [ -n "$INCLUDE_ONLY" ] ||
{
10 proto_yggdrasil_init_config
() {
14 proto_config_add_string
"private_key"
15 proto_config_add_boolean
"allocate_listen_addresses"
18 proto_config_add_boolean
"jumper_enable"
19 proto_config_add_string
"jumper_loglevel"
20 proto_config_add_boolean
"jumper_autofill_listen_addresses"
21 proto_config_add_string
"jumper_config"
24 proto_yggdrasil_setup_peer_if_non_interface
() {
25 local peer_config
="$1"
28 config_get peer_address
"${peer_config}" "address"
29 config_get peer_interface
"${peer_config}" "interface"
30 if [ -z ${peer_interface} ]; then
31 json_add_string
"" ${peer_address}
35 proto_yggdrasil_dump_peer_interface
() {
36 local peer_config
="$1"
39 config_get peer_interface
"${peer_config}" "interface"
41 if [ ! -z ${peer_interface} ]; then
42 peer_interfaces
="${peer_interfaces}\n${peer_interface}"
46 proto_yggdrasil_setup_peer_if_interface
() {
47 local peer_config
="$1"
50 config_get peer_interface
"${peer_config}" "interface"
51 if [ "${peer_interface}" = "${peer_interface_filter}" ]; then
52 config_get peer_address
"${peer_config}" "address"
53 json_add_string
"" ${peer_address}
57 proto_yggdrasil_append_to_interface_regex
() {
58 if [ -z "${regex}" ]; then
65 proto_yggdrasil_setup_multicast_interface
() {
66 local interface_config
="$1"
73 config_get beacon
"${interface_config}" "beacon"
74 config_get listen
"${interface_config}" "listen"
75 config_get port
"${interface_config}" "port"
76 config_get password
"${interface_config}" "password"
79 json_add_boolean
"Beacon" $beacon
80 json_add_boolean
"Listen" $listen
81 if [ ! -z ${port} ]; then
82 json_add_int
"Port" $port
86 if [ ! -z ${password} ]; then
87 json_add_string
"Password" $password
90 config_list_foreach
"${interface_config}" interface proto_yggdrasil_append_to_interface_regex
92 json_add_string
"Regex" "^(${regex})\$"
97 proto_yggdrasil_add_string
() {
101 proto_yggdrasil_generate_keypair
() {
102 json_load
"$(yggdrasil -genconf -json)"
103 json_get_vars PrivateKey
105 private_key
=$PrivateKey
106 public_key
=${PrivateKey:64}
109 proto_yggdrasil_allocate_listen_addresses
() {
112 # Collect already defined protocols
114 _add_address_protocol
() {
115 protocols
="${protocols}$(echo $1 | cut -d "://" -f1) "
117 config_list_foreach
"$config" listen_address _add_address_protocol
119 # Add new address for each previously unspecified protocol
120 for protocol
in "tls" "quic"; do
121 if ! echo "$protocols" |
grep "$protocol" &>/dev
/null
; then
122 # By default linux dynamically alocates ports in the range 32768..60999
123 # `sysctl net.ipv4.ip_local_port_range`
124 random_port
=$
(( ($RANDOM + $RANDOM) % 22767 + 10000 ))
125 proto_yggdrasil_add_string
"${protocol}://127.0.0.1:${random_port}"
130 proto_yggdrasil_generate_jumper_config
() {
135 # Autofill Yggdrasil listeners
136 config_get is_autofill_listeners
"$config" "jumper_autofill_listen_addresses"
137 if [ "$is_autofill_listeners" == "1" ]; then
138 echo "yggdrasil_listen = ["
142 json_load_file
"${ygg_cfg}"
143 json_for_each_item _print_address
"Listen"
147 # Print admin api socket
148 echo "yggdrasil_admin_listen = [ \"${ygg_sock}\" ]"
151 config_get jumper_config
"$config" "jumper_config"
152 echo "${jumper_config}"
155 proto_yggdrasil_setup
() {
158 local ygg_dir
="/tmp/yggdrasil"
159 local ygg_cfg
="${ygg_dir}/${config}.conf"
160 local ygg_sock
="unix://${ygg_dir}/${config}.sock"
166 local listen_addresses
167 local whitelisted_keys
169 local node_info_privacy
172 config_get private_key
"${config}" "private_key"
173 config_get public_key
"${config}" "public_key"
174 config_get mtu
"${config}" "mtu"
175 config_get node_info
"${config}" "node_info"
176 config_get node_info_privacy
"${config}" "node_info_privacy"
178 if [ -z $private_key ]; then
179 proto_yggdrasil_generate_keypair
183 mkdir
-p "${ygg_dir}"
185 if [ $private_key = "auto" ]; then
186 proto_yggdrasil_generate_keypair
187 uci
-t ${ygg_dir}/.uci.
${config} batch <<EOF
188 set network.${config}.private_key='${private_key}'
189 set network.${config}.public_key='${public_key}'
191 uci
-t ${ygg_dir}/.uci.
${config} commit
;
194 # Generate config file
196 json_add_string
"IfName" ${config}
197 json_add_string
"AdminListen" ${ygg_sock}
199 json_add_string
"PrivateKey" ${private_key}
200 json_add_string
"PublicKey" ${public_key}
202 if [ ! -z $mtu ]; then
203 json_add_int
"IfMTU" ${mtu}
206 if [ ! -z $node_info ]; then
207 json_add_string
"NodeInfo" "%%_YGGDRASIL_NODEINFO_TEMPLATE_%%"
210 json_add_boolean
"NodeInfoPrivacy" ${node_info_privacy}
213 json_add_array
"Peers"
214 config_foreach proto_yggdrasil_setup_peer_if_non_interface
"yggdrasil_${config}_peer"
217 local peer_interfaces
219 config_foreach proto_yggdrasil_dump_peer_interface
"yggdrasil_${config}_peer"
220 peer_interfaces
=$
(echo -e ${peer_interfaces} |
sort |
uniq)
222 json_add_object
"InterfacePeers"
223 for peer_interface_filter
in ${peer_interfaces}; do
224 json_add_array
"${peer_interface_filter}"
225 config_foreach proto_yggdrasil_setup_peer_if_interface
"yggdrasil_${config}_peer"
230 json_add_array
"AllowedPublicKeys"
231 config_list_foreach
"$config" allowed_public_key proto_yggdrasil_add_string
234 json_add_array
"Listen"
235 config_list_foreach
"$config" listen_address proto_yggdrasil_add_string
237 # If needed, add new address for each previously unspecified protocol
238 config_get is_jumper_enabled
"$config" "jumper_enable"
239 config_get allocate_listen_addresses
"$config" "allocate_listen_addresses"
240 if [ "$is_jumper_enabled" == "1" ] && [ "$allocate_listen_addresses" == "1" ]; then
241 proto_yggdrasil_allocate_listen_addresses
"$config"
246 json_add_array
"MulticastInterfaces"
247 config_foreach proto_yggdrasil_setup_multicast_interface
"yggdrasil_${config}_interface"
250 json_dump
> "${ygg_cfg}.1"
251 awk -v s
='"%%_YGGDRASIL_NODEINFO_TEMPLATE_%%"' -v r
="${node_info}" '{gsub(s, r)} 1' "${ygg_cfg}.1" > ${ygg_cfg}
254 proto_run_command "$config" /usr/sbin/yggdrasil -useconffile "${ygg_cfg}"
255 proto_init_update "$config" 1
256 proto_add_ipv6_address "$
(yggdrasil
-useconffile "${ygg_cfg}" -address)" "7"
257 proto_add_ipv6_prefix "$
(yggdrasil
-useconffile "${ygg_cfg}" -subnet)"
258 proto_send_update "$config"
260 # Start jumper if needed
261 config_get is_jumper_enabled "$config" "jumper_enable
"
262 if [ "$is_jumper_enabled" == "1" ] && [ -f /usr/sbin/yggdrasil-jumper ]; then
263 jumper_cfg="${ygg_dir}/${config}-jumper.conf
"
264 proto_yggdrasil_generate_jumper_config "$config" "$ygg_sock" "$ygg_cfg" > "$jumper_cfg"
266 config_get jumper_loglevel "$config" "jumper_loglevel
"
267 sh -c "sleep 2 && exec /usr
/sbin
/yggdrasil-jumper
--loglevel \"${jumper_loglevel:-info}\" --config \"$jumper_cfg\" 2&>1 | logger
-t \"${config}-jumper\"" &
271 proto_yggdrasil_teardown() {
273 proto_kill_command "$interface"
276 [ -n "$INCLUDE_ONLY" ] || {
277 add_protocol yggdrasil