<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi,<br>
<br>
As requested by LetoTo I have forwarded my IRC message to email.<br>
<br>
<br>
I came across a bug in Openswan. The box starts up. Openswan
connects. The date is set back to 1970, NTPD is started and sets the
date to be 2011.<br>
<br>
After this, the command "ipsec auto --status" blocks indefinitely.<br>
<br>
Analysis (based on 2.4 and verified in 2.6) is that in
timer.c:next_event(), the expression <b>evlist->ev_time - now()</b>
is negative (ev_time is 40 years ago). Hence next_event() returns 0,
causing the event to be triggered.<br>
<br>
But when handle_timer_event() is called, the expression <b>now() <
ev->ev_time</b> evaluates to TRUE (due to long wrapping???), meaning
that the event is not removed from the event list.<br>
<br>
Looking at <i>server.c</i>, the code becomes stuck in the loop ... <span
style="color: rgb(0, 0, 0);">in <i>call_server()</i> next_event()
returns 0. This then sets ndes to 0 (and osw_select() is NOT called).</span><span
style="color: rgb(0, 0, 0);"> But when handle_timer_event() is
called, the function believes that there are no events to handle, so
the event queue does not change. So when call_server() loops it calls
next_event() which returns 0 again.<br>
<br>
</span>
<p style="margin: 0px; text-indent: 0px;"><!--EndFragment--></p>
This blocks the thread from calling the select() function to handle all
the file descriptors. Hence <b>ipsec auto --status</b> never gets a
reply to its request, and will block forever. Likewise, all
communications into Openswan never gets a reply.<br>
<br>
A proposed solution (that I have tested successfully in version 2.4) is
to change now() to use the systems uptime instead. This solution also
has the benefit that timing jitter is not introduced by people setting
the time on a device or programs such as ntpd.<br>
<br>
Let me know if you have any questions.<br>
<br>
<br>
Thanks,<br>
Antony.<br>
<br>
<br>
<b>Proposed diff ...<br>
</b><br>
diff --git a/lib/libopenswan/oswtime.c b/lib/libopenswan/oswtime.c<br>
index 6440258..7e17529 100644<br>
--- a/lib/libopenswan/oswtime.c<br>
+++ b/lib/libopenswan/oswtime.c<br>
@@ -22,6 +22,7
@@
<br>
#include <unistd.h><br>
#include <netinet/in.h><br>
#include <arpa/inet.h><br>
+#include <sys/sysinfo.h><br>
<br>
#include <openswan.h><br>
<br>
@@ -34,18 +35,18 @@<br>
time_t<br>
now(void)<br>
{<br>
- static time_t delta = 0<br>
- , last_time = 0;<br>
- time_t n = time(NULL);<br>
+ /*<br>
+ * Use uptime as it cannot jump unexpentantly,<br>
+ * for example, when the time is changed forwards or backwards.<br>
+ */<br>
+ struct sysinfo info;<br>
<br>
- passert(n != (time_t)-1);<br>
- if (last_time > n)<br>
+ if (sysinfo(&info) == 0)<br>
{<br>
- openswan_log("time moved backwards %ld seconds",
(long)(last_time - n));<br>
- delta += last_time - n;<br>
+ return (time_t)info.uptime;<br>
}<br>
- last_time = n;<br>
- return n + delta;<br>
+ passert(0);<br>
+ return 0;<br>
}<br>
<br>
/* Names of the months */<br>
<br>
<br>
</body>
</html>