1 |
diff -Nurp ipsec-tools-0.8.0-p3/src/racoon/handler.h ipsec-tools-0.8.0-p103/src/racoon/handler.h |
2 |
--- ipsec-tools-0.8.0-p3/src/racoon/handler.h 2010-11-17 12:40:41.000000000 +0200 |
3 |
+++ ipsec-tools-0.8.0-p103/src/racoon/handler.h 2012-03-06 12:09:55.085380720 +0200 |
4 |
@@ -316,6 +316,8 @@ struct ph2handle { |
5 |
|
6 |
u_int8_t flags; /* Flags for phase 2 */ |
7 |
u_int32_t msgid; /* msgid for phase 2 */ |
8 |
+ |
9 |
+ u_int32_t sa_count; /* num of SAs sent in SADB_ADD */ |
10 |
|
11 |
struct sainfo *sainfo; /* place holder of sainfo */ |
12 |
struct saprop *proposal; /* SA(s) proposal. */ |
13 |
diff -Nurp ipsec-tools-0.8.0-p3/src/racoon/pfkey.c ipsec-tools-0.8.0-p103/src/racoon/pfkey.c |
14 |
--- ipsec-tools-0.8.0-p3/src/racoon/pfkey.c 2011-03-15 15:20:14.000000000 +0200 |
15 |
+++ ipsec-tools-0.8.0-p103/src/racoon/pfkey.c 2012-03-06 12:09:55.086380830 +0200 |
16 |
@@ -1347,7 +1347,9 @@ pk_recvupdate(mhp) |
17 |
sched_cancel(&iph2->sce); |
18 |
|
19 |
/* update status */ |
20 |
- iph2->status = PHASE2ST_ESTABLISHED; |
21 |
+ /* Do this in pk_recvadd |
22 |
+ * iph2->status = PHASE2ST_ESTABLISHED; |
23 |
+ */ |
24 |
evt_phase2(iph2, EVT_PHASE2_UP, NULL); |
25 |
|
26 |
#ifdef ENABLE_STATS |
27 |
@@ -1379,6 +1381,7 @@ pk_sendadd(iph2) |
28 |
{ |
29 |
struct saproto *pr; |
30 |
struct pfkey_send_sa_args sa_args; |
31 |
+ u_int32_t sa_sent = 0; |
32 |
|
33 |
/* sanity check */ |
34 |
if (iph2->approval == NULL) { |
35 |
@@ -1498,6 +1501,9 @@ pk_sendadd(iph2) |
36 |
return -1; |
37 |
} |
38 |
|
39 |
+ /* keep count of SAs added */ |
40 |
+ sa_sent++; |
41 |
+ |
42 |
if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]) |
43 |
continue; |
44 |
|
45 |
@@ -1518,6 +1524,7 @@ pk_sendadd(iph2) |
46 |
sadbsecas2str(sa_args.src, sa_args.dst, |
47 |
sa_args.satype, sa_args.spi, sa_args.mode)); |
48 |
} |
49 |
+ iph2->sa_count = sa_sent; |
50 |
racoon_free(sa_args.src); |
51 |
racoon_free(sa_args.dst); |
52 |
return 0; |
53 |
@@ -1576,10 +1583,20 @@ pk_recvadd(mhp) |
54 |
} |
55 |
|
56 |
/* |
57 |
- * NOTE don't update any status of phase2 handle |
58 |
- * because they must be updated by SADB_UPDATE message |
59 |
+ * Thus, update the status of phase 2 handle after all SADB_ADD |
60 |
+ * msgs have been received for the handle, rather than |
61 |
+ * after SADB_UPDATE. |
62 |
+ * |
63 |
+ * This also removes the possibilty of processing an ACQUIRE |
64 |
+ * received by kernel for SAs we are still adding. |
65 |
*/ |
66 |
|
67 |
+ if (iph2->sa_count) { |
68 |
+ iph2->sa_count = iph2->sa_count - 1; |
69 |
+ if (iph2->sa_count == 0) |
70 |
+ iph2->status = PHASE2ST_ESTABLISHED; |
71 |
+ } |
72 |
+ |
73 |
plog(LLV_INFO, LOCATION, NULL, |
74 |
"IPsec-SA established: %s\n", |
75 |
sadbsecas2str(src, dst, |
76 |
@@ -1690,6 +1707,7 @@ pk_recvexpire(mhp) |
77 |
plog(LLV_ERROR, LOCATION, iph2->dst, |
78 |
"failed to begin ipsec sa " |
79 |
"re-negotication.\n"); |
80 |
+ iph2->status = PHASE2ST_EXPIRED; |
81 |
remph2(iph2); |
82 |
delph2(iph2); |
83 |
return -1; |
84 |
@@ -1855,8 +1873,17 @@ pk_recvacquire(mhp) |
85 |
* 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon |
86 |
* has to prcesss such a acquire message because racoon may |
87 |
* lost the expire message. |
88 |
+ * |
89 |
+ * When in responder role, an spid doesn't get added to |
90 |
+ * the handler since responder didn't receive acquire. |
91 |
+ * Thus there is the case that a negotiation can be occurring |
92 |
+ * and responder receives acquire for same policy. So to prevent |
93 |
+ * another identical negotiation, also check by address. |
94 |
*/ |
95 |
iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id); |
96 |
+ if (iph2 == NULL) |
97 |
+ iph2 = getph2bysaddr(src, dst); |
98 |
+ |
99 |
if (iph2 != NULL) { |
100 |
if (iph2->status < PHASE2ST_ESTABLISHED) { |
101 |
plog(LLV_DEBUG, LOCATION, NULL, |