From f25071b66fbcf508f46e16f30e964bdaa8f97d6f Mon Sep 17 00:00:00 2001 From: james Date: Thu, 1 Oct 2009 21:08:40 +0000 Subject: client-kill management interface command, when issued on server, will now send a RESTART message to client. 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 --- forward.c | 11 +++++++---- forward.h | 2 +- multi.c | 2 +- openvpn.h | 1 + push.c | 28 +++++++++++++++++++++++++++- push.h | 4 ++++ 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/forward.c b/forward.c index 87f3350..661ac5c 100644 --- a/forward.c +++ b/forward.c @@ -157,6 +157,8 @@ check_incoming_control_channel_dowork (struct context *c) receive_auth_failed (c, &buf); else if (buf_string_match_head_str (&buf, "PUSH_")) incoming_push_message (c, &buf); + else if (buf_string_match_head_str (&buf, "RESTART")) + server_pushed_restart (c, &buf); else msg (D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR (&buf)); } @@ -181,7 +183,7 @@ check_push_request_dowork (struct context *c) event_timeout_modify_wakeup (&c->c2.push_request_interval, 5); } -#endif +#endif /* P2MP */ /* * Things that need to happen immediately after connection initiation should go here. @@ -328,15 +330,16 @@ check_server_poll_timeout_dowork (struct context *c) } /* - * Schedule a SIGTERM n_seconds from now. + * Schedule a signal n_seconds from now. */ void -schedule_exit (struct context *c, const int n_seconds) +schedule_exit (struct context *c, const int n_seconds, const int signal) { tls_set_single_session (c->c2.tls_multi); update_time (); reset_coarse_timers (c); event_timeout_init (&c->c2.scheduled_exit, n_seconds, now); + c->c2.scheduled_exit_signal = signal; msg (D_SCHED_EXIT, "Delayed exit in %d seconds", n_seconds); } @@ -346,7 +349,7 @@ schedule_exit (struct context *c, const int n_seconds) void check_scheduled_exit_dowork (struct context *c) { - c->sig->signal_received = SIGTERM; + c->sig->signal_received = c->c2.scheduled_exit_signal; c->sig->signal_text = "delayed-exit"; } diff --git a/forward.h b/forward.h index 8361f5b..671cd84 100644 --- a/forward.h +++ b/forward.h @@ -80,7 +80,7 @@ bool send_control_channel_string (struct context *c, const char *str, int msglev void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf); #if P2MP -void schedule_exit (struct context *c, const int n_seconds); +void schedule_exit (struct context *c, const int n_seconds, const int signal); #endif #endif /* FORWARD_H */ diff --git a/multi.c b/multi.c index ecd1bb3..7f77cb8 100644 --- a/multi.c +++ b/multi.c @@ -2539,7 +2539,7 @@ management_kill_by_cid (void *arg, const unsigned long cid) struct multi_instance *mi = lookup_by_cid (m, cid); if (mi) { - multi_signal_instance (m, mi, SIGTERM); + send_restart (&mi->context); /* was: multi_signal_instance (m, mi, SIGTERM); */ return true; } else diff --git a/openvpn.h b/openvpn.h index 70df9e0..1df46a1 100644 --- a/openvpn.h +++ b/openvpn.h @@ -436,6 +436,7 @@ struct context_2 struct event_timeout server_poll_interval; struct event_timeout scheduled_exit; + int scheduled_exit_signal; #endif /* packet filter */ diff --git a/push.c b/push.c index 142222b..f817c87 100644 --- a/push.c +++ b/push.c @@ -72,7 +72,22 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) } } +/* + * Act on received restart message from server + */ +void +server_pushed_restart (struct context *c, const struct buffer *buffer) +{ + if (c->options.pull) + { + msg (D_STREAM_ERRORS, "Connection reset command was pushed by server"); + c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ + c->sig->signal_text = "server-pushed-connection-reset"; + } +} + #if P2MP_SERVER + /* * Send auth failed message from server to client. */ @@ -83,7 +98,7 @@ send_auth_failed (struct context *c, const char *client_reason) static const char auth_failed[] = "AUTH_FAILED"; size_t len; - schedule_exit (c, c->options.scheduled_exit_interval); + schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed); if (len > TLS_CHANNEL_BUF_SIZE) @@ -99,6 +114,17 @@ send_auth_failed (struct context *c, const char *client_reason) gc_free (&gc); } + +/* + * Send restart message from server to client. + */ +void +send_restart (struct context *c) +{ + schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); + send_control_channel_string (c, "RESTART", D_PUSH); +} + #endif /* diff --git a/push.h b/push.h index e281310..914b119 100644 --- a/push.h +++ b/push.h @@ -49,6 +49,8 @@ bool send_push_request (struct context *c); void receive_auth_failed (struct context *c, const struct buffer *buffer); +void server_pushed_restart (struct context *c, const struct buffer *buffer); + #if P2MP_SERVER void clone_push_list (struct options *o); @@ -64,6 +66,8 @@ void remove_iroutes_from_push_route_list (struct options *o); void send_auth_failed (struct context *c, const char *client_reason); +void send_restart (struct context *c); + #endif #endif #endif -- cgit