1 ## @defgroup services Dienste
2 ## @brief Verwaltung von Diensten (z.B. via olsrd-nameservice announciert)
3 # Beginn der Doku-Gruppe
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 # local_port: der lokale Port, der für eine Dienst-Weiterleitung verwendet wird - er sollte über reboots hinweg stabil sein
19 # source: die Quelle des Diensts (olsrd/dns/manual) muss erhalten bleiben, um ihn später löschen zu können
20 PERSISTENT_SERVICE_ATTRIBUTES=
"service scheme host port protocol path uci_dependency file_dependency priority rank offset disabled source local_port"
22 SERVICES_LOG_BASE=/var/log/on-services
32 local name=
"${service}_${scheme}_${host}_${port}_${protocol}"
33 [ -n
"${path#/}" ] && name=
"${name}_${path#/}"
34 echo
"$name" | sed
's/[^A-Za-z0-9_]/_/g'
38 # Aktualisiere den Zeitstempel und die Entfernung (etx) eines Dienstes
40 trap
"error_trap notify_service '$*'" $GUARD_TRAPS
49 local service_name=$(get_service_name
"$service" "$scheme" "$host" "$port" "$protocol" "$path")
51 # diese Attribute sind Bestandteil des Namens und aendern sich eigentlich nicht
52 set_service_value
"$service_name" "service" "$service"
53 set_service_value
"$service_name" "scheme" "$scheme"
54 set_service_value
"$service_name" "host" "$host"
55 set_service_value
"$service_name" "port" "$port"
56 set_service_value
"$service_name" "protocol" "$protocol"
57 set_service_value
"$service_name" "path" "$path"
59 # dies sind die flexiblen Attribute
60 set_service_value
"$service_name" "details" "$details"
61 set_service_value
"$service_name" "timestamp" "$(get_time_minute)"
62 set_service_value
"$service_name" "source" "$source"
67 ## @fn update_service_routing_distance()
68 ## @brief Aktualisiere Routing-Entfernung und Hop-Count eines Dienst-Anbieters
69 ## @param service_name der zu aktualisierende Dienst
70 ## @details Beide Dienst-Werte werden gelöscht, falls der Host nicht route-bar sein sollte.
71 ## Diese Funktion sollte regelmäßig für alle Hosts ausgeführt werden.
73 trap
"error_trap update_service_routing_distance '$*'" $GUARD_TRAPS
74 local service_name=
"$1"
78 set_service_value
"$service_name" "distance" "$etx"
79 set_service_value
"$service_name" "hop_count" "$hop"
84 ## @fn is_existing_service()
85 ## @brief Prüfe ob ein Service existiert
86 ## @param service_name der Name des Diensts
87 ## @returns exitcode=0 falls der Dienst existiert
89 local service_name=
"$1"
90 [ -n
"$service_name" -a -e
"$PERSISTENT_SERVICE_STATUS_DIR/$service_name" ] &&
return 0
91 trap
"" $GUARD_TRAPS &&
return 1
95 # Ermittle eine reproduzierbare Zahl von 0 bis (LOCAL_BIAS_MODULO-1) - abhaengig von der lokalen IP und der IP der Gegenstelle.
96 # Dadurch koennen wir beim Sortieren strukturelle Ungleichgewichte (z.B. durch alphabetische Sortierung) verhindern.
97 _get_local_bias_for_host() {
99 # Die resultierende host_number darf nicht zu gross sein (z.B. mit Exponentendarstellung),
100 # da andernfalls awk die Berechnung fehlerhaft durchführt.
101 local host_number=$(echo
"$ip$(get_local_bias_number)" | md5sum | sed
's/[^0-9]//g')
102 # Laenge von
'host_number' reduzieren (die Berechnung schlaegt sonst fehl)
103 # Wir fuegen die 1 an den Beginn, um die Interpretation als octal-Zahl zu verhindern (fuehrende Null).
104 echo $(( 1${host_number:0:6} % LOCAL_BIAS_MODULO))
108 # Ermittle die Service-Prioritaet eines Dienstes.
109 # Der Wert ist beliebig und nur im Vergleich mit den Prioritaeten der anderen Dienste verwendbar.
110 # Als optionaler zweiter Parameter kann die Sortierung uebergeben werden. Falls diese nicht uebergeben wurde,
111 # wird die aktuell konfigurierte Sortierung benutzt.
112 # Sollte ein Dienst ein "priority"-Attribut tragen, dann wird die uebliche Dienst-Sortierung aufgehoben
113 # und lediglich "priority" (und gegebenenfalls separat "offset") beachtet.
114 get_service_priority() {
115 trap
"error_trap get_service_priority '$*'" $GUARD_TRAPS
116 local service_name=
"$1"
117 local sorting=
"${2:-}"
120 # priority wird von nicht-olsr-Clients verwendet (z.B. mesh-Gateways mit oeffentlichen IPs)
121 local base_priority=$(
122 if [ -n
"$priority" ]; then
123 # dieses Ziel traegt anscheinend keine Routing-Metrik
125 echo
"$((priority + offset))"
127 # wir benoetigen Informationen fuer Ziele mit Routing-Metriken
128 # aus Performance-Gruenden kommt die Sortierung manchmal von aussen
129 [ -z
"$sorting" ] && sorting=$(get_service_sorting)
130 if [
"$sorting" =
"etx" -o
"$sorting" =
"hop" ]; then
131 get_distance_with_offset
"$service_name" "$sorting"
132 elif [
"$sorting" =
"manual" ]; then
135 msg_info "Unknown sorting method for services: $sorting"
139 local host_bias=$(_get_local_bias_for_host
"$(get_service_value "$service_name
" "host
")")
140 echo $(( ${base_priority:-$DEFAULT_SERVICE_RANK} * 1000 + host_bias))
144 get_distance_with_offset() {
145 trap
"error_trap get_distance_with_offset '$*'" $GUARD_TRAPS
146 local service_name=
"$1"
147 local sorting=
"${2:-}"
148 # aus Performance-Gruenden wird manchmal das sorting von aussen vorgegeben
149 [ -z
"$sorting" ] && sorting=$(get_service_sorting)
152 [ -z
"$distance" ] &&
return 0
154 [ -z
"$offset" ] && offset=0
155 if [
"$sorting" =
"etx" ]; then
156 base_value=
"$distance"
157 elif [
"$sorting" =
"hop" ]; then
160 msg_debug "get_distance_with_offset: sorting '$sorting' not implemented"
162 [ -n
"$base_value" ] && echo
"$base_value" "$offset" | awk
'{ print $1 + $2 }'
167 set_service_sorting() {
168 trap
"error_trap set_service_sorting '$*'" $GUARD_TRAPS
169 local new_sorting=
"$1"
170 local old_sorting=$(get_service_sorting)
171 [
"$old_sorting" =
"$new_sorting" ] &&
return 0
172 [
"$new_sorting" !=
"manual" -a
"$new_sorting" !=
"hop" -a
"$new_sorting" !=
"etx" ] && \
173 msg_info "Warning: Ignoring unknown sorting method: $new_sorting" && \
174 trap
"" $GUARD_TRAPS &&
return 1
175 uci
set "on-core.settings.service_sorting=$new_sorting"
176 apply_changes on-core
180 # Liefere die aktuelle Sortier-Methode.
181 # Falls eine ungueltige Sortier-Methode gesetzt ist, wird diese auf die Standard-Sortierung zurueckgesetzt.
182 # Die Ausgabe dieser Funktion ist also in jedem Fall eine gueltige Sortier-Methode.
183 get_service_sorting() {
184 trap
"error_trap get_service_sorting '$*'" $GUARD_TRAPS
185 local sorting=$(uci_get
"on-core.settings.service_sorting")
186 if [
"$sorting" =
"manual" -o
"$sorting" =
"hop" -o
"$sorting" =
"etx" ]; then
187 # zulaessige Sortierung
190 # unbekannte Sortierung: dauerhaft setzen
191 # keine Warnung falls die Sortierung nicht gesetzt wurde
192 [ -n
"$sorting" ] &&
msg_info "Warning: coercing unknown sorting method: $sorting -> $DEFAULT_SERVICE_SORTING"
193 uci
set "on-core.settings.service_sorting=$DEFAULT_SERVICE_SORTING"
194 echo -n
"$DEFAULT_SERVICE_SORTING"
200 sort_services_by_priority() {
201 trap
"error_trap sort_services_by_priority '$*'" $GUARD_TRAPS
204 local sorting=$(get_service_sorting)
205 while read service_name;
do
206 priority=$(get_service_priority
"$service_name" "$sorting")
207 # keine Entfernung (nicht erreichbar) -> ganz nach hinten sortieren (schmutzig, aber wohl ausreichend)
208 [ -z
"$priority" ] && priority=999999999999999
209 echo
"$priority" "$service_name"
210 done | sort -n | awk
'{print $2}'
214 ## @fn sort_services_by()
215 ## @brief Sortiere den eingegebenen Strom von Dienstnamen und gib eine sortierte Liste entsprechende des Arguments aus.
216 ## @param sort_key Der Dienst-Wert, anhand dessen die Auswertung und Sortierung stattfinden soll.
218 trap
"error_trap sort_services_by '$*'" $GUARD_TRAPS
221 while read service_name;
do
223 echo
"$value" "$service_name"
224 done | sort -n | cut -f 2- -
d " "
229 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die erreichbar sind.
230 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an die Standardausgabe
231 ## weitergeleitet, falls der Dienst erreichbar sind. "Erreichbarkeit" gilt als erreicht, wenn
232 ## der Host via olsr route-bar ist oder wenn er als DNS-entdeckter Dienst eine Priorität hat
233 ## oder wenn er manuell hinzugefügt wurde.
236 while read service_name;
do
237 { [ -n
"$(get_service_value "$service_name
" "distance
")" ] \
238 || [ -n
"$(get_service_value "$service_name
" "priority
")" ] \
239 || [
"$(get_service_value "$service_name
" "source
")" =
"manual" ]
240 } && echo
"$service_name"
246 ## @fn filter_enabled_services()
247 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die nicht manuell ausgeblendet wurden.
248 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an
249 ## die Standardausgabe weitergeleitet, falls der Dienst nicht abgewählt wurde.
253 while read service_name;
do
255 [ -n
"$disabled" ] && uci_is_true
"$disabled" &&
continue
262 ## @brief Liefere zu einer Reihe von Diensten ein gewähltes Attribut dieser Dienste zurück.
263 ## @param key Der Name eines Dienst-Attributs
264 ## @param default Der Standard-Wert wird anstelle des Attribut-Werts verwendet, falls dieser leer ist.
265 ## @details Die Dienstenamen werden via Standardeingabe erwartet. Auf der Standardausgabe wird für
266 ## einen Dienst entweder ein Wert oder nichts ausgeliefert. Keine Ausgabe erfolgt, falls der
267 ## Wert des Dienste-Attributs leer ist. Bei der Eingabe von mehreren Diensten werden also
268 ## eventuell weniger Zeilen ausgegeben, als eingelesen wurden.
269 ## Falls der optionale zweite 'default'-Parameter nicht leer ist, dann wird bei einem leeren
270 ## Ergebnis stattdessen dieser Wert ausgegeben. Der 'default'-Parameter sorgt somit dafür, dass
271 ## die Anzahl der eingelesenen Zeilen in jedem Fall mit der Anzahl der ausgegebenen Zeilen
275 local
default=
"${2:-}"
278 while read service_name;
do
280 [ -z
"$value" ] && value=
"$default"
281 [ -n
"$value" ] && echo
"$value" ||
true
287 ## @param service_type (optional) ein Service-Typ
288 ## @brief Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind.
289 ## Falls kein Typ angegben wird, dann werden alle Dienste ungeachtet ihres Typs ausgegeben.
291 trap
"error_trap get_services '$*'" $GUARD_TRAPS
294 # alle Dienste ausgeben
295 # kein Dienste-Verzeichnis? Keine Ergebnisse ...
296 [ -e
"$PERSISTENT_SERVICE_STATUS_DIR" ] ||
return 0
297 find
"$PERSISTENT_SERVICE_STATUS_DIR" -type f -size +1
c -print0 \
298 | xargs -0 -r -n 1 basename \
299 |
if [ $# -gt 0 ]; then
307 ## @fn filter_services_by_value()
308 ## @param key ein Schlüssel
309 ## @param value ein Wert
310 ## @details Als Parameter kann ein "key/value"-Schluesselpaar angegeben werden.
311 ## Nur diejenigen Dienste, auf die diese Bedingung zutrifft, werden zurueckgeliefert.
316 while read service_name;
do
317 [
"$value" =
"$(get_service_value "$service_name
" "$key
")" ] && echo
"$service_name" ||
true
322 # Setzen eines Werts fuer einen Dienst.
323 # Je nach Schluesselname wird der Inhalt in die persistente uci- oder
324 # die volatile tmpfs-Datenbank geschrieben.
325 set_service_value() {
326 local service_name=
"$1"
330 [ -z
"$service_name" ] \
331 &&
msg_info "Error: no service given for attribute change ($attribute=$value)" \
332 && trap
"" $GUARD_TRAPS &&
return 1
333 if echo
"$PERSISTENT_SERVICE_ATTRIBUTES" | grep -q -w
"$attribute"; then
334 dirname=
"$PERSISTENT_SERVICE_STATUS_DIR"
336 dirname=
"$VOLATILE_SERVICE_STATUS_DIR"
339 _set_file_dict_value
"$dirname/$service_name" "$attribute" "$value"
343 ## @fn get_service_value()
344 ## @brief Auslesen eines Werts aus der Service-Datenbank.
345 ## @param key Der Name eines Dienst-Attributs
346 ## @param default Der Standard-Wert wird anstelle des Attribut-Werts verwendet, falls dieser leer ist.
347 ## @details Falls das Attribut nicht existiert, wird ein leerer Text zurückgeliefert.
348 ## Es gibt keinen abschließenden Zeilenumbruch.
350 local service_name=
"$1"
352 local
default=
"${3:-}"
355 [ -z
"$service_name" ] \
356 &&
msg_info "Error: no service given for attribute request ('$attribute')" \
357 && trap
"" $GUARD_TRAPS &&
return 1
358 value=$(
_get_file_dict_value "$attribute" "$PERSISTENT_SERVICE_STATUS_DIR/$service_name" "$VOLATILE_SERVICE_STATUS_DIR/$service_name")
359 [ -n
"$value" ] && echo -n
"$value" || echo -n
"$default"
364 # Liefere die Suffixe aller Schluessel aus der Service-Attribut-Datenbank,
365 # die mit dem gegebenen Praefix uebereinstimmen.
366 get_service_attributes() {
367 _get_file_dict_keys
"$PERSISTENT_SERVICE_STATUS_DIR/$1" "$VOLATILE_SERVICE_STATUS_DIR/$1"
371 ## @fn print_services()
372 ## @brief menschenfreundliche Ausgabe der aktuell angemeldeten Dienste
373 ## @param service_type (optional) ein Service-Type
374 ## @returns Ausgabe der bekannten Dienste (für Menschen - nicht parsebar)
376 trap
"error_trap print_services '$*'" $GUARD_TRAPS
382 get_service_attributes
"$service_name" |
while read attribute;
do
384 echo -e
"\t$attribute=$value"
391 # Speichere das angegebene uci-Praefix als eine von einem Service abhaengige Konfiguration.
392 # Dies ist sinnvoll fuer abgeleitete VPN-Konfigurationen oder Portweiterleitungen.
393 # Schnittstelle: siehe _add_service_dependency
394 service_add_uci_dependency() {
395 _add_service_dependency
"uci_dependency" "$@"
399 # Speichere einen Dateinamen als Abhaengigkeit eines Service.
400 # Dies ist sinnvoll fuer Dateien, die nicht mehr gebraucht werden, sobald der Service entfernt wird.
401 # Schnittstelle: siehe _add_service_dependency
402 service_add_file_dependency() {
403 _add_service_dependency
"file_dependency" "$@"
407 # Speichere eine Abhaengigkeit fuer einen Dienst.
408 # Parameter: Service-Name
409 # Parameter: textuelle Darstellung einer Abhaengigkeit (ohne Leerzeichen)
410 _add_service_dependency() {
411 trap
"error_trap _add_service_dependency '$*'" $GUARD_TRAPS
412 local dependency=
"$1"
413 local service_name=
"$2"
418 # schon vorhanden -> fertig
419 [
"$dep" =
"$token" ] &&
return 0 ||
true
421 if [ -z
"$deps" ]; then
426 set_service_value
"$service_name" "$dependency" "$deps"
430 # Entferne alle mit diesem Service verbundenen Konfigurationen (inkl. Rekonfiguration von firewall, etc.).
431 cleanup_service_dependencies() {
432 trap
"error_trap cleanup_service_dependencies '$*'" $GUARD_TRAPS
433 local service_name=
"$1"
441 # uci-Sektionen loeschen
444 # gib die oberste config-Ebene aus - fuer spaeteres "apply_changes"
445 echo
"$dep" | cut -f 1 -
d .
446 done | sort | uniq |
while read branch;
do
447 apply_changes
"$branch"
449 set_service_value
"$service_name" "uci_dependency" ""
453 get_service_description() {
454 trap
"error_trap get_service_description '$*'" $GUARD_TRAPS
455 local service_name=
"$1"
461 echo
"$scheme://$host:$port ($proto) $details"
466 trap
"error_trap delete_service '$*'" $GUARD_TRAPS
467 local service_name=
"$1"
468 [ -z
"$service_name" ] &&
msg_info "Error: no service given for deletion" && trap
"" $GUARD_TRAPS &&
return 1
469 cleanup_service_dependencies
"$service_name"
470 rm -f
"$PERSISTENT_SERVICE_STATUS_DIR/$service_name"
471 rm -f
"$VOLATILE_SERVICE_STATUS_DIR/$service_name"
475 # Durchlaufe alle Dienste und verteile Rangziffern ohne Doppelung an alle Dienste.
476 # Die Dienst-Arten (z.B. DNS und UGW) werden dabei nicht beachtet.
477 # Die Rangziffern sind anschliessend streng monoton aufsteigend - beginnend bei 1.
478 # Falls aktuell die manuelle Sortierung aktiv ist, wird deren Reihenfolge beibehalten.
479 # Ansonsten basiert die Vergabe der Rangziffern auf der Reihenfolge entsprechend der aktuell aktiven Sortierung.
480 _distribute_service_ranks() {
483 get_services | sort_services_by_priority |
while read service_name;
do
484 set_service_value
"$service_name" "rank" "$index"
490 ## @fn move_service_up()
491 ## @brief Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach oben
492 ## @param service_name der zu verschiebende Dienst
493 ## @param service_type der Service-Typ innerhalb derer Mitglieder die Verschiebung stattfinden soll
494 ## @details Für verschiedene Sortier-Modi hat dies verschiedene Auswirkungen:
495 ## * manual: Verschiebung vor den davorplatzierten Dienst desselben Typs
496 ## * etx/hop: Reduzierung des Offsets um eins
497 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste nach unten.
499 trap
"error_trap move_service_up '$*'" $GUARD_TRAPS
500 local service_name=
"$1"
502 local sorting=$(get_service_sorting)
504 local current_service
506 if [
"$sorting" =
"hop" -o
"$sorting" =
"etx" ]; then
507 # reduziere den Offset um eins
509 temp=$(echo
"$temp" | awk
'{ print $1 - 1 }')
510 set_service_value
"$service_name" "offset" "$temp"
511 elif [
"$sorting" =
"manual" ]; then
512 get_services "$@" | sort_services_by_priority |
while read current_service;
do
513 if [
"$current_service" =
"$service_name" ]; then
514 if [ -z
"$prev_service" ]; then
515 # es gibt keinen Dienst oberhalb des zu verschiebenden
518 # wir verschieben den Dienst ueber den davor liegenden
520 # ziehe einen halben Rang ab
521 temp=$(echo
"$temp" | awk
'{ print $1 - 0.5 }')
522 set_service_value
"$service_name" "rank" "$temp"
523 # erneuere die Rang-Vergabe
524 _distribute_service_ranks
529 prev_service=
"$current_service"
532 msg_info "Warning: [move_service_up] sorting method is not implemented: $sorting"
537 ## @fn move_service_down()
538 ## @brief Verschiebe einen Dienst in der Dienst-Sortierung um eine Stufe nach unten
539 ## @param service_name der zu verschiebende Dienst
540 ## @param service_type der Service-Typ innerhalb derer Mitglieder die Verschiebung stattfinden soll
541 ## @details Für verschiedene Sortier-Modi hat dies verschiedene Auswirkungen:
542 ## * manual: Verschiebung hinter den dahinterliegenden Dienst desselben Typs
543 ## * etx/hop: Erhöhung des Offsets um eins
544 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste nach unten.
546 trap
"error_trap move_service_down '$*'" $GUARD_TRAPS
547 local service_name=
"$1"
549 local sorting=$(get_service_sorting)
551 local current_service
553 if [
"$sorting" =
"hop" -o
"$sorting" =
"etx" ]; then
554 # reduziere den Offset um eins
556 temp=$(echo
"$temp" | awk
'{ print $1 + 1 }')
557 set_service_value
"$service_name" "offset" "$temp"
558 elif [
"$sorting" =
"manual" ]; then
559 get_services "$@" | sort_services_by_priority |
while read current_service;
do
560 if [
"$prev_service" =
"$service_name" ]; then
561 # wir verschieben den Dienst hinter den danach liegenden
563 # fuege einen halben Rang hinzu
564 temp=$(echo
"$temp" | awk
'{ print $1 + 0.5 }')
565 set_service_value
"$service_name" "rank" "$temp"
566 # erneuere die Rang-Vergabe
567 _distribute_service_ranks
571 prev_service=
"$current_service"
574 msg_info "Warning: [move_service_down] sorting method is not implemented: $sorting"
579 ## @fn move_service_top()
580 ## @brief Verschiebe einen Dienst an die Spitze der Dienst-Sortierung
581 ## @param service_name der zu verschiebende Dienst
582 ## @param service_types ein oder mehrere Dienst-Typen, auf die die Ermittlung der Dienst-Liste begrenzt werden soll (z.B. "gw")
583 ## @details Der Dienst steht anschließend direkt vor dem bisher führenden Dienst der ausgewählten Typen (falls angegeben).
584 ## Falls keine Dienst-Typen angegeben sind, bewegt der Dienst sich in der globalen Liste an die Spitze.
586 trap
"error_trap move_service_top '$*'" $GUARD_TRAPS
587 local service_name=
"$1"
589 local top_service=$(
get_services "$@" | sort_services_by_priority | head -1)
590 local sorting=$(get_service_sorting)
597 # kein top-Service oder wir sind bereits ganz oben -> Ende
598 [ -z
"$top_service" -o
"$top_service" =
"$service_name" ] &&
return 0
599 if [
"$sorting" =
"hop" -o
"$sorting" =
"etx" ]; then
600 top_distance=$(get_distance_with_offset
"$top_service" "$sorting")
601 our_distance=$(get_distance_with_offset
"$service_name" "$sorting")
602 [ -z
"$our_distance" ] &&
msg_info "Failed to move unreachable service ('$service_name') to top" &&
return 0
604 # wir verschieben unseren Offset, auf dass wir knapp ueber
"top" stehen
605 new_offset=$(echo | awk
"{ print $current_offset + int($top_distance - $our_distance) - 1 }")
606 set_service_value
"$service_name" "offset" "$new_offset"
607 elif [
"$sorting" =
"manual" ]; then
608 # setze den Rang des Dienstes auf den top-Dienst minus 0.5
610 new_rank=$(echo
"$top_rank" | awk
'{ print $1 - 0.5 }')
611 set_service_value
"$service_name" "rank" "$new_rank"
612 # erneuere die Rang-Vergabe
613 _distribute_service_ranks
615 msg_info "Warning: [move_service_top] sorting method is not implemented: $sorting"
620 ## @fn get_service_detail()
621 ## @brief Ermittle den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts
622 ## @param service_name Name eines Diensts
623 ## @param key Name des Schlüssels
624 ## @param default dieser Wert wird zurückgeliefert, falls der Schlüssel nicht gefunden wurde
625 ## @returns den ermittelten Wert aus dem Schlüssel-Wert-Paar
627 local service_name=
"$1"
629 local
default=
"${3:-}"
630 local value=$(
get_service_value "$service_name" "details" | get_from_key_value_list
"$key" ":")
631 [ -n
"$value" ] && echo -n
"$value" || echo -n
"$default"
637 ## @brief Setze den Wert eines Schlüssel-Wert-Paars im "details"-Attribut eines Diensts
638 ## @param service_name Name eines Diensts
639 ## @param key Name des Schlüssels
640 ## @param value der neue Wert
641 ## @details Ein leerer Wert löscht das Schlüssel-Wert-Paar.
643 local service_name=
"$1"
646 local new_details=$(
get_service_value "$service_name" "details" | replace_in_key_value_list
"$key" ":" "$value")
647 set_service_value
"$service_name" "details" "$new_details"
652 # Liefere eine Semikolon-separierte Liste von Service-Eigenschaften zurueck.
653 # Jede Eigenschaft wird folgendermassen ausgedrueckt:
654 # type|source|key[|
default]
655 # Dabei sind folgende Inhalte moeglich:
656 # type: Rueckgabetyp (
string, number,
bool)
657 # source: Quelle der Informationen (value, detail, function, id)
658 # key: Name des Werts, des Details oder der Funktion
659 # default: Standardwert, falls das Ergebnis leer sein sollte
660 # Wahrheitswerte werden als "true" oder "false" zurueckgeliefert. Alle anderen Rueckgabetypen bleiben unveraendert.
661 # Das Ergebnis sieht folgendermassen aus:
662 # SERVICE_NAME;RESULT1;RESULT2;...
663 get_service_as_csv() {
664 local service_name=
"$1"
674 # Abbruch mit Fehler bei unbekanntem Dienst
676 echo -n
"$service_name"
677 for specification in
"$@";
do
678 rtype=$(echo
"$specification" | cut -f 1 -
d "|")
679 source=$(echo
"$specification" | cut -f 2 -
d "|")
680 key=$(echo
"$specification" | cut -f 3 -
d "|")
681 default=$(echo
"$specification" | cut -f 4- -
d "|")
682 # Ermittlung des Funktionsaufrufs
683 if [
"$source" =
"function" ]; then
684 if [
"$rtype" =
"bool" ]; then
685 "$key" "$service_name" && value=
"true" || value=
"false"
687 value=$(
"$key" "$service_name")
690 if [
"$source" =
"value" ]; then
692 elif [
"$source" =
"detail" ]; then
695 msg_info "Unknown service attribute requested: $specification"
696 echo -n
"${separator}"
699 [ -z
"$value" ] && [ -n
"$default" ] && value=
"$default"
700 if [
"$rtype" =
"bool" ]; then
701 # Pruefung auf wahr/falsch
702 value=$(uci_is_true
"$value" && echo
"true" || echo
"false")
705 echo -n
"${separator}${value}"
707 # mit Zeilenumbruch abschliessen
713 ## @brief Ermittle den Namen der Log-Datei für diesen Dienst. Zusätzliche Details (z.B. "openvpn mtu") sind möglich.
714 ## @param service Name eines Dienstes.
715 ## @param other Eine beliebige Anzahl weiterer Parameter ist erlaubt: diese erweitern den typischen Log-Dateinamen für diesen Dienst.
716 ## @details Die Funktion stellt sicher, dass das Verzeichnis der ermittelten Log-Datei anschließend existiert.
718 local service_name=
"$1"
720 local filename=
"$service_name"
721 while [ $# -gt 0 ];
do
722 filename=
"${filename}.$1"
725 local full_filename=
"$SERVICES_LOG_BASE/$(get_safe_filename "$filename
").log"
726 mkdir -
p "$(dirname "$full_filename
")"
727 echo -n
"$full_filename"
731 ## @fn update_service_wan_status()
732 ## @brief Pruefe ob der Verkehr zum Anbieter des Diensts über ein WAN-Interface verlaufen würde. Das "wan_status"-Flag des Diensts wird daraufhin aktualisiert.
733 ## @param service_name der Name des Diensts
734 ## @details Diese Operation dauert ca. 5s, da zusätzlich die Ping-Zeit des Zielhosts ermittelt wird.
736 trap
"error_trap ugw_update_wan_status '$*'" $GUARD_TRAPS
737 local service_name=
"$1"
742 if is_device_in_zone
"$outgoing_device" "$ZONE_WAN"; then
743 set_service_value
"$service_name" "wan_status" "true"
744 ping_time=$(get_ping_time
"$host")
745 set_service_value
"$service_name" "wan_ping" "$ping_time"
746 msg_debug "target '$host' routing through wan device: $outgoing_device"
747 msg_debug "average ping time for $host: ${ping_time}ms"
749 outgoing_zone=$(get_zone_of_device
"$outgoing_device")
750 # ausfuehrliche Erklaerung, falls das Routing zuvor noch akzeptabel war
751 uci_is_true
"$(get_service_value "$service_name
" "wan_status
" "false")" \
752 &&
msg_info "Routing switched away from WAN interface to '$outgoing_device'"
753 msg_debug "warning: target '$host' is routed via interface '$outgoing_device' (zone '$outgoing_zone') instead of the expected WAN zone ($ZONE_WAN)"
754 set_service_value
"$service_name" "wan_status" "false"
755 set_service_value
"$service_name" "wan_ping" ""
759 # Ende der Doku-Gruppe