1 ## @defgroup on-service-relay Dienst-Weiterleitungen
2 # Beginn der Doku-Gruppe
5 ## für die Kompatibilität mit Firmware vor v0.5
6 UGW_LOCAL_SERVICE_PORT_LEGACY=1600
7 DEFAULT_MESH_OPENVPN_PORT=1602
8 ## falls mehr als ein GW-Dienst weitergereicht wird, wird dieser Port und die folgenden verwendet
9 SERVICE_RELAY_LOCAL_RELAY_PORT_START=5100
12 # Pruefung ob ein lokaler Port bereits fuer einen ugw-Dienst weitergeleitet wird
13 _is_local_service_relay_port_unused() {
17 [ -n
"$collisions" ] && trap
"" $GUARD_TRAPS &&
return 1
18 # keine Kollision entdeckt
23 # Liefere den Port zurueck, der einer Dienst-Weiterleitung lokal zugewiesen wurde.
24 # Falls noch kein Port definiert ist, dann waehle einen neuen Port.
25 # Parameter: config_name
26 pick_local_service_relay_port() {
27 trap
"error_trap pick_local_service_relay_port '$*'" $GUARD_TRAPS
28 local service_name=
"$1"
31 # falls unbelegt: suche einen unbenutzten lokalen Port
32 if [ -z
"$port" ]; then
33 # fuer IGW-Verbindungen: belege zuerst den alten Standard-Port (fuer alte Clients)
34 if [
"$(get_service_value "$service_name
" "service
")" =
"gw" ]; then
35 _is_local_service_relay_port_unused
"$UGW_LOCAL_SERVICE_PORT_LEGACY" \
36 && port=
"$UGW_LOCAL_SERVICE_PORT_LEGACY"
40 if [ -z
"$port" ]; then
41 port=
"$SERVICE_RELAY_LOCAL_RELAY_PORT_START"
42 until _is_local_service_relay_port_unused
"$port";
do
46 set_service_value
"$service_name" "local_relay_port" "$port"
51 ## @fn update_relay_firewall_rules
52 ## @brief Erstelle die Liste aller Firewall-Regeln fuer Service-Relay-Weiterleitungen neu.
53 ## @details Diese Funktion wird als Teil des Firewall-Reload-Prozess und nach Service-Relay-Aenderungen
55 update_relay_firewall_rules() {
56 trap
"error_trap update_relay_firewall_rules '$*'" $GUARD_TRAPS
62 local dnat_chain=
"on_service_relay_dnat"
63 local parent_dnat_chain=
"prerouting_${ZONE_MESH}_rule"
64 local tos_chain=
"on_service_relay_tos"
65 local parent_tos_chain=
"PREROUTING"
66 main_ip=$(get_main_ip)
67 # neue Chains erzeugen
68 iptables -t nat --
new-chain
"$dnat_chain" 2>/dev/
null || iptables -t nat --flush
"$dnat_chain"
69 iptables -t
mangle --
new-chain
"$tos_chain" 2>/dev/
null || iptables -t
mangle --flush
"$tos_chain"
70 # Verweis auf die neue Chain erzeugen
71 iptables -t nat --check
"$parent_dnat_chain" -j
"$dnat_chain" 2>/dev/
null \
72 || iptables -t nat --insert
"$parent_dnat_chain" -j
"$dnat_chain"
73 iptables -t
mangle --check
"$parent_tos_chain" -j
"$tos_chain" 2>/dev/
null \
74 || iptables -t
mangle --insert
"$parent_tos_chain" -j
"$tos_chain"
75 # DNAT- und TOS-Chain fuellen
76 get_services | filter_relay_services |
while read service;
do
77 is_service_relay_possible
"$service" ||
continue
83 iptables -t nat -A
"$dnat_chain" --destination
"$main_ip" --protocol
"$protocol" --dport
"$local_port" \
84 -j DNAT --to-destination
"${target_ip}:${port}"
85 # falls on-openvpn vorhanden ist, wollen wir vermeiden, dass mesh-Tunnel ueber den Internet-Tunnel laufen
86 [ -z
"${TOS_NON_TUNNEL:-}" ] || iptables -t
mangle -A
"$tos_chain" --destination
"$main_ip" \
87 --protocol
"$protocol" --dport
"$local_port" -j TOS --set-tos
"$TOS_NON_TUNNEL"
93 _get_service_relay_olsr_announcement_prefix() {
94 trap
"error_trap _get_service_relay_olsr_announcement_prefix '$*'" $GUARD_TRAPS
95 local service_name=
"$1"
102 main_ip=$(get_main_ip)
105 service_type=
"${service_type#$RELAYABLE_SERVICE_PREFIX}"
108 port=$(pick_local_service_relay_port
"$service_name")
110 # announce the service
111 echo
"${scheme}://${main_ip}:${port}|${protocol}|${service_type}"
115 ## @fn get_service_relay_olsr_announcement()
116 ## @brief Ermittle den oder die OLSR-Nameservice-Announcements, die zu dem Dienst gehoeren.
117 get_service_relay_olsr_announcement() {
118 trap
"error_trap get_service_relay_olsr_announcement '$*'" $GUARD_TRAPS
119 local service_name=
"$1"
120 local announce_unique
122 announce_unique=$(_get_service_relay_olsr_announcement_prefix
"$service_name")
123 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
124 uci_get_list "${uci_prefix}.service" | awk
'{ if ($1 == "'$announce_unique
'") print $0; }'
128 ## @fn announce_olsr_service_relay()
129 ## @brief Verkuende das lokale Relay eines öffentlichen Dienstes inkl. Geschwindigkeitsdaten via olsr nameservice.
130 ## @param service_name Name des zu veröffentlichenden Diensts
131 ## @attention Anschließend muss die uci-Sektion 'olsrd' committed werden.
132 announce_olsr_service_relay() {
133 trap
"error_trap announce_olsr_service_relay '$*'" $GUARD_TRAPS
134 local service_name=
"$1"
136 local service_details
137 service_unique=$(_get_service_relay_olsr_announcement_prefix
"$service_name")
138 # das
'service_name'-Detail wird fuer die anschliessende Beraeumung (firewall-Regeln usw.) verwendet
139 # nur nicht-leere Attribute werden geschrieben
140 service_details=$(
while read
key value;
do [ -z
"$value" ] &&
continue; echo
"$key:$value";
done <<EOF
147 # Zeilenumbrueche durch Leerzeichen ersetzen, abschliessendes Leerzeichen entfernen
148 service_details=$(echo
"$service_details" | tr
'\n' ' ' | sed
's/ $//')
149 # loesche alte Dienst-Announcements mit demselben Prefix
153 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
154 get_service_relay_olsr_announcement
"$service_name" |
while read this_unique this_details;
do
155 # der Wert ist bereits korrekt - wir koennen abbrechen
156 [
"$this_details" =
"$service_details" ] &&
break
157 # der Wert ist falsch: loeschen und am Ende neu hinzufuegen
158 msg_debug "Deleting outdated service-relay announcement: $service_unique $this_details"
159 uci_delete_list "${uci_prefix}.service" "$service_unique $this_details"
161 # falls keine Treffer gibt, fuegen wir ein neues Announcement hinzu
162 if [ -z
"$(get_service_relay_olsr_announcement "$service_name
")" ]; then
163 msg_debug "Adding new service-relay announcement: $service_unique $service_details"
164 uci_add_list "${uci_prefix}.service" "$service_unique $service_details"
169 ## @fn get_olsr_relay_service_name_from_description()
170 ## @brief Ermittle den Dienstnamen, der zu einer olsr-Relay-Service-Definition gehoert.
171 get_olsr_relay_service_name_from_description() {
172 trap
"error_trap get_olsr_relay_service_name_from_description '$*'" $GUARD_TRAPS
173 local service_description=
"$1"
177 fields=$(echo
"$service_description" | parse_olsr_service_descriptions)
178 port=$(echo
"$fields" | cut -f 3)
179 service_type=$(echo
"$fields" | cut -f 6)
184 # olsr-Nameservice-Beschreibungen entfernen falls der dazugehoerige Dienst nicht mehr relay-tauglich ist
185 deannounce_unused_olsr_service_relays() {
186 # wir erwarten einen ausführbaren Testnamen
187 local test_for_activity=
"$1"
188 local service_description
191 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
192 uci_get_list "${uci_prefix}.service" |
while read service_description;
do
193 # unbenutzte Eintraege entfernen
194 service_name=$(get_olsr_relay_service_name_from_description
"$service_description")
195 [ -z
"$service_name" ] &&
msg_info "Failed to parse olsr service description: $service_description" &&
continue
196 "$test_for_activity" "$service_name" &&
continue
203 ## @fn is_service_relay_possible()
204 ## @brief Pruefe ob ein Relay-Dienst aktiviert (nicht "disabled") ist und ob das WAN-Routing korrekt ist.
205 is_service_relay_possible() {
206 trap
"error_trap is_service_relay_possible '$*'" $GUARD_TRAPS
207 local service_name=
"$1"
211 uci_is_true
"$disabled" && trap
"" $GUARD_TRAPS &&
return 1
213 uci_is_false
"$wan_routing" && trap
"" $GUARD_TRAPS &&
return 1
218 ## @fn update_service_relay_status()
219 ## @brief Pruefe regelmaessig, ob Weiterleitungen für alle bekannten durchgereichten Diensten existieren.
220 ## @details Fehlende Weiterleitungen oder olsr-Announcements werden angelegt.
221 update_service_relay_status() {
222 trap
"error_trap update_service_relay_status '$*'" $GUARD_TRAPS
226 get_services | filter_relay_services |
while read service_name;
do
227 # WAN-Routing pruefen und aktualisieren
229 set_service_value
"$service_name" "wan_status" "$wan_status"
230 is_service_relay_possible
"$service_name" ||
continue
231 announce_olsr_service_relay
"$service_name"
233 update_mesh_gateway_firewall_rules
234 deannounce_unused_olsr_service_relays is_service_relay_possible
236 deannounce_unused_olsr_service_relays
false
242 ## @fn filter_relay_services()
243 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die als Dienst-Relay fungieren.
244 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an die Standardausgabe
245 ## weitergeleitet, falls es sich um einen Relay-Dienst handelt.
246 filter_relay_services() {
248 while read service_name;
do
249 [ -n
"$(get_service_value "$service_name
" "local_relay_port
")" ] && echo
"$service_name"
254 # Ende der Doku-Gruppe
get_services(service_type)
Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind. Falls kein Typ angegben wird...
uci_add_list(uci_path, new_item)
Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
filter_services_by_value(key, value)
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
uci_get_list(uci_path)
Liefere alle einzelenen Elemente einer UCI-Liste zurück.
filter_routable_addresses()
Filtere aus einer Menge von Ziel-IPs diejenigen heraus, für die eine passende Routing-Regel existiert...
msg_debug(message)
Debug-Meldungen ins syslog schreiben.
get_service_value(key, default)
Auslesen eines Werts aus der Service-Datenbank.
set eu grep root::etc shadow exit if which chpasswd dev null
is_service_routed_via_wan(service_name)
Pruefe ob der Verkehr zum Anbieter des Diensts über ein WAN-Interface verlaufen würde.
set eu for table in filter nat mangle
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.