This feature is intended to make UDP clients respond the same as TCP
clients in the case where the server issues a RESTART message in
order to force the client to reconnect and pull a new options/route
list.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5021 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -157,6 +157,8 @@ check_incoming_control_channel_dowork (struct context *c) |
| 157 | 157 |
receive_auth_failed (c, &buf); |
| 158 | 158 |
else if (buf_string_match_head_str (&buf, "PUSH_")) |
| 159 | 159 |
incoming_push_message (c, &buf); |
| 160 |
+ else if (buf_string_match_head_str (&buf, "RESTART")) |
|
| 161 |
+ server_pushed_restart (c, &buf); |
|
| 160 | 162 |
else |
| 161 | 163 |
msg (D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR (&buf)); |
| 162 | 164 |
} |
| ... | ... |
@@ -181,7 +183,7 @@ check_push_request_dowork (struct context *c) |
| 181 | 181 |
event_timeout_modify_wakeup (&c->c2.push_request_interval, 5); |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 |
-#endif |
|
| 184 |
+#endif /* P2MP */ |
|
| 185 | 185 |
|
| 186 | 186 |
/* |
| 187 | 187 |
* Things that need to happen immediately after connection initiation should go here. |
| ... | ... |
@@ -328,15 +330,16 @@ check_server_poll_timeout_dowork (struct context *c) |
| 328 | 328 |
} |
| 329 | 329 |
|
| 330 | 330 |
/* |
| 331 |
- * Schedule a SIGTERM n_seconds from now. |
|
| 331 |
+ * Schedule a signal n_seconds from now. |
|
| 332 | 332 |
*/ |
| 333 | 333 |
void |
| 334 |
-schedule_exit (struct context *c, const int n_seconds) |
|
| 334 |
+schedule_exit (struct context *c, const int n_seconds, const int signal) |
|
| 335 | 335 |
{
|
| 336 | 336 |
tls_set_single_session (c->c2.tls_multi); |
| 337 | 337 |
update_time (); |
| 338 | 338 |
reset_coarse_timers (c); |
| 339 | 339 |
event_timeout_init (&c->c2.scheduled_exit, n_seconds, now); |
| 340 |
+ c->c2.scheduled_exit_signal = signal; |
|
| 340 | 341 |
msg (D_SCHED_EXIT, "Delayed exit in %d seconds", n_seconds); |
| 341 | 342 |
} |
| 342 | 343 |
|
| ... | ... |
@@ -346,7 +349,7 @@ schedule_exit (struct context *c, const int n_seconds) |
| 346 | 346 |
void |
| 347 | 347 |
check_scheduled_exit_dowork (struct context *c) |
| 348 | 348 |
{
|
| 349 |
- c->sig->signal_received = SIGTERM; |
|
| 349 |
+ c->sig->signal_received = c->c2.scheduled_exit_signal; |
|
| 350 | 350 |
c->sig->signal_text = "delayed-exit"; |
| 351 | 351 |
} |
| 352 | 352 |
|
| ... | ... |
@@ -80,7 +80,7 @@ bool send_control_channel_string (struct context *c, const char *str, int msglev |
| 80 | 80 |
void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf); |
| 81 | 81 |
|
| 82 | 82 |
#if P2MP |
| 83 |
-void schedule_exit (struct context *c, const int n_seconds); |
|
| 83 |
+void schedule_exit (struct context *c, const int n_seconds, const int signal); |
|
| 84 | 84 |
#endif |
| 85 | 85 |
|
| 86 | 86 |
#endif /* FORWARD_H */ |
| ... | ... |
@@ -2539,7 +2539,7 @@ management_kill_by_cid (void *arg, const unsigned long cid) |
| 2539 | 2539 |
struct multi_instance *mi = lookup_by_cid (m, cid); |
| 2540 | 2540 |
if (mi) |
| 2541 | 2541 |
{
|
| 2542 |
- multi_signal_instance (m, mi, SIGTERM); |
|
| 2542 |
+ send_restart (&mi->context); /* was: multi_signal_instance (m, mi, SIGTERM); */ |
|
| 2543 | 2543 |
return true; |
| 2544 | 2544 |
} |
| 2545 | 2545 |
else |
| ... | ... |
@@ -72,7 +72,22 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) |
| 72 | 72 |
} |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+/* |
|
| 76 |
+ * Act on received restart message from server |
|
| 77 |
+ */ |
|
| 78 |
+void |
|
| 79 |
+server_pushed_restart (struct context *c, const struct buffer *buffer) |
|
| 80 |
+{
|
|
| 81 |
+ if (c->options.pull) |
|
| 82 |
+ {
|
|
| 83 |
+ msg (D_STREAM_ERRORS, "Connection reset command was pushed by server"); |
|
| 84 |
+ c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ |
|
| 85 |
+ c->sig->signal_text = "server-pushed-connection-reset"; |
|
| 86 |
+ } |
|
| 87 |
+} |
|
| 88 |
+ |
|
| 75 | 89 |
#if P2MP_SERVER |
| 90 |
+ |
|
| 76 | 91 |
/* |
| 77 | 92 |
* Send auth failed message from server to client. |
| 78 | 93 |
*/ |
| ... | ... |
@@ -83,7 +98,7 @@ send_auth_failed (struct context *c, const char *client_reason) |
| 83 | 83 |
static const char auth_failed[] = "AUTH_FAILED"; |
| 84 | 84 |
size_t len; |
| 85 | 85 |
|
| 86 |
- schedule_exit (c, c->options.scheduled_exit_interval); |
|
| 86 |
+ schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); |
|
| 87 | 87 |
|
| 88 | 88 |
len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed); |
| 89 | 89 |
if (len > TLS_CHANNEL_BUF_SIZE) |
| ... | ... |
@@ -99,6 +114,17 @@ send_auth_failed (struct context *c, const char *client_reason) |
| 99 | 99 |
|
| 100 | 100 |
gc_free (&gc); |
| 101 | 101 |
} |
| 102 |
+ |
|
| 103 |
+/* |
|
| 104 |
+ * Send restart message from server to client. |
|
| 105 |
+ */ |
|
| 106 |
+void |
|
| 107 |
+send_restart (struct context *c) |
|
| 108 |
+{
|
|
| 109 |
+ schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); |
|
| 110 |
+ send_control_channel_string (c, "RESTART", D_PUSH); |
|
| 111 |
+} |
|
| 112 |
+ |
|
| 102 | 113 |
#endif |
| 103 | 114 |
|
| 104 | 115 |
/* |
| ... | ... |
@@ -49,6 +49,8 @@ bool send_push_request (struct context *c); |
| 49 | 49 |
|
| 50 | 50 |
void receive_auth_failed (struct context *c, const struct buffer *buffer); |
| 51 | 51 |
|
| 52 |
+void server_pushed_restart (struct context *c, const struct buffer *buffer); |
|
| 53 |
+ |
|
| 52 | 54 |
#if P2MP_SERVER |
| 53 | 55 |
|
| 54 | 56 |
void clone_push_list (struct options *o); |
| ... | ... |
@@ -64,6 +66,8 @@ void remove_iroutes_from_push_route_list (struct options *o); |
| 64 | 64 |
|
| 65 | 65 |
void send_auth_failed (struct context *c, const char *client_reason); |
| 66 | 66 |
|
| 67 |
+void send_restart (struct context *c); |
|
| 68 |
+ |
|
| 67 | 69 |
#endif |
| 68 | 70 |
#endif |
| 69 | 71 |
#endif |