diff options
author | Chia-chi Yeh <chiachi@android.com> | 2011-07-13 14:05:22 -0700 |
---|---|---|
committer | Chia-chi Yeh <chiachi@android.com> | 2011-07-13 16:21:39 -0700 |
commit | cfc417e4c9268b46d71d2fe17aa9ad21bde23f39 (patch) | |
tree | 6e138c32366a905c33c42cffa916b0c608f095d4 | |
parent | 264d6b72846aba10ca1f3cd1a7bd76e3a02e21e5 (diff) | |
download | ipsec-tools-cfc417e4c9268b46d71d2fe17aa9ad21bde23f39.tar.gz |
ipsec-tools: Do not run the phase1-up script more than once.
Racoon executes phase1-up or phase1-down when phase 1 is established or
destroyed. Combining with the usage of mode-cfg, phase1-up generates the
SPD policy and sets the internal network, and phase1-down reverts what
phase1-up does. However, a new phase 1 may be established before the
previous one is destroyed, so phase1-down may be executed after the new
phase1-up, which causes some difficulties to maintain the state.
It can be solved in several ways, such as disabling phase 1 rekeying or
carefully updating the internal network. The former limits the lifetime
of a VPN connection, and the latter complicates the VPN on Android. We
can also disable mode-cfg or skip the phase1-up script after the first
phase 1 is established. It is hard to tell which one is the best. Just
try one and see if we need to switch to another.
Change-Id: Icd010c3242b2f66651e1332f819fb5f274c9fc45
-rw-r--r-- | setup.c | 45 |
1 files changed, 27 insertions, 18 deletions
@@ -548,31 +548,40 @@ static char *get_env(char * const *envp, char *key) return *envp ? &(*envp)[length + 1] : ""; } +static int skip_script = 0; extern void android_setenv(char ***envp); int privsep_script_exec(char *script, int name, char * const *envp) { - /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */ - struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"), NULL); - struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"), - get_env(envp, "LOCAL_PORT")); - struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"), - get_env(envp, "REMOTE_PORT")); - - if (addr4 && local && remote) { + if (skip_script) { + do_plog(LLV_WARNING, + "Phase 1 is up again. This time skip executing the script.\n"); + } else { + /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */ + struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"), + NULL); + struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"), + get_env(envp, "LOCAL_PORT")); + struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"), + get_env(envp, "REMOTE_PORT")); + + if (addr4 && local && remote) { #ifdef ANDROID_CHANGES - android_setenv((char ***)&envp); + android_setenv((char ***)&envp); #endif - spdadd(addr4, NULL, IPPROTO_IP, local, remote); - } else { - do_plog(LLV_ERROR, "Cannot find parameters to generate SPD policy.\n"); - exit(1); - } + spdadd(addr4, NULL, IPPROTO_IP, local, remote); + } else { + do_plog(LLV_ERROR, "Cannot get parameters for SPD policy.\n"); + exit(1); + } - racoon_free(addr4); - racoon_free(local); - racoon_free(remote); - return script ? script_exec(script, name, envp) : -1; + skip_script = 1; + racoon_free(addr4); + racoon_free(local); + racoon_free(remote); + return script_exec(script, name, envp); + } + return 0; } int privsep_accounting_system(int port, struct sockaddr *addr, |