diff options
author | Chia-chi Yeh <chiachi@android.com> | 2011-05-31 13:26:30 -0700 |
---|---|---|
committer | Chia-chi Yeh <chiachi@android.com> | 2011-05-31 13:34:05 -0700 |
commit | 3473d8ebd2f370edcc83c7455c76cf3b2daef4ae (patch) | |
tree | 84ec3cf49b54f129f5dd87d91e7e6e1ea629c4c8 | |
parent | 96869bdabff3948f0a6dc2dad2933d1aace21442 (diff) | |
download | ipsec-tools-3473d8ebd2f370edcc83c7455c76cf3b2daef4ae.tar.gz |
Only remove entries to the VPN server on exit.
We might have other IPSec users, and flushing everything causes problems.
Bug: 4171459
Change-Id: Icebd4a04f9b88890ac1cfd587673fcf906a00aa5
-rw-r--r-- | setup.c | 61 |
1 files changed, 47 insertions, 14 deletions
@@ -49,6 +49,7 @@ static struct localconf localconf; static struct remoteconf remoteconf; static struct sainfo sainfo; static char *pre_shared_key; +static struct sockaddr target; struct localconf *lcconf = &localconf; char *script_names[SCRIPT_MAX + 1]; @@ -178,15 +179,51 @@ static void add_sainfo_algorithm(int class, int algorithm, int length) } } +static int match(struct sadb_address *address) +{ + if (address) { + struct sockaddr *source = PFKEY_ADDR_SADDR(address); + return !cmpsaddrwop(source, &target); + } + return 0; +} + /* flush; spdflush; */ static void flush() { + struct sadb_msg *p; + int replies = 0; int key = pfkey_open(); - if (key != -1) { - pfkey_send_flush(key, SADB_SATYPE_UNSPEC); - pfkey_send_spdflush(key); - pfkey_close(key); + + if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 || + pfkey_send_spddump(key) <= 0) { + do_plog(LLV_ERROR, "Cannot dump SAD and SPD"); + exit(1); } + + for (p = NULL; replies < 2 && (p = pfkey_recv(key)) != NULL; free(p)) { + caddr_t q[SADB_EXT_MAX + 1]; + + if (p->sadb_msg_type != SADB_DUMP && + p->sadb_msg_type != SADB_X_SPDDUMP) { + continue; + } + replies += !p->sadb_msg_seq; + + if (p->sadb_msg_errno || pfkey_align(p, q) || pfkey_check(q)) { + continue; + } + if (match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) || + match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) { + p->sadb_msg_type = (p->sadb_msg_type == SADB_DUMP) ? + SADB_DELETE : SADB_X_SPDDELETE; + p->sadb_msg_reserved = 0; + p->sadb_msg_seq = 0; + pfkey_send(key, p, PFKEY_UNUNIT64(p->sadb_msg_len)); + } + } + + pfkey_close(key); } /* flush; spdflush; @@ -197,13 +234,9 @@ static void spdadd(struct sockaddr *local, struct sockaddr *remote) struct sadb_x_policy p; struct sadb_x_ipsecrequest q; } policy; - int mask = (local->sa_family == AF_INET) ? sizeof(struct in_addr) * 8 : + int prefix = (local->sa_family == AF_INET) ? sizeof(struct in_addr) * 8 : sizeof(struct in6_addr) * 8; int key = pfkey_open(); - if (key == -1) { - do_plog(LLV_ERROR, "Cannot create KEY socket\n"); - exit(1); - } memset(&policy, 0, sizeof(policy)); policy.p.sadb_x_policy_len = PFKEY_UNIT64(sizeof(policy)); @@ -218,11 +251,11 @@ static void spdadd(struct sockaddr *local, struct sockaddr *remote) policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; policy.q.sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; - if (pfkey_send_flush(key, SADB_SATYPE_UNSPEC) <= 0 || - pfkey_send_spdflush(key) <= 0 || - pfkey_send_spdadd(key, local, mask, remote, mask, IPPROTO_UDP, + target = *remote; + flush(); + if (pfkey_send_spdadd(key, local, prefix, remote, prefix, IPPROTO_UDP, (caddr_t)&policy, sizeof(policy), 0) <= 0) { - do_plog(LLV_ERROR, "Cannot initialize SA and SPD\n"); + do_plog(LLV_ERROR, "Cannot initialize SAD and SPD\n"); exit(1); } pfkey_close(key); @@ -243,7 +276,7 @@ void setup(int argc, char **argv) /* Set local address and remote address. */ set_address(argv[1], argv[2]); - /* Initialize SA and SPD. */ + /* Initialize SAD and SPD. */ spdadd(myaddrs[0].addr, remoteconf.remote); /* Set local port and remote port. */ |