blob: e82db087c5810582d163f8a6bcf7ddcb2d6188fd [file] [log] [blame]
Patrick Williamsb48b7b42016-08-17 15:04:38 -05001racoon: Resend UPDATE message when received EINTR message
2
3Upstream-Status: Pending
4
5While kernel is processing the UPDATE message which is sent from racoon,
6it maybe interrupted by system signal and if this case happens,
7kernel responds with an EINTR message to racoon and kernel fails to
8establish the corresponding SA.
9Fix this problem by resend the UPDATE message when EINTR(Interrupted
10system call) error happens.
11
12Signed-off-by: Xufeng Zhang <xufeng.zhang@windriver.com>
13---
14--- a/src/libipsec/libpfkey.h
15+++ b/src/libipsec/libpfkey.h
16@@ -92,6 +92,12 @@
17 u_int16_t ctxstrlen; /* length of security context string */
18 };
19
20+struct update_msg_info {
21+ struct sadb_msg *update_msg;
22+ int so;
23+ int len;
24+};
25+
26 /* The options built into libipsec */
27 extern int libipsec_opt;
28 #define LIBIPSEC_OPT_NATT 0x01
29--- a/src/libipsec/pfkey.c
30+++ b/src/libipsec/pfkey.c
31@@ -1219,7 +1219,8 @@
32 }
33 #endif
34
35-
36+struct update_msg_info update_msg_send = {NULL, 0, 0};
37+
38 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
39 static int
40 pfkey_send_x1(struct pfkey_send_sa_args *sa_parms)
41@@ -1483,10 +1484,24 @@
42
43 /* send message */
44 len = pfkey_send(sa_parms->so, newmsg, len);
45- free(newmsg);
46
47- if (len < 0)
48- return -1;
49+ if (newmsg->sadb_msg_type == SADB_UPDATE) {
50+ if (update_msg_send.update_msg)
51+ free(update_msg_send.update_msg);
52+ update_msg_send.update_msg = newmsg;
53+ update_msg_send.so = sa_parms->so;
54+ update_msg_send.len = len;
55+
56+ if (len < 0) {
57+ free(update_msg_send.update_msg);
58+ update_msg_send.update_msg = NULL;
59+ return -1;
60+ }
61+ } else {
62+ free(newmsg);
63+ if (len < 0)
64+ return -1;
65+ }
66
67 __ipsec_errcode = EIPSEC_NO_ERROR;
68 return len;
69--- a/src/racoon/session.c
70+++ b/src/racoon/session.c
71@@ -100,6 +100,8 @@
72
73 #include "sainfo.h"
74
75+extern struct update_msg_info update_msg_send;
76+
77 struct fd_monitor {
78 int (*callback)(void *ctx, int fd);
79 void *ctx;
80@@ -348,6 +350,11 @@
81 close_sockets();
82 backupsa_clean();
83
84+ if (update_msg_send.update_msg) {
85+ free(update_msg_send.update_msg);
86+ update_msg_send.update_msg = NULL;
87+ }
88+
89 plog(LLV_INFO, LOCATION, NULL, "racoon process %d shutdown\n", getpid());
90
91 exit(0);
92--- a/src/racoon/pfkey.c
93+++ b/src/racoon/pfkey.c
94@@ -103,10 +103,12 @@
95 #include "crypto_openssl.h"
96 #include "grabmyaddr.h"
97+#include "../libipsec/libpfkey.h"
98
99 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
100 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
101 #endif
102
103+extern struct update_msg_info update_msg_send;
104 /* prototype */
105 static u_int ipsecdoi2pfkey_aalg __P((u_int));
106 static u_int ipsecdoi2pfkey_ealg __P((u_int));
107@@ -253,6 +255,13 @@
108 s_pfkey_type(msg->sadb_msg_type),
109 strerror(msg->sadb_msg_errno));
110
111+ if (msg->sadb_msg_errno == EINTR &&
112+ update_msg_send.update_msg) {
113+ plog(LLV_DEBUG, LOCATION, NULL,
114+ "pfkey update resend\n");
115+ send(update_msg_send.so, (void *)update_msg_send.update_msg, (socklen_t)update_msg_send.len, 0);
116+ }
117+
118 goto end;
119 }
120
121@@ -498,6 +507,11 @@
122 {
123 flushsp();
124
125+ if (update_msg_send.update_msg) {
126+ free(update_msg_send.update_msg);
127+ update_msg_send.update_msg = NULL;
128+ }
129+
130 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
131 plog(LLV_ERROR, LOCATION, NULL,
132 "libipsec sending spddump failed: %s\n",
133@@ -1295,6 +1309,8 @@
134 return 0;
135 }
136
137+int update_received = 0;
138+
139 static int
140 pk_recvupdate(mhp)
141 caddr_t *mhp;
142@@ -1307,6 +1323,13 @@
143 int incomplete = 0;
144 struct saproto *pr;
145
146+ update_received = 1;
147+
148+ if (update_msg_send.update_msg) {
149+ free(update_msg_send.update_msg);
150+ update_msg_send.update_msg = NULL;
151+ }
152+
153 /* ignore this message because of local test mode. */
154 if (f_local)
155 return 0;
156@@ -4163,3 +4186,8 @@
157
158 return buf;
159 }
160+
161+int receive_from_isakmp()
162+{
163+ return pfkey_handler(NULL, lcconf->sock_pfkey);
164+}
165--- a/src/racoon/pfkey.h
166+++ b/src/racoon/pfkey.h
167@@ -71,5 +71,6 @@
168 extern u_int32_t pk_getseq __P((void));
169 extern const char *sadbsecas2str
170 __P((struct sockaddr *, struct sockaddr *, int, u_int32_t, int));
171+extern int receive_from_isakmp __P((void));
172
173 #endif /* _PFKEY_H */
174--- a/src/racoon/isakmp_quick.c
175+++ b/src/racoon/isakmp_quick.c
176@@ -774,6 +774,8 @@
177 return error;
178 }
179
180+extern int update_received;
181+
182 /*
183 * send to responder
184 * HDR*, HASH(3)
185@@ -892,6 +894,11 @@
186 }
187 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
188
189+ while (!update_received)
190+ receive_from_isakmp();
191+
192+ update_received = 0;
193+
194 /* Do ADD for responder */
195 if (pk_sendadd(iph2) < 0) {
196 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
197@@ -1035,6 +1042,11 @@
198 }
199 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
200
201+ while (!update_received)
202+ receive_from_isakmp();
203+
204+ update_received = 0;
205+
206 /* Do ADD for responder */
207 if (pk_sendadd(iph2) < 0) {
208 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
209@@ -1989,6 +2001,11 @@
210 }
211 plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
212
213+ while (!update_received)
214+ receive_from_isakmp();
215+
216+ update_received = 0;
217+
218 /* Do ADD for responder */
219 if (pk_sendadd(iph2) < 0) {
220 plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");