Opennet Firmware
services.sh
gehe zur Dokumentation dieser Datei
1 ## @defgroup services Dienste
2 ## @brief Verwaltung von Diensten (z.B. via olsrd-nameservice announciert)
3 # Beginn der Doku-Gruppe
4 ## @{
5 
6 VOLATILE_SERVICE_STATUS_DIR=/tmp/on-services-volatile.d
7 PERSISTENT_SERVICE_STATUS_DIR=/etc/on-services.d
8 # eine grosse Zahl sorgt dafuer, dass neu entdeckte Dienste hinten angehaengt werden
9 DEFAULT_SERVICE_RANK=10000
10 DEFAULT_SERVICE_SORTING=etx
11 # Die folgenden Attribute werden dauerhaft (im Flash) gespeichert. Häufige Änderungen sind also eher unerwünscht.
12 # Gruende fuer ausgefallene/unintuitive Attribute:
13 # uci_dependency: später zu beräumende uci-Einträge wollen wir uns merken
14 # file_dependency: siehe uci_dependency
15 # priority: DNS-entdeckte Dienste enthalten ein "priority"-Attribut, nach einem reboot wieder verfügbar sein sollte
16 # rank/offset: Attribute zur Ermittlung der Dienstreihenfolge
17 # disabled: der Dienst wurde vom Nutzenden an- oder abgewählt
18 # source: die Quelle des Diensts (olsrd/dns/manual) muss erhalten bleiben, um ihn später löschen zu können
19 # Wir beachten den vorherigen Zustand der Variable, damit andere Module (z.B. on-usergw) diese
20 # ebenfalls beeinflussen können.
21 PERSISTENT_SERVICE_ATTRIBUTES="${PERSISTENT_SERVICE_ATTRIBUTES:-} service scheme host port protocol path uci_dependency file_dependency priority rank offset disabled source"
22 LOCAL_BIAS_MODULO=10
23 SERVICES_LOG_BASE=/var/log/on-services
24 # Namenspräfix für weiterzuleitende Dienste
25 RELAYABLE_SERVICE_PREFIX="proxy-"
26 UPDATE_TRUSTED_SERVICES_PERIOD_MINUTES=360
27 USER_SERVICES_URL=https://service-discovery.opennet-initiative.de/user-services.csv
28 
29 # andere Module fügen eventuell weitere URLs hinzu
30 SERVICES_LIST_URLS="${SERVICES_LIST_URLS:-} $USER_SERVICES_URL"
31 
32 
33 ## @fn get_service_name()
34 ## @brief Ermittle en Namen eines Diensts basierend auf den Dienst-Attributen.
35 ## @details Reihenfolge der Eingabeparameter: SERVICE_TYPE SCHEMA HOST PORT PROTOCOL PATH
37  local service="$1"
38  local scheme="$2"
39  local host="$3"
40  local port="$4"
41  local protocol="$5"
42  local path="$6"
43  local name="${service}_${scheme}_${host}_${port}_${protocol}"
44  [ -n "${path#/}" ] && name="${name}_${path#/}"
45  echo "$name" | sed 's/[^A-Za-z0-9_]/_/g'
46 }
47 
48 
49 ## @fn notify_service()
50 ## @brief Aktualisiere den Zeitstempel und die Entfernung (etx) eines Dienstes
51 ## @param service z.B. "gw"
52 ## @param scheme z.B. "openvpn"
53 ## @param host z.B. "192.168.2.254"
54 ## @param port z.B. "1600"
55 ## @param path z.B. "/"
56 ## @param protocol z.B. "udp"
57 ## @param details z.B. "via:megumi"
58 ## @returns Der Dienstname wird ausgegeben.
60  trap 'error_trap notify_service "$*"' EXIT
61  # wir erwarten sieben Parameter
62  [ "$#" -eq 7 ] || [ "$#" -eq 8 ]
63  local source="$1"
64  shift
65  echo "$@" | notify_services "$source"
66 }
67 
68 
69 ## @fn notify_services()
70 ## @brief Siehe "notify_service" - jedoch effizienter im Umgang mit einer großen Anzahl von Diensten
71 ## @param source Quelle (z.B. "olsr")
72 ## @returns Alle Dienstnamen werden ausgegeben.
74  trap 'error_trap notify_services "$*"' EXIT
75  local source="$1"
76  local service
77  local scheme
78  local host
79  local port
80  local protocol
81  local path
82  local source
83  local details
84  local service_name
85  local etx
86  local hop
87  while read -r service scheme host port protocol path details; do
88  service_name=$(get_service_name "$service" "$scheme" "$host" "$port" "$protocol" "$path")
89  # Diese Attribute duerften sich nicht aendern, aber wir wollen sicherheitshalber lieber kaputten
90  # Werten vorbeugen.
91  # "details", "timestamp" und "source" sind die flexiblen Werte.
92  set_service_value "$service_name" \
93  "service" "$service" \
94  "scheme" "$scheme" \
95  "host" "$host" \
96  "port" "$port" \
97  "protocol" "$protocol" \
98  "path" "$path" \
99  "details" "$details" \
100  "timestamp" "$(get_uptime_minutes)" \
101  "source" "$source"
102  get_hop_count_and_etx "$host" | while read -r hop etx; do
103  set_service_value "$service_name" \
104  "distance" "$etx" \
105  "hop_count" "$hop"
106  done
107  echo "$service_name"
108  done
109 }
110 
111 
112 ## @fn is_existing_service()
113 ## @brief Prüfe ob ein Service existiert
114 ## @param service_name der Name des Diensts
115 ## @returns exitcode=0 falls der Dienst existiert
117  local service_name="$1"
118  if [ -n "$service_name" ] && [ -e "$PERSISTENT_SERVICE_STATUS_DIR/$service_name" ]; then
119  return 0
120  else
121  trap "" EXIT && return 1
122  fi
123 }
124 
125 
126 ## @fn _get_local_bias_for_service()
127 ## @brief Ermittle eine reproduzierbare Zahl von 0 bis (LOCAL_BIAS_MODULO-1) - abhängig von der lokalen IP und dem Dienstnamen.
128 ## @param service_name der Name des Diensts für den ein Bias-Wert zu ermitteln ist.
129 ## @details Dadurch können wir beim Sortieren strukturelle Bevorzugungen (z.B. durch alphabetische Sortierung) verhindern.
131  local service_name="$1"
132  # lade den Wert aus dem Cache, falls moeglich
133  local bias_cache
134  bias_cache=$(get_service_value "$service_name" "local_bias")
135  if [ -z "$bias_cache" ]; then
136  # Die resultierende host_number darf nicht zu gross sein (z.B. mit Exponentendarstellung),
137  # da andernfalls awk die Berechnung fehlerhaft durchführt.
138  local host_number
139  host_number=$(echo "$service_name$(get_local_bias_number)" | md5sum | sed 's/[^0-9]//g')
140  # Laenge von 'host_number' reduzieren (die Berechnung schlaegt sonst fehl)
141  # Wir fuegen die 1 an den Beginn, um die Interpretation als octal-Zahl zu verhindern (fuehrende Null).
142  bias_cache=$(( 1${host_number:0:6} % LOCAL_BIAS_MODULO))
143  set_service_value "$service_name" "local_bias" "$bias_cache"
144  fi
145  echo -n "$bias_cache"
146 }
147 
149 # Ermittle die Service-Prioritaet eines Dienstes.
150 # Der Wert ist beliebig und nur im Vergleich mit den Prioritaeten der anderen Dienste verwendbar.
151 # Als optionaler zweiter Parameter kann die Sortierung uebergeben werden. Falls diese nicht uebergeben wurde,
152 # wird die aktuell konfigurierte Sortierung benutzt.
153 # Sollte ein Dienst ein "priority"-Attribut tragen, dann wird die uebliche Dienst-Sortierung aufgehoben
154 # und lediglich "priority" (und gegebenenfalls separat "offset") beachtet.
155 get_service_priority() {
156  trap 'error_trap get_service_priority "$*"' EXIT
157  local service_name="$1"
158  local sorting="${2:-}"
159  local priority
160  priority=$(get_service_value "$service_name" "priority")
161  # priority wird von nicht-olsr-Clients verwendet (z.B. mesh-Gateways mit oeffentlichen IPs)
162  local base_priority
163  base_priority=$(
164  if [ -n "$priority" ]; then
165  # dieses Ziel traegt anscheinend keine Routing-Metrik
166  local offset
167  offset=$(get_service_value "$service_name" "offset" "0")
168  echo "$((priority + offset))"
169  else
170  # wir benoetigen Informationen fuer Ziele mit Routing-Metriken
171  # aus Performance-Gruenden kommt die Sortierung manchmal von aussen
172  [ -z "$sorting" ] && sorting=$(get_service_sorting)
173  if [ "$sorting" = "etx" ] || [ "$sorting" = "hop" ]; then
174  get_distance_with_offset "$service_name" "$sorting"
175  elif [ "$sorting" = "manual" ]; then
176  get_service_value "$service_name" "rank" "$DEFAULT_SERVICE_RANK"
177  else
178  msg_error "Unknown sorting method for services: $sorting"
179  echo 1
180  fi
181  fi)
182  local service_bias
183  service_bias=$(_get_local_bias_for_service "$service_name")
184  echo "${base_priority:-$DEFAULT_SERVICE_RANK}" | awk '{ print $1 * 1000 + '"$service_bias"'; }'
185 }
186 
187 
188 get_distance_with_offset() {
189  trap 'error_trap get_distance_with_offset "$*"' EXIT
190  local service_name="$1"
191  local sorting="${2:-}"
192  local distance
193  local base_value=
194  local offset
195  # aus Performance-Gruenden wird manchmal das sorting von aussen vorgegeben
196  [ -z "$sorting" ] && sorting=$(get_service_sorting)
197  distance=$(get_service_value "$service_name" "distance")
198  [ -z "$distance" ] && return 0
199  offset=$(get_service_value "$service_name" "offset")
200  [ -z "$offset" ] && offset=0
201  if [ "$sorting" = "etx" ]; then
202  base_value="$distance"
203  elif [ "$sorting" = "hop" ]; then
204  base_value=$(get_service_value "$service_name" "hop_count")
205  else
206  msg_debug "get_distance_with_offset: sorting '$sorting' not implemented"
207  fi
208  [ -n "$base_value" ] && echo "$base_value" "$offset" | awk '{ print $1 + $2 }'
209 }
210 
211 
212 set_service_sorting() {
213  trap 'error_trap set_service_sorting "$*"' EXIT
214  local new_sorting="$1"
215  local old_sorting
216  old_sorting=$(get_service_sorting)
217  [ "$old_sorting" = "$new_sorting" ] && return 0
218  if [ "$new_sorting" != "manual" ] && [ "$new_sorting" != "hop" ] && [ "$new_sorting" != "etx" ]; then
219  msg_error "Ignoring unknown sorting method: $new_sorting"
220  trap "" EXIT && return 1
221  else
222  uci set "on-core.settings.service_sorting=$new_sorting"
223  apply_changes "on-core"
224  fi
225 }
226 
227 
228 # Liefere die aktuelle Sortier-Methode.
229 # Falls eine ungueltige Sortier-Methode gesetzt ist, wird diese auf die Standard-Sortierung zurueckgesetzt.
230 # Die Ausgabe dieser Funktion ist also in jedem Fall eine gueltige Sortier-Methode.
231 get_service_sorting() {
232  trap 'error_trap get_service_sorting "$*"' EXIT
233  local sorting
234  sorting=$(uci_get "on-core.settings.service_sorting")
235  if [ "$sorting" = "manual" ] || [ "$sorting" = "hop" ] || [ "$sorting" = "etx" ]; then
236  # zulaessige Sortierung
237  echo -n "$sorting"
238  else
239  # unbekannte Sortierung: dauerhaft setzen
240  # keine Warnung falls die Sortierung nicht gesetzt wurde
241  [ -n "$sorting" ] && msg_error "coercing unknown sorting method: $sorting -> $DEFAULT_SERVICE_SORTING"
242  uci set "on-core.settings.service_sorting=$DEFAULT_SERVICE_SORTING"
243  echo -n "$DEFAULT_SERVICE_SORTING"
244  fi
245  return 0
246 }
247 
248 
249 ## @fn sort_services_by_priority()
250 ## @brief Sortiere den eingegebenen Strom von Dienstnamen und gib eine nach der Priorität sortierte Liste.
251 ## @details Die Prioritätsinformation wird typischerweise für nicht-mesh-verteilte Dienste verwendet (z.B. den mesh-Tunnel).
253  trap 'error_trap sort_services_by_priority "$*"' EXIT
254  local service_name
255  local priority
256  local sorting
257  sorting=$(get_service_sorting)
258  while read -r service_name; do
259  priority=$(get_service_priority "$service_name" "$sorting")
260  # keine Entfernung (nicht erreichbar) -> ganz nach hinten sortieren (schmutzig, aber wohl ausreichend)
261  [ -z "$priority" ] && priority=999999999999999
262  echo "$priority" "$service_name"
263  done | sort -n | awk '{print $2}'
264 }
265 
266 
267 ## @fn filter_reachable_services()
268 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die erreichbar sind.
269 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an die Standardausgabe
270 ## weitergeleitet, falls der Dienst erreichbar sind. "Erreichbarkeit" gilt als erreicht, wenn
271 ## der Host via olsr route-bar ist oder wenn er als DNS-entdeckter Dienst eine Priorität hat
272 ## oder wenn er manuell hinzugefügt wurde.
274  local service_name
275  while read -r service_name; do
276  { [ -n "$(get_service_value "$service_name" "distance")" ] \
277  || [ -n "$(get_service_value "$service_name" "priority")" ] \
278  || [ "$(get_service_value "$service_name" "source")" = "manual" ]
279  } && echo "$service_name"
280  true
281  done
282 }
283 
284 
285 ## @fn filter_enabled_services()
286 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die nicht manuell ausgeblendet wurden.
287 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an
288 ## die Standardausgabe weitergeleitet, falls der Dienst nicht abgewählt wurde.
290  local service_name
291  local disabled
292  while read -r service_name; do
293  disabled=$(get_service_value "$service_name" "disabled")
294  [ -n "$disabled" ] && uci_is_true "$disabled" && continue
295  echo "$service_name"
296  done
297 }
298 
299 
300 ## @fn pipe_service_attribute()
301 ## @brief Liefere zu einer Reihe von Diensten ein gewähltes Attribut dieser Dienste zurück.
302 ## @param key Der Name eines Dienst-Attributs
303 ## @param default Der Standard-Wert wird anstelle des Attribut-Werts verwendet, falls dieser leer ist.
304 ## @details Die Dienstenamen werden via Standardeingabe erwartet. Auf der Standardausgabe wird für
305 ## einen Dienst entweder ein Wert oder nichts ausgeliefert. Keine Ausgabe erfolgt, falls der
306 ## Wert des Dienste-Attributs leer ist. Bei der Eingabe von mehreren Diensten werden also
307 ## eventuell weniger Zeilen ausgegeben, als eingelesen wurden.
308 ## Falls der optionale zweite 'default'-Parameter nicht leer ist, dann wird bei einem leeren
309 ## Ergebnis stattdessen dieser Wert ausgegeben. Der 'default'-Parameter sorgt somit dafür, dass
310 ## die Anzahl der eingelesenen Zeilen in jedem Fall mit der Anzahl der ausgegebenen Zeilen
311 ## übereinstimmt.
312 ## Die Ausgabe besteht aus dem Service-Namen und dem Attributinhalt (getrennt durch einen Tabulator).
314  local key="$1"
315  local default="${2:-}"
316  local service_name
317  local value
318  while read -r service_name; do
319  [ -z "$service_name" ] && continue
320  value=$(get_service_value "$service_name" "$key")
321  [ -z "$value" ] && value="$default"
322  [ -n "$value" ] && printf '%s\t%s\n' "$service_name" "$value"
323  true
324  done
325 }
326 
327 
328 ## @fn get_services()
329 ## @param service_type (optional) ein Service-Typ
330 ## @brief Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind.
331 ## Falls kein Typ angegben wird, dann werden alle Dienste ungeachtet ihres Typs ausgegeben.
332 get_services() {
333  trap 'error_trap get_services "$*"' EXIT
334  local service_type="${1:-}"
335  # alle Dienste ausgeben
336  # kein Dienste-Verzeichnis? Keine Ergebnisse ...
337  [ -e "$PERSISTENT_SERVICE_STATUS_DIR" ] || return 0
338  find "$PERSISTENT_SERVICE_STATUS_DIR" -type f -size +1c -print0 \
339  | xargs -0 -r -n 1 basename \
340  | if [ -n "$service_type" ]; then
341  filter_services_by_value "service" "$service_type"
342  else
343  cat -
344  fi
345 }
346 
347 
348 ## @fn filter_services_by_value()
349 ## @param key ein Schlüssel
350 ## @param value ein Wert
351 ## @details Als Parameter kann ein "key/value"-Schluesselpaar angegeben werden.
352 ## Nur diejenigen Dienste, auf die diese Bedingung zutrifft, werden zurueckgeliefert.
354  local key="$1"
355  local value="$2"
356  local service_name
357  while read -r service_name; do
358  [ "$value" != "$(get_service_value "$service_name" "$key")" ] || echo "$service_name"
359  done
360 }
361 
362 
363 ## @fn set_service_value()
364 ## @brief Setzen eines oder mehrerer Werte fuer einen Dienst.
365 ## Je nach Schluesselname wird der Inhalt in die persistente uci- oder
366 # die volatile tmpfs-Datenbank geschrieben.
368  local service_name="$1"
369  shift
370  local attribute
371  local value
372  local dirname
373  [ -z "$service_name" ] \
374  && msg_error "No service given for attribute change ($attribute=$value)" \
375  && trap "" EXIT && return 1
376  while [ "$#" -gt 0 ]; do
377  attribute="$1"
378  value="$2"
379  shift 2
380  # unverändert? ueberspringen ...
381  [ "$value" = "$(get_service_value "$service_name" "$attribute")" ] && continue
382  if echo "$PERSISTENT_SERVICE_ATTRIBUTES" | grep -q -w "$attribute"; then
383  dirname="$PERSISTENT_SERVICE_STATUS_DIR"
384  else
385  dirname="$VOLATILE_SERVICE_STATUS_DIR"
386  fi
387  _set_file_dict_value "$dirname/$service_name" "$attribute" "$value"
388  done
389 }
390 
391 
392 ## @fn get_service_value()
393 ## @brief Auslesen eines Werts aus der Service-Datenbank.
394 ## @param key Der Name eines Dienst-Attributs
395 ## @param default Der Standard-Wert wird anstelle des Attribut-Werts verwendet, falls dieser leer ist.
396 ## @details Falls das Attribut nicht existiert, wird ein leerer Text zurückgeliefert.
397 ## Es gibt keinen abschließenden Zeilenumbruch.
399  local service_name="$1"
400  local attribute="$2"
401  local default="${3:-}"
402  local value
403  local dirname
404  [ -z "$service_name" ] \
405  && msg_error "No service given for attribute request ('$attribute')" \
406  && trap "" EXIT && return 1
407  value=$(_get_file_dict_value "$attribute" "$PERSISTENT_SERVICE_STATUS_DIR/$service_name" "$VOLATILE_SERVICE_STATUS_DIR/$service_name")
408  [ -n "$value" ] && echo -n "$value" || echo -n "$default"
409  return 0
410 }
411 
412 
413 # Liefere die Suffixe aller Schluessel aus der Service-Attribut-Datenbank,
414 # die mit dem gegebenen Praefix uebereinstimmen.
415 get_service_attributes() {
416  _get_file_dict_keys "$PERSISTENT_SERVICE_STATUS_DIR/$1" "$VOLATILE_SERVICE_STATUS_DIR/$1"
417 }
418 
419 
420 ## @fn print_services()
421 ## @brief menschenfreundliche Ausgabe der aktuell angemeldeten Dienste
422 ## @param service_type (optional) ein Service-Type
423 ## @returns Ausgabe der bekannten Dienste (für Menschen - nicht parsebar)
424 print_services() {
425  trap 'error_trap print_services "$*"' EXIT
426  local service_name
427  local attribute
428  local value
429  for service_name in $(get_services "$@"); do
430  echo "$service_name"
431  for attribute in $(get_service_attributes "$service_name"); do
432  printf '\t%s=%s\n' "$attribute" "$(get_service_value "$service_name" "$attribute")"
433  done
434  done
435  return 0
436 }
437 
438 
439 # Speichere das angegebene uci-Praefix als eine von einem Service abhaengige Konfiguration.
440 # Dies ist sinnvoll fuer abgeleitete VPN-Konfigurationen oder Portweiterleitungen.
441 # Schnittstelle: siehe _add_service_dependency
442 service_add_uci_dependency() {
443  _add_service_dependency "uci_dependency" "$@"
444 }
445 
446 
447 # Speichere einen Dateinamen als Abhaengigkeit eines Service.
448 # Dies ist sinnvoll fuer Dateien, die nicht mehr gebraucht werden, sobald der Service entfernt wird.
449 # Schnittstelle: siehe _add_service_dependency
450 service_add_file_dependency() {
451  _add_service_dependency "file_dependency" "$@"
452 }
453 
454 
455 # Speichere eine Abhaengigkeit fuer einen Dienst.
456 # Parameter: Service-Name
457 # Parameter: textuelle Darstellung einer Abhaengigkeit (ohne Leerzeichen)
458 _add_service_dependency() {
459  trap 'error_trap _add_service_dependency "$*"' EXIT
460  local dependency="$1"
461  local service_name="$2"
462  local token="$3"
463  local deps
464  local dep
465  deps=$(get_service_value "$service_name" "$dependency")
466  for dep in $deps; do
467  # schon vorhanden -> fertig
468  [ "$dep" = "$token" ] && return 0
469  true
470  done
471  if [ -z "$deps" ]; then
472  deps="$token"
473  else
474  deps="$deps $token"
475  fi
476  set_service_value "$service_name" "$dependency" "$deps"
477 }
478 
479 
480 # Entferne alle mit diesem Service verbundenen Konfigurationen (inkl. Rekonfiguration von firewall, etc.).
481 cleanup_service_dependencies() {
482  trap 'error_trap cleanup_service_dependencies "$*"' EXIT
483  local service_name="$1"
484  local dep
485  local filename
486  local branch
487  # Dateien loeschen
488  for filename in $(get_service_value "$service_name" "file_dependency"); do
489  rm -f "$filename"
490  done
491  # uci-Sektionen loeschen
492  for dep in $(get_service_value "$service_name" "uci_dependency"); do
493  uci_delete "$dep"
494  # gib die oberste config-Ebene aus - fuer spaeteres "apply_changes"
495  echo "$dep" | cut -f 1 -d .
496  done | sort | uniq | while read -r branch; do
497  apply_changes "$branch"
498  done
499  set_service_value "$service_name" "uci_dependency" ""
500 }
501 
502 
503 delete_service() {
504  trap 'error_trap delete_service "$*"' EXIT
505  local service_name="$1"
506  [ -z "$service_name" ] && msg_error "No service given for deletion" && trap "" EXIT && return 1
507  cleanup_service_dependencies "$service_name"
508  rm -f "$PERSISTENT_SERVICE_STATUS_DIR/$service_name"
509  rm -f "$VOLATILE_SERVICE_STATUS_DIR/$service_name"
510 }
511 
512 
513 # Durchlaufe alle Dienste und verteile Rangziffern ohne Doppelung an alle Dienste.
514 # Die Dienst-Arten (z.B. DNS und UGW) werden dabei nicht beachtet.
515 # Die Rangziffern sind anschliessend streng monoton aufsteigend - beginnend bei 1.
516 # Falls aktuell die manuelle Sortierung aktiv ist, wird deren Reihenfolge beibehalten.
517 # Ansonsten basiert die Vergabe der Rangziffern auf der Reihenfolge entsprechend der aktuell aktiven Sortierung.
518 _distribute_service_ranks() {
519  local service_name
520  local index=1
521  for service_name in $(get_services | sort_services_by_priority); do
522  set_service_value "$service_name" "rank" "$index"
523  index=$((index + 1))
524  done
525 }
526 
527 
528 ## @fn move_service_up()
529 ## @brief Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach oben
530 ## @param service_name der zu verschiebende Dienst
531 ## @param service_type der Service-Typ innerhalb derer Mitglieder die Verschiebung stattfinden soll
532 ## @details Für verschiedene Sortier-Modi hat dies verschiedene Auswirkungen:
533 ## * manual: Verschiebung vor den davorplatzierten Dienst desselben Typs
534 ## * etx/hop: Reduzierung des Offsets um eins
535 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste nach unten.
536 move_service_up() {
537  trap 'error_trap move_service_up "$*"' EXIT
538  local service_name="$1"
539  shift
540  local sorting
541  local prev_service=
542  local current_service
543  local temp
544  sorting=$(get_service_sorting)
545  if [ "$sorting" = "hop" ] || [ "$sorting" = "etx" ]; then
546  # reduziere den Offset um eins
547  temp=$(get_service_value "$service_name" "offset" 0)
548  temp=$(echo "$temp" | awk '{ print $1 - 1 }')
549  set_service_value "$service_name" "offset" "$temp"
550  elif [ "$sorting" = "manual" ]; then
551  for current_service in $(get_services "$@" | sort_services_by_priority); do
552  if [ "$current_service" = "$service_name" ]; then
553  if [ -z "$prev_service" ]; then
554  # es gibt keinen Dienst oberhalb des zu verschiebenden
555  true
556  else
557  # wir verschieben den Dienst ueber den davor liegenden
558  temp=$(get_service_value "$prev_service" "rank" "$DEFAULT_SERVICE_RANK")
559  # ziehe einen halben Rang ab
560  temp=$(echo "$temp" | awk '{ print $1 - 0.5 }')
561  set_service_value "$service_name" "rank" "$temp"
562  # erneuere die Rang-Vergabe
563  _distribute_service_ranks
564  fi
565  # wir sind fertig
566  break
567  fi
568  prev_service="$current_service"
569  done
570  else
571  msg_info "Warning: [move_service_up] for this sorting method is not implemented: $sorting"
572  fi
573 }
574 
575 
576 ## @fn move_service_down()
577 ## @brief Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach unten
578 ## @param service_name der zu verschiebende Dienst
579 ## @param service_type der Service-Typ innerhalb derer Mitglieder die Verschiebung stattfinden soll
580 ## @details Für verschiedene Sortier-Modi hat dies verschiedene Auswirkungen:
581 ## * manual: Verschiebung hinter den dahinterliegenden Dienst desselben Typs
582 ## * etx/hop: Erhöhung des Offsets um eins
583 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste nach unten.
585  trap 'error_trap move_service_down "$*"' EXIT
586  local service_name="$1"
587  shift
588  local sorting
589  local prev_service=
590  local current_service
591  local temp
592  sorting=$(get_service_sorting)
593  if [ "$sorting" = "hop" ] || [ "$sorting" = "etx" ]; then
594  # reduziere den Offset um eins
595  temp=$(get_service_value "$service_name" "offset" 0)
596  temp=$(echo "$temp" | awk '{ print $1 + 1 }')
597  set_service_value "$service_name" "offset" "$temp"
598  elif [ "$sorting" = "manual" ]; then
599  for current_service in $(get_services "$@" | sort_services_by_priority); do
600  if [ "$prev_service" = "$service_name" ]; then
601  # wir verschieben den Dienst hinter den danach liegenden
602  temp=$(get_service_value "$current_service" "rank" "$DEFAULT_SERVICE_RANK")
603  # fuege einen halben Rang hinzu
604  temp=$(echo "$temp" | awk '{ print $1 + 0.5 }')
605  set_service_value "$service_name" "rank" "$temp"
606  # erneuere die Rang-Vergabe
607  _distribute_service_ranks
608  # wir sind fertig
609  break
610  fi
611  prev_service="$current_service"
612  done
613  else
614  msg_info "Warning: [move_service_down] for this sorting method is not implemented: $sorting"
615  fi
616 }
617 
618 
619 ## @fn move_service_top()
620 ## @brief Verschiebe einen Dienst an die Spitze der Dienst-Sortierung
621 ## @param service_name der zu verschiebende Dienst
622 ## @param service_types ein oder mehrere Dienst-Typen, auf die die Ermittlung der Dienst-Liste begrenzt werden soll (z.B. "gw")
623 ## @details Der Dienst steht anschließend direkt vor dem bisher führenden Dienst der ausgewählten Typen (falls angegeben).
624 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste an die Spitze.
626  trap 'error_trap move_service_top "$*"' EXIT
627  local service_name="$1"
628  shift
629  local top_service
630  local sorting
631  local top_rank
632  local new_rank
633  local top_distance
634  local our_distance
635  local current_offset
636  local new_offset
637  top_service=$(get_services "$@" | sort_services_by_priority | head -1)
638  sorting=$(get_service_sorting)
639  # kein top-Service oder wir sind bereits ganz oben -> Ende
640  if [ -z "$top_service" ] || [ "$top_service" = "$service_name" ]; then
641  true
642  elif [ "$sorting" = "hop" ] || [ "$sorting" = "etx" ]; then
643  top_distance=$(get_distance_with_offset "$top_service" "$sorting")
644  our_distance=$(get_distance_with_offset "$service_name" "$sorting")
645  [ -z "$our_distance" ] && msg_info "Failed to move unreachable service ('$service_name') to top" && return 0
646  current_offset=$(get_service_value "$service_name" "offset" 0)
647  # wir verschieben unseren Offset, auf dass wir knapp ueber "top" stehen
648  new_offset=$(echo | awk "{ print $current_offset + int($top_distance - $our_distance) - 1 }")
649  set_service_value "$service_name" "offset" "$new_offset"
650  elif [ "$sorting" = "manual" ]; then
651  # setze den Rang des Dienstes auf den top-Dienst minus 0.5
652  top_rank=$(get_service_value "$top_service" "rank" "$DEFAULT_SERVICE_RANK")
653  new_rank=$(echo "$top_rank" | awk '{ print $1 - 0.5 }')
654  set_service_value "$service_name" "rank" "$new_rank"
655  # erneuere die Rang-Vergabe
656  _distribute_service_ranks
657  else
658  msg_info "Warning: [move_service_top] for this sorting method is not implemented: $sorting"
659  fi
660 }
661 
662 
663 ## @fn get_service_detail()
664 ## @brief Ermittle den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts
665 ## @param service_name Name eines Diensts
666 ## @param key Name des Schlüssels
667 ## @param default dieser Wert wird zurückgeliefert, falls der Schlüssel nicht gefunden wurde
668 ## @returns den ermittelten Wert aus dem Schlüssel-Wert-Paar
670  local service_name="$1"
671  local key="$2"
672  local default="${3:-}"
673  local value
674  value=$(get_service_value "$service_name" "details" | get_from_key_value_list "$key" ":")
675  [ -n "$value" ] && echo -n "$value" || echo -n "$default"
676  return 0
677 }
678 
679 
680 ## @fn set_service_detail()
681 ## @brief Setze den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts
682 ## @param service_name Name eines Diensts
683 ## @param key Name des Schlüssels
684 ## @param value der neue Wert
685 ## @details Ein leerer Wert löscht das Schlüssel-Wert-Paar.
687  local service_name="$1"
688  local key="$2"
689  local value="$3"
690  local new_details
691  new_details=$(get_service_value "$service_name" "details" | replace_in_key_value_list "$key" ":" "$value")
692  set_service_value "$service_name" "details" "$new_details"
693  return 0
694 }
695 
696 
697 # Liefere eine Semikolon-separierte Liste von Service-Eigenschaften zurueck.
698 # Jede Eigenschaft wird folgendermassen ausgedrueckt:
699 # type|source|key[|default]
700 # Dabei sind folgende Inhalte moeglich:
701 # type: Rueckgabetyp (string, number, bool)
702 # source: Quelle der Informationen (value, detail, function, id)
703 # key: Name des Werts, des Details oder der Funktion
704 # default: Standardwert, falls das Ergebnis leer sein sollte
705 # Wahrheitswerte werden als "true" oder "false" zurueckgeliefert. Alle anderen Rueckgabetypen bleiben unveraendert.
706 # Das Ergebnis sieht folgendermassen aus:
707 # SERVICE_NAME;RESULT1;RESULT2;...
708 get_service_as_csv() {
709  local service_name="$1"
710  shift
711  local separator=";"
712  local specification
713  local rtype
714  local source
715  local key
716  local default
717  local value
718  # Abbruch mit Fehler bei unbekanntem Dienst
719  is_existing_service "$service_name" || { trap "" EXIT && return 1; }
720  echo -n "$service_name"
721  for specification in "$@"; do
722  rtype=$(echo "$specification" | cut -f 1 -d "|")
723  source=$(echo "$specification" | cut -f 2 -d "|")
724  key=$(echo "$specification" | cut -f 3 -d "|")
725  default=$(echo "$specification" | cut -f 4- -d "|")
726  # Ermittlung des Funktionsaufrufs
727  if [ "$source" = "function" ]; then
728  if [ "$rtype" = "bool" ]; then
729  "$key" "$service_name" && value="true" || value="false"
730  else
731  value=$("$key" "$service_name")
732  fi
733  else
734  if [ "$source" = "value" ]; then
735  value=$(get_service_value "$service_name" "$key")
736  elif [ "$source" = "detail" ]; then
737  value=$(get_service_detail "$service_name" "$key")
738  else
739  msg_error "Unknown service attribute requested: $specification"
740  echo -n "${separator}"
741  continue
742  fi
743  [ -z "$value" ] && [ -n "$default" ] && value="$default"
744  if [ "$rtype" = "bool" ]; then
745  # Pruefung auf wahr/falsch
746  value=$(uci_is_true "$value" && echo "true" || echo "false")
747  fi
748  fi
749  echo -n "${separator}${value}"
750  done
751  # mit Zeilenumbruch abschliessen
752  echo
753 }
754 
755 
757 ## @brief Ermittle den Namen der Log-Datei für diesen Dienst. Zusätzliche Details (z.B. "openvpn mtu") sind möglich.
758 ## @param service Name eines Dienstes.
759 ## @param other Eine beliebige Anzahl weiterer Parameter ist erlaubt: diese erweitern den typischen Log-Dateinamen für diesen Dienst.
760 ## @details Die Funktion stellt sicher, dass das Verzeichnis der ermittelten Log-Datei anschließend existiert.
762  trap 'error_trap get_service_log_filename "$*"' EXIT
763  local service_name="$1"
764  shift
765  local full_filename
766  local filename="$service_name"
767  while [ $# -gt 0 ]; do
768  filename="${filename}.$1"
769  shift
770  done
771  full_filename="$SERVICES_LOG_BASE/$(get_safe_filename "$filename").log"
772  mkdir -p "$(dirname "$full_filename")"
773  echo -n "$full_filename"
774 }
775 
776 
777 ## @fn get_service_log_content()
778 ## @brief Lies den Inhalt einer Log-Datei für einen Dienst aus.
779 ## @param service Name eines Dienstes.
780 ## @param max_lines maximale Anzahl der auszuliefernden Zeilen (unbegrenzt: 0)
781 ## @param other Eine beliebige Anzahl weiterer Parameter ist erlaubt: diese erweitern den typischen Log-Dateinamen für diesen Dienst.
782 ## @see get_service_log_filename
784  trap 'error_trap get_service_log_content "$*"' EXIT
785  local service_name="$1"
786  local max_lines="$2"
787  shift 2
788  local log_filename
789  log_filename=$(get_service_log_filename "$service_name" "$@")
790  [ -e "$log_filename" ] || return 0
791  if [ "$max_lines" = "0" ]; then
792  # alle Einträge ausgeben
793  cat -
794  else
795  # nur die letzten Einträge ausliefern
796  tail -n "$max_lines"
797  fi <"$log_filename"
798 }
799 
800 
801 ## @fn is_service_routed_via_wan()
802 ## @brief Pruefe ob der Verkehr zum Anbieter des Diensts über ein WAN-Interface verlaufen würde.
803 ## @param service_name der Name des Diensts
804 ## @returns Exitcode == 0, falls das Routing über das WAN-Interface verläuft.
806  trap 'error_trap is_service_routed_via_wan "$*"' EXIT
807  local service_name="$1"
808  # verwende die übergebene TypeOfService-Angabe oder (falls vorhanden/installiert) den
809  # TOS-Wert, der fuer nicht-Tunnel-Verkehr verwendet wird (typischerweise ist dies die
810  # die Intention des Anfragenden)
811  local tos_field="${2:-}"
812  [ -z "$tos_field" ] && tos_field="${TOS_NON_TUNNEL:-}"
813  local host
814  local outgoing_device
815  local outgoing_zone
816  host=$(get_service_value "$service_name" "host")
817  outgoing_device=$(get_target_route_interface "$host" "$tos_field")
818  if is_device_in_zone "$outgoing_device" "$ZONE_WAN"; then
819  msg_debug "target '$host' routing through wan device: $outgoing_device"
820  return 0
821  else
822  outgoing_zone=$(get_zone_of_device "$outgoing_device")
823  msg_debug "warning: target '$host' is routed via interface '$outgoing_device' (zone '$outgoing_zone') instead of the expected WAN zone ($ZONE_WAN)"
824  trap "" EXIT && return 1
825  fi
826 }
827 
828 
829 _notify_service_success() {
830  local service_name="$1"
831  set_service_value "$service_name" "status" "true"
832  set_service_value "$service_name" "status_fail_counter" ""
833  set_service_value "$service_name" "status_timestamp" "$(get_uptime_minutes)"
834 }
835 
836 
837 _notify_service_failure() {
838  local service_name="$1"
839  local max_fail_attempts="$2"
840  # erhoehe den Fehlerzaehler
841  local fail_counter
842  fail_counter=$(( $(get_service_value "$service_name" "status_fail_counter" "0") + 1))
843  set_service_value "$service_name" "status_fail_counter" "$fail_counter"
844  # Pruefe, ob der Fehlerzaehler gross genug ist, um seinen Status auf "fail" zu setzen.
845  if [ "$fail_counter" -ge "$max_fail_attempts" ]; then
846  # Die maximale Anzahl von aufeinanderfolgenden fehlgeschlagenen Tests wurde erreicht:
847  # markiere ihn als kaputt.
848  set_service_value "$service_name" "status" "false"
849  elif uci_is_true "$(get_service_value "$service_name" "status")"; then
850  # Bisher galt der Dienst als funktionsfaehig - wir setzen ihn auf "neutral" bis
851  # die maximale Anzahl aufeinanderfolgender Fehler erreicht ist.
852  set_service_value "$service_name" "status" ""
853  else
854  # Der Test gilt wohl schon als fehlerhaft - das kann so bleiben.
855  true
856  fi
857  set_service_value "$service_name" "status_timestamp" "$(get_uptime_minutes)"
858 }
859 
860 
861 ## @fn is_trusted_service_list_outdated()
862 ## @brief Ermittle ob mindestens ein Zeitstempel für einen "trusted" Dienst vorhanden ist, der nicht älter
863 ## als die vorgegebene Aktualisierungsperiode ist.
864 ## @returns Wahr, falls kein Diest mit aktuellem Zeitstempel gefunden wurde.
866  trap 'error_trap is_trusted_service_list_outdated "$*"' EXIT
867  local most_recent_timestamp
868  most_recent_timestamp=$(get_services \
869  | filter_services_by_value "source" "trusted" \
870  | pipe_service_attribute "timestamp" | cut -f 2- \
871  | sort -n | tail -1)
872  # kein Zeitstempel -> dies gilt als "veraltet"
873  [ -z "$most_recent_timestamp" ] && return 0
874  # der aktuellste Zeitstempel ist zu alt
875  is_timestamp_older_minutes "$most_recent_timestamp" "$UPDATE_TRUSTED_SERVICES_PERIOD_MINUTES" && return 0
876  trap "" EXIT && return 1
877 }
878 
879 
880 retrieve_service_list_url() {
881  local url="$1"
882  if is_function_available "https_request_opennet"; then
883  https_request_opennet "$url" \
884  || http_request "$url" \
885  || msg_info "Failed to retrieve list of services from $url"
886  else
887  if ! http_request "$url"; then
888  if echo "$url" | grep -q '^https://'; then
889  # The URL probably uses a certificate signed by the Opennet CA,
890  # while "on-certificate" is not installed.
891  # Thus we do not emit any warnings.
892  true
893  else
894  msg_info "Failed to retrieve list of services from $url"
895  fi
896  fi
897  fi
898 }
899 
900 
901 ## @fn update_trusted_services_list()
902 ## @brief Hole die vertrauenswürdigen Dienste von signierten Opennet-Quellen.
903 ## @details Diese Dienste führen beispielsweise auf UGW-APs zur Konfiguration von Portweiterleitungen
904 ## ins Internet. Daher sind sie nur aus vertrauenswürdiger Quelle zu akzeptieren (oder manuell).
906  local line
907  local service_type
908  local scheme
909  local host
910  local port
911  local protocol
912  local priority
913  local details
914  local service_name
915  local is_proxy
916  local service_list
917  service_list=$(for url in $SERVICES_LIST_URLS; do retrieve_service_list_url "$url"; done)
918  # leeres Ergebnis? Noch keine Internet-Verbindung? Keine Aktualisierung, keine Beraeumung ...
919  [ -z "$service_list" ] && msg_info "No trusted services discovered: skipping update." && return
920  echo "$service_list" | grep -v "^#" | sed 's/\t\+/\t/g' | while read -r line; do
921  service_type=$(echo "$line" | cut -f 1)
922  # falls der Dienst-Typ mit "proxy-" beginnt, soll er weitergeleitet werden
923  if [ "${service_type#$RELAYABLE_SERVICE_PREFIX}" = "$service_type" ]; then
924  # kein Proxy-Dienst
925  is_proxy=
926  else
927  # ein Proxy-Dienst
928  is_proxy=1
929  # entferne das Praefix
930  fi
931  scheme=$(echo "$line" | cut -f 2)
932  host=$(echo "$line" | cut -f 3)
933  port=$(echo "$line" | cut -f 4)
934  protocol=$(echo "$line" | cut -f 5)
935  priority=$(echo "$line" | cut -f 6)
936  details=$(echo "$line" | cut -f 7-)
937  service_name=$(notify_service "trusted" "$service_type" "$scheme" "$host" "$port" "$protocol" "/" "$details")
938  set_service_value "$service_name" "priority" "$priority"
939  if [ -n "$is_proxy" ]; then
940  if is_function_available "pick_local_service_relay_port"; then
941  pick_local_service_relay_port "$service_name" >/dev/null
942  fi
943  fi
944  true
945  done
946  # veraltete Dienste entfernen
947  local min_timestamp
948  min_timestamp=$(($(get_uptime_minutes) - $(get_on_core_default "trusted_service_expire_minutes")))
949  # falls die uptime kleiner ist als die Verfallszeit, dann ist ein Test sinnfrei
950  if [ "$min_timestamp" -gt 0 ]; then
951  for service_name in $(get_services "mesh" | filter_services_by_value "source" "trusted"); do
952  timestamp=$(get_service_value "$service_name" "timestamp" 0)
953  # Wurde der Service erst vor kurzem aktualisiert? Sonst loeschen ...
954  [ "$timestamp" -ge "$min_timestamp" ] || delete_service "$service_name"
955  done
956  fi
957  # aktualisiere DNS- und NTP-Dienste
958  apply_changes on-core
959 }
960 
961 
963 ## @brief Durchlaufe alle via STDIN angegebenen Dienste bis mindestens ein Test erfolgreich ist
964 ## @param test_function der Name der zu verwendenden Test-Funktion für einen Dienst (z.B. "verify_vpn_connection")
965 ## @param test_period_minutes Wiederholungsperiode der Dienst-Prüfung
966 ## @param max_fail_attempts Anzahl von Fehlversuchen, bis ein Dienst von "gut" oder "unklar" zu "schlecht" wechselt
967 ## @details Die Diensteanbieter werden in der Reihenfolge ihrer Priorität geprüft.
968 ## Nach dem ersten Durchlauf dieser Funktion sollte typischerweise der nächstgelegene nutzbare Dienst
969 ## als funktionierend markiert sein.
970 ## Falls nach dem Durchlauf aller Dienste keiner positiv getestet wurde (beispielsweise weil alle Zeitstempel zu frisch sind),
971 ## dann wird in jedem Fall der älteste nicht-funktionsfähige Dienst getestet. Dies minimiert die Ausfallzeit im
972 ## Falle einer globalen Nicht-Erreichbarkeit aller Dienstenanbieter ohne auf den Ablauf der Test-Periode warten zu müssen.
973 ## @attention Seiteneffekt: die Zustandsinformationen des getesteten Diensts (Status, Test-Zeitstempel) werden verändert.
975  trap 'error_trap test_openvpn_service_type "$*"' EXIT
976  local test_function="$1"
977  local test_period_minutes="$2"
978  local max_fail_attempts="$3"
979  local service_name
980  local timestamp
981  local status
982  for service_name in $(filter_reachable_services \
985  timestamp=$(get_service_value "$service_name" "status_timestamp" "0")
986  status=$(get_service_value "$service_name" "status")
987  if [ -z "$status" ] || is_timestamp_older_minutes "$timestamp" "$test_period_minutes"; then
988  if "$test_function" "$service_name"; then
989  msg_debug "service $service_name successfully tested"
990  _notify_service_success "$service_name"
991  # wir sind fertig - keine weiteren Tests
992  # Da "return" aufgrund der Pipe nicht die gesamte Funktion beenden
993  # würde, senden wir stattdessen die Markierung fuer "keine Tests
994  # noetig" und beenden die Schleife.
995  printf '%s %s\n' "-1" "$service_name"
996  break
997  else
998  msg_debug "failed to verify $service_name"
999  _notify_service_failure "$service_name" "$max_fail_attempts"
1000  fi
1001  elif uci_is_false "$status"; then
1002  # Junge "kaputte" Dienste sind potentielle Kandidaten fuer einen vorzeitigen Test, falls
1003  # ansonsten kein Dienst positiv getestet wurde.
1004  echo "$timestamp $service_name"
1005  else
1006  # funktionsfaehige "alte" Dienste - es gibt nichts fuer sie zu tun
1007  # Wir sortieren sie nach ganz oben, um bei Existenz eines lauffaehigen Diensts
1008  # keine unnoetigen Tests von nicht-funktionierenden Hosts durchzufuehren.
1009  printf '%s %s\n' "-1" "$service_name"
1010  fi
1011  done | sort -n | while read -r timestamp service_name; do
1012  # Mit dem Zeitstempel "-1" sind funktionierende Dienste markiert. Wir brauchen also keine
1013  # weiteren Tests.
1014  [ "$timestamp" = "-1" ] && return 0
1015  # Hier landen wir nur, falls alle defekten Gateways zu jung fuer einen Test waren und
1016  # gleichzeitig kein Dienst erfolgreich getestet wurde bzw. als erfolgreich gilt.
1017  # Dies stellt sicher, dass nach einer kurzen Nicht-Erreichbarkeit aller Gateways (z.B. olsr-Ausfall)
1018  # relativ schnell wieder ein funktionierender Gateway gefunden wird, obwohl alle Test-Zeitstempel noch recht
1019  # frisch sind.
1020  msg_debug "there is no service to be tested - thus we pick the service with the oldest test timestamp: $service_name"
1021  if "$test_function" "$service_name"; then
1022  _notify_service_success "$service_name"
1023  else
1024  _notify_service_failure "$service_name" "$max_fail_attempts"
1025  fi
1026  # wir wollen nur genau einen Test durchfuehren
1027  break
1028  done
1029 }
1030 
1031 # Ende der Doku-Gruppe
1032 ## @}
get_hop_count_and_etx(host)
Liefere den Hop-Count und den ETX-Wert für einen Zielhost zurück.
Definition: routing.sh:62
uci_delete(uci_path)
Lösche ein UCI-Element.
Definition: uci.sh:46
get_service_log_filename()
Ermittle den Namen der Log-Datei für diesen Dienst. Zusätzliche Details (z.B. "openvpn mtu"...
Definition: services.sh:136
get_services(service_type)
Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind. Falls kein Typ angegben wird...
Definition: services.sh:68
notify_service()
Aktualisiere den Zeitstempel und die Entfernung (etx, service, scheme, host, port, path, protocol, details) eines Dienstes.
Definition: services.sh:18
while read r key value
Definition: core.sh:85
move_service_down(service_name, service_type)
Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach unten.
Definition: services.sh:109
_get_local_bias_for_service()
Ermittle eine reproduzierbare Zahl von 0 bis (LOCAL_BIAS_MODULO-1, service_name) - abhängig von der l...
Definition: services.sh:33
get_service_log_content(service, max_lines)
Lies den Inhalt einer Log-Datei für einen Dienst aus.
Definition: services.sh:143
get_zone_of_device(interface)
Ermittle die Zone eines physischen Netzwerk-Interfaces.
Definition: network.sh:55
filter_reachable_services()
Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die erreichbar sind.
Definition: services.sh:44
set_service_value()
Setzen eines oder mehrerer Werte fuer einen Dienst. Je nach Schluesselname wird der Inhalt in die per...
Definition: services.sh:79
filter_enabled_services()
Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die nicht manuell ausgeblendet wurden...
Definition: services.sh:49
move_service_top(service_name, service_types)
Verschiebe einen Dienst an die Spitze der Dienst-Sortierung.
Definition: services.sh:116
pipe_service_attribute(key, default)
Liefere zu einer Reihe von Diensten ein gewähltes Attribut dieser Dienste zurück. ...
Definition: services.sh:63
update_trusted_services_list()
Hole die vertrauenswürdigen Dienste von signierten Opennet-Quellen.
Definition: services.sh:158
local key
Definition: core.sh:85
_get_file_dict_value(key)
Auslesen eines Werts aus einem Schlüssel/Wert-Eingabestrom.
Definition: core.sh:85
run_cyclic_service_tests(test_function)
Durchlaufe alle via STDIN angegebenen Dienste bis mindestens ein Test erfolgreich ist...
Definition: services.sh:171
sort_services_by_priority()
Sortiere den eingegebenen Strom von Dienstnamen und gib eine nach der Priorität sortierte Liste...
Definition: services.sh:37
filter_services_by_value(key, value)
Definition: services.sh:74
set eu grep root::etc shadow exit if command v chpasswd dev null
Definition: on-password:12
move_service_up(service_name, service_type)
Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach oben.
Definition: services.sh:100
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
Definition: core.sh:15
is_trusted_service_list_outdated()
Ermittle ob mindestens ein Zeitstempel für einen "trusted" Dienst vorhanden ist, der nicht älter als ...
Definition: services.sh:153
set_service_detail(service_name, key, value)
Setze den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts.
Definition: services.sh:130
print_services(service_type)
menschenfreundliche Ausgabe der aktuell angemeldeten Dienste
Definition: services.sh:91
notify_services(source)
Siehe "notify_service" - jedoch effizienter im Umgang mit einer großen Anzahl von Diensten...
Definition: services.sh:23
msg_debug(message)
Debug-Meldungen ins syslog schreiben.
Definition: core.sh:9
set eu on function print_services services log for dir in etc on services d var on services volatile d
Definition: services:13
get_service_value(key, default)
Auslesen eines Werts aus der Service-Datenbank.
Definition: services.sh:86
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
Definition: core.sh:22
shift
Definition: core.sh:85
get_service_detail(service_name, key, default)
Ermittle den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts. ...
Definition: services.sh:123
is_service_routed_via_wan(service_name)
Pruefe ob der Verkehr zum Anbieter des Diensts über ein WAN-Interface verlaufen würde.
Definition: services.sh:148
done
Definition: core.sh:85
get_service_name()
Ermittle en Namen eines Diensts basierend auf den Dienst-Attributen.
Definition: services.sh:7
get_target_route_interface(target)
Ermittle das Netzwerkinterface, über den der Verkehr zu einem Ziel laufen würde.
Definition: routing.sh:26
is_existing_service(service_name)
Prüfe ob ein Service existiert.
Definition: services.sh:28