releasing package iodine version 0.6.0~rc1-16
[debian/iodine.git] / debian / iodine-client-start
index 9dd6237a47e0d962c7dde36e8d7c3cc2559e8c8f..9b7cabf119f47c31f793a6f5e7cb0219c3a6c2a8 100755 (executable)
 ## Cause script to bail immediately on failed command
 set -e
 
-## Options for user to set.
+function usage
+{
+    cat <<EOF
+'iodine-client-start' starts an iodine IP-over-DNS tunnel.
 
-## Minimal customization: put the two lines
-##  subdomain=your.tunnel.sub.domain
-##  passwd=password_for_that_tunnel
-## in the file /etc/default/iodine-client.
+Usage: iodine-client-start [option]
+
+  -h, --help           Print help and exit
+  -v, --version                Print version info and exit
+
+Invoking the program without options attempts to set up and configure
+an iodine IP-over-DNS tunnel using the configuration in the file
+/etc/default/iodine-client or by querying the user. It tries to
+figure out the right way to set things up by observing the network,
+and if all else fails by guessing.
+
+QUICK CONFIGURATION
+
+Put two lines in the file /etc/default/iodine-client
+
+       subdomain=your.tunnel.sub.domain
+
+       passwd=password_for_that_tunnel
+
+
+or invoke the script with those environment variables set:
+
+       env subdomain=xxx passwd=xxx iodine-client-start
+
+If these are not set, the script will query the user for them.
+
+DETAILS
+
+The configuration file consists of lines which are either comments
+starting with '#', or settings of the form VAR="val". Valid VARs are:
+
+subdomain
+    Sample value: your.tunnel.sub.domain (no default, must be set)
+
+passwd
+    Sample value: password_for_that_tunnel (no default, must be set)
+
+testhost
+    Hostname to ping when testing if network is working (default:
+    slashdot.org)
+
+bounce_localnet
+    Take the local network down and then up again before starting
+    tunnel (default: false)
+
+test_ping_localnet
+    Test if the local network is working by pinging the gateway
+    (default: true)
+
+test_ping_tunnel
+    Test if the iodine tunnel is working after it has been set up by
+    pinging the host at the other end (default: true)
+
+test_ping_final
+    Test if the tunnel is working after everything is ostensibly set
+    up by trying to ping an external host (default: true)
+
+default_router
+    IP address of router on the local network---should be found
+    automatically, set this if that fails and the program guesses wrong.
+
+interface
+    Interface to use (e.g., eth1, eth0, etc) for connection to DNS
+    server used for the iodine tunnel---should be found automatically,
+    set this if that fails and the program guesses wrong.
+
+mtu
+    Set if tunnel MTU needs to be manually changed (lowered). Should
+    not be necessary anymore, as recent versions of iodine negotiate
+    an appropriate MTU during tunnel setup. But if that negotiation
+    does not happen, or if you are using an older version of iodine,
+    the default tunnel MTU is 1024, and if the local DNS server
+    restricts to 512 byte packets you might need to use an MTU of 220.
+
+skip_raw_udp_mode
+    Set "-r" option in iodine command line. With this option, iodine
+    does not try to establish a direct UDP socket to the iodine server
+    on port 53. (default: true).
+
+continue_on_error
+    Set if the script should continue even if a command fails.
+    Use to test script when running as non-root. Defaults to false
+    if running as root, true otherwise.
+EOF
+}
+
+function version
+{
+    echo iodine-client-start 1.0.5
+}
+
+case $# in
+    0)
+       ;;
+    1)
+       case "$1" in
+           # start)
+           #   ;;
+           # stop)
+           #   ;;
+           # restart)
+           #   ;;
+           --version|-v)
+               version
+               exit
+               ;;
+           --help|-h)
+               usage
+               exit
+               ;;
+           *)
+               echo error: unknown option "$1"
+               exit 1
+       esac
+       exit
+       ;;
+    *)
+       echo error: too many arguments "$*"
+       exit 1
+       ;;
+esac
 
 echo "${iodine_client_rc:=/etc/default/iodine-client}" > /dev/null
 
@@ -55,7 +175,7 @@ fi
 echo "${testhost:=slashdot.org}"               > /dev/null
 
 ## Set if local network should be taken down and then up
-echo "${bounce_localnet:=true}"                        > /dev/null
+echo "${bounce_localnet:=false}"               > /dev/null
 
 ## Set for testing network availability via ping at various points
 echo "${test_ping_localnet:=true}"             > /dev/null
@@ -74,6 +194,9 @@ echo "${interface}"                          > /dev/null
 ##  - if local DNS server restricts to 512 byte packets then use MTU 220
 echo "${mtu}"                                  > /dev/null
 
+## Set it if you want try RAW udp mode
+echo "${skip_raw_udp_mode:=true}"           > /dev/null
+
 ## Set if the script should continue even if a command fails.
 ## Used to test script when running as non-root.
 if [ $(whoami) = root ]; then
@@ -88,8 +211,17 @@ fi
 ##  ipcalc (for /usr/bin/ipcalc)
 ##  dnsutils (for /usr/bin/dig)
 ##  fping (for /usr/bin/fping)
+##  or oping (for /usr/bin/oping)
 ##  gawk (for /usr/bin/gawk, to use gensub())
 
+if type -P fping > /dev/null; then
+    ping_cmd="fping -C1"
+elif type -P oping > /dev/null; then
+    ping_cmd="oping -c1"
+else
+    ping_cmd="echo would ping"
+fi
+
 ## TO DO
 ## - avoid double ping when DNS server and local router are the same
 ## - option to not kill existing iodine DNS tunnels, in case there
@@ -102,8 +234,13 @@ echo ==== Creating IP-over-DNS tunnel over local network connection...
 ## Find a network interface
 
 if [ -z ${interface} ]; then
-    interface=$(tail --lines=+3 /proc/net/wireless \
-       | head -1 | tr -d : | awk '{print $1}')
+    interfaces=$(tail --lines=+3 /proc/net/wireless \
+       | tr -d : | awk '{print $1}')
+    for dev in ${interfaces}; do
+        if ip -4 addr show dev ${dev} | grep -q inet; then
+            interface=${dev}
+        fi
+    done
 fi
 
 if [ -z ${interface} ]; then
@@ -181,7 +318,7 @@ fi
 
 if ${test_ping_localnet}; then
     echo ==== Ping test of  local network router and DNS servers...
-    fping -C1 ${router} ${nameservers} \
+    ${ping_cmd} ${router} ${nameservers} \
        || echo WARNING: Ping test failed.
 fi
 
@@ -189,18 +326,25 @@ fi
 
 for n in ${nameservers}; do
     n_net=$(ipcalc --nobinary ${n}/${prefix_len} | awk '$1=="Network:" {print $2}')
+    n_net8=$(ipcalc --nobinary ${n}/8 | awk '$1=="Network:" {print $2}')
     if [ "${n_net}" != "${local_net}" ]; then
-       echo ==== Adding point-to-point route for DNS server ${n}
-        ## remove point-to-point route first, in case it is already present
-       ip -4 route del ${n}/32 || true
-       ip -4 route add ${n}/32 via ${router} || ${continue_on_error}
+        if [ "${n_net8}" != "127.0.0.0/8" ]; then
+           echo ==== Adding point-to-point route for DNS server ${n}
+            ## remove point-to-point route first, in case it is already present
+           ip -4 route del ${n}/32 || true
+           ip -4 route add ${n}/32 via ${router} || ${continue_on_error}
+        fi
     fi
 done
 
 ## Bring up DNS tunnel
 
 echo ==== Creating IP-over-DNS tunnel...
-iodine -P "${passwd}" "${subdomain}" || ${continue_on_error}
+if ${skip_raw_udp_mode}; then
+    iodine_opts="${iodine_opts} -r"
+fi
+
+iodine ${iodine_opts} -P "${passwd}" "${subdomain}" || ${continue_on_error}
 
 ## Find DNS tunnel interface
 
@@ -237,7 +381,7 @@ echo ==== DNS tunnel remote endpoint: ${tunnel_remote}
 
 if ${test_ping_tunnel}; then
     echo ==== Ping test of local router, nameserver, and DNS tunnel...
-    fping -C1 ${router} ${nameservers} ${tunnel_remote} \
+    ${ping_cmd} ${router} ${nameservers} ${tunnel_remote} \
        || echo WARNING: Ping test failed.
 fi
 
@@ -246,7 +390,7 @@ fi
 echo ==== Setting default route through DNS tunnel...
 
 ## Remove default route via local router
-ip -4 route del default via ${router} || ${continue_on_error}
+ip -4 route del default via ${router} || echo WARNING: No default route to delete
 ## Add default via tunnel
 ip -4 route add default via ${tunnel_remote} || ${continue_on_error}
 
@@ -254,6 +398,6 @@ ip -4 route add default via ${tunnel_remote} || ${continue_on_error}
 
 if ${test_ping_final}; then
     echo ==== Ping test of local router, nameserver, DNS tunnel, external test host...
-    fping -C1 ${router} ${nameservers} ${tunnel_remote} ${testhost_ip:-${testhost}} \
+    ${ping_cmd} ${router} ${nameservers} ${tunnel_remote} ${testhost_ip:-${testhost}} \
        || echo WARNING: Ping test failed.
 fi