aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config-win32.h.in3
-rw-r--r--configure.ac2
-rw-r--r--error.c9
-rw-r--r--error.h4
-rw-r--r--init.c6
-rw-r--r--manage.c89
-rw-r--r--manage.h5
-rw-r--r--options.c5
-rw-r--r--options.h1
-rwxr-xr-xservice-win32/service.patch12
10 files changed, 112 insertions, 24 deletions
diff --git a/config-win32.h.in b/config-win32.h.in
index 3ea4d85..502c6ae 100644
--- a/config-win32.h.in
+++ b/config-win32.h.in
@@ -98,6 +98,9 @@ typedef unsigned long in_addr_t;
/* Dimension size to use for empty array declaration */
#define EMPTY_ARRAY_SIZE 0
+/* Define to 1 if you have the `getsockname' function. */
+#define HAVE_GETSOCKNAME 1
+
/* Define to 1 if you have the <openssl/engine.h> header file. */
#define HAVE_OPENSSL_ENGINE_H 1
diff --git a/configure.ac b/configure.ac
index aeb7237..13d7d32 100644
--- a/configure.ac
+++ b/configure.ac
@@ -378,7 +378,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl
getpass strerror syslog openlog mlockall getgrnam setgid dnl
setgroups stat flock readv writev setsockopt getsockopt dnl
setsid chdir gettimeofday putenv getpeername unlink dnl
- poll chsize ftruncate sendmsg recvmsg)
+ poll chsize ftruncate sendmsg recvmsg getsockname)
AC_CACHE_SAVE
dnl Required library functions
diff --git a/error.c b/error.c
index f01dd8f..6191cb3 100644
--- a/error.c
+++ b/error.c
@@ -705,6 +705,15 @@ msg_flags_string (const unsigned int flags, struct gc_arena *gc)
return BSTR (&out);
}
+#ifdef ENABLE_DEBUG
+void
+crash (void)
+{
+ char *null = NULL;
+ *null = 0;
+}
+#endif
+
#ifdef WIN32
const char *
diff --git a/error.h b/error.h
index bfe5ec3..62926cc 100644
--- a/error.h
+++ b/error.h
@@ -195,6 +195,10 @@ FILE *msg_fp(void);
void assert_failed (const char *filename, int line);
+#ifdef ENABLE_DEBUG
+void crash (void); // force a segfault (debugging only)
+#endif
+
/* Inline functions */
static inline bool
diff --git a/init.c b/init.c
index 97bf9ec..b1ef034 100644
--- a/init.c
+++ b/init.c
@@ -2393,7 +2393,8 @@ open_management (struct context *c)
c->options.management_echo_buffer_size,
c->options.management_state_buffer_size,
c->options.management_hold,
- c->options.management_client))
+ c->options.management_client,
+ c->options.management_write_peer_info_file))
{
management_set_state (management,
OPENVPN_STATE_CONNECTING,
@@ -2665,7 +2666,8 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
return;
sig:
- c->sig->signal_text = "init_instance";
+ if (!c->sig->signal_text)
+ c->sig->signal_text = "init_instance";
close_context (c, -1, flags);
return;
}
diff --git a/manage.c b/manage.c
index 935b18a..9c2a178 100644
--- a/manage.c
+++ b/manage.c
@@ -187,7 +187,10 @@ man_output_list_push (struct management *man, const char *str)
output_list_push (man->connection.out, (const unsigned char *) str);
man_update_io_state (man);
if (!man->persist.standalone_disabled)
- man_output_standalone (man, NULL);
+ {
+ volatile int signal_received = 0;
+ man_output_standalone (man, &signal_received);
+ }
}
}
@@ -792,6 +795,46 @@ man_stop_ne32 (struct management *man)
#endif
static void
+man_record_peer_info (struct management *man)
+{
+ struct gc_arena gc = gc_new ();
+ if (man->settings.write_peer_info_file)
+ {
+ bool success = false;
+#ifdef HAVE_GETSOCKNAME
+ if (socket_defined (man->connection.sd_cli))
+ {
+ struct sockaddr_in addr;
+ socklen_t addrlen = sizeof (addr);
+ int status;
+
+ CLEAR (addr);
+ status = getsockname (man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen);
+ if (!status && addrlen == sizeof (addr))
+ {
+ const in_addr_t a = ntohl (addr.sin_addr.s_addr);
+ const int p = ntohs (addr.sin_port);
+ FILE *fp = fopen (man->settings.write_peer_info_file, "w");
+ if (fp)
+ {
+ fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p);
+ if (!fclose (fp))
+ success = true;
+ }
+ }
+ }
+#endif
+ if (!success)
+ {
+ msg (D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file %s",
+ man->settings.write_peer_info_file);
+ throw_signal_soft (SIGTERM, "management-connect-failed");
+ }
+ }
+ gc_free (&gc);
+}
+
+static void
man_connection_settings_reset (struct management *man)
{
man->connection.state_realtime = false;
@@ -937,6 +980,7 @@ man_connect (struct management *man)
goto done;
}
+ man_record_peer_info (man);
man_new_connection_post (man, "Connected to management server at");
done:
@@ -960,7 +1004,10 @@ man_reset_client_socket (struct management *man, const bool exiting)
if (!exiting)
{
if (man->settings.connect_as_client)
- throw_signal_soft (SIGTERM, "management-exit");
+ {
+ msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit");
+ throw_signal_soft (SIGTERM, "management-exit");
+ }
else
man_listen (man);
}
@@ -1199,7 +1246,8 @@ man_settings_init (struct man_settings *ms,
const int echo_buffer_size,
const int state_buffer_size,
const bool hold,
- const bool connect_as_client)
+ const bool connect_as_client,
+ const char *write_peer_info_file)
{
if (!ms->defined)
{
@@ -1233,6 +1281,7 @@ man_settings_init (struct man_settings *ms,
* rather than a server?
*/
ms->connect_as_client = connect_as_client;
+ ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL);
/*
* Initialize socket address
@@ -1269,6 +1318,7 @@ man_settings_init (struct man_settings *ms,
static void
man_settings_close (struct man_settings *ms)
{
+ free (ms->write_peer_info_file);
CLEAR (*ms);
}
@@ -1360,7 +1410,8 @@ management_open (struct management *man,
const int echo_buffer_size,
const int state_buffer_size,
const bool hold,
- const bool connect_as_client)
+ const bool connect_as_client,
+ const char *write_peer_info_file)
{
bool ret = false;
@@ -1378,7 +1429,8 @@ management_open (struct management *man,
echo_buffer_size,
state_buffer_size,
hold,
- connect_as_client);
+ connect_as_client,
+ write_peer_info_file);
/*
* The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
@@ -1678,6 +1730,18 @@ man_standalone_ok (const struct management *man)
return !man->settings.management_over_tunnel && man->connection.state != MS_INITIAL;
}
+static bool
+man_check_for_signals (volatile int *signal_received)
+{
+ if (signal_received)
+ {
+ get_signal (signal_received);
+ if (*signal_received)
+ return true;
+ }
+ return false;
+}
+
/*
* Wait for socket I/O when outside primary event loop
*/
@@ -1696,16 +1760,17 @@ man_block (struct management *man, volatile int *signal_received, const time_t e
management_socket_set (man, man->connection.es, NULL, NULL);
tv.tv_usec = 0;
tv.tv_sec = 1;
+ if (man_check_for_signals (signal_received))
+ {
+ status = -1;
+ break;
+ }
status = event_wait (man->connection.es, &tv, &esr, 1);
update_time ();
- if (signal_received)
+ if (man_check_for_signals (signal_received))
{
- get_signal (signal_received);
- if (*signal_received)
- {
- status = -1;
- break;
- }
+ status = -1;
+ break;
}
/* set SIGINT signal if expiration time exceeded */
if (expire && now >= expire)
diff --git a/manage.h b/manage.h
index 873bb42..d7ed79c 100644
--- a/manage.h
+++ b/manage.h
@@ -201,6 +201,7 @@ struct man_settings {
bool server;
bool hold;
bool connect_as_client;
+ char *write_peer_info_file;
};
/* up_query modes */
@@ -267,8 +268,8 @@ bool management_open (struct management *man,
const int echo_buffer_size,
const int state_buffer_size,
const bool hold,
- const bool connect_as_client);
-
+ const bool connect_as_client,
+ const char *write_peer_info_file);
void management_close (struct management *man);
diff --git a/options.c b/options.c
index 45d0023..2c9dbcb 100644
--- a/options.c
+++ b/options.c
@@ -1184,6 +1184,7 @@ show_settings (const struct options *o)
SHOW_BOOL (management_query_passwords);
SHOW_BOOL (management_hold);
SHOW_BOOL (management_client);
+ SHOW_STR (management_write_peer_info_file);
#endif
#ifdef ENABLE_PLUGIN
if (o->plugin_list)
@@ -1498,7 +1499,8 @@ options_postprocess (struct options *options, bool first_time)
*/
#ifdef ENABLE_MANAGEMENT
if (!options->management_addr &&
- (options->management_query_passwords || options->management_hold || options->management_client
+ (options->management_query_passwords || options->management_hold
+ || options->management_client || options->management_write_peer_info_file
|| options->management_log_history_cache != defaults.management_log_history_cache))
msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified");
#endif
@@ -3129,6 +3131,7 @@ add_option (struct options *options,
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_client = true;
+ options->management_write_peer_info_file = p[1];
}
else if (streq (p[0], "management-log-cache") && p[1])
{
diff --git a/options.h b/options.h
index ca04cab..9f8f08a 100644
--- a/options.h
+++ b/options.h
@@ -280,6 +280,7 @@ struct options
bool management_query_passwords;
bool management_hold;
bool management_client;
+ const char *management_write_peer_info_file;
#endif
#ifdef ENABLE_PLUGIN
diff --git a/service-win32/service.patch b/service-win32/service.patch
index b4b2063..8de38eb 100755
--- a/service-win32/service.patch
+++ b/service-win32/service.patch
@@ -1,5 +1,5 @@
---- service.c.orig Mon Sep 5 14:38:41 2005
-+++ service.c Tue Sep 6 13:58:52 2005
+--- service.c.orig Mon Jan 30 10:03:35 2006
++++ service.c Mon Jan 30 10:16:33 2006
@@ -16,6 +16,7 @@
service_main(DWORD dwArgc, LPTSTR *lpszArgv);
CmdInstallService();
@@ -221,9 +221,9 @@
+
+ schService = OpenService(
+ schSCManager, // SCM database
-+ "MeetrixService", // service name
++ SZSERVICENAME, // service name
+ SERVICE_ALL_ACCESS);
-+
++
+ if (schService == NULL) {
+ _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
+ ret = 1;
@@ -319,8 +319,8 @@
}
if ( lpszTemp )
---- service.h.orig Mon Sep 5 14:38:41 2005
-+++ service.h Tue Sep 6 13:58:59 2005
+--- service.h.orig Mon Jan 30 10:03:35 2006
++++ service.h Mon Jan 30 10:03:35 2006
@@ -62,13 +62,13 @@
//// todo: change to desired strings
////