Skip to content

Commit ae899ac

Browse files
committed
Use interactice service to start openvpn process
Instead of starting openvpn process directly: - connect to interactive service pipe - send startup info - read openvpn process pid (for watchdog) GitHub: #23 Signed-off-by: Lev Stipakov <[email protected]>
1 parent 6b6b1e6 commit ae899ac

File tree

1 file changed

+39
-49
lines changed

1 file changed

+39
-49
lines changed

OpenVPNChild.cs

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.IO;
5+
using System.IO.Pipes;
56
using System.Linq;
67
using System.Text;
78
using System.Threading;
@@ -11,9 +12,8 @@ namespace OpenVpn
1112
{
1213
class OpenVpnChild
1314
{
14-
StreamWriter logFile;
15+
string logFile;
1516
Process process;
16-
ProcessStartInfo startInfo;
1717
System.Timers.Timer restartTimer;
1818
OpenVpnServiceConfiguration config;
1919
string configFile;
@@ -28,42 +28,14 @@ public OpenVpnChild(OpenVpnServiceConfiguration config, string configFile)
2828
this.configFile = String.Copy(configFile);
2929
this.exitEvent = Path.GetFileName(configFile) + "_" + Process.GetCurrentProcess().Id.ToString();
3030
var justFilename = System.IO.Path.GetFileName(configFile);
31-
var logFilename = config.logDir + "\\" +
32-
justFilename.Substring(0, justFilename.Length - config.configExt.Length) + ".log";
31+
logFile = config.logDir + "\\" + justFilename.Substring(0, justFilename.Length - config.configExt.Length) + ".log";
32+
3333

3434
// FIXME: if (!init_security_attributes_allow_all (&sa))
3535
//{
3636
// MSG (M_SYSERR, "InitializeSecurityDescriptor start_" PACKAGE " failed");
3737
// goto finish;
3838
//}
39-
40-
logFile = new StreamWriter(File.Open(logFilename,
41-
config.logAppend ? FileMode.Append : FileMode.Create,
42-
FileAccess.Write,
43-
FileShare.Read), new UTF8Encoding(false));
44-
logFile.AutoFlush = true;
45-
46-
/// SET UP PROCESS START INFO
47-
string[] procArgs = {
48-
"--config",
49-
"\"" + configFile + "\"",
50-
"--service ",
51-
"\"" + exitEvent + "\"" + " 0"
52-
};
53-
this.startInfo = new System.Diagnostics.ProcessStartInfo()
54-
{
55-
RedirectStandardInput = true,
56-
RedirectStandardOutput = true,
57-
RedirectStandardError = true,
58-
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
59-
60-
FileName = config.exePath,
61-
Arguments = String.Join(" ", procArgs),
62-
WorkingDirectory = config.configDir,
63-
64-
UseShellExecute = false,
65-
/* create_new_console is not exposed -- but we probably don't need it?*/
66-
};
6739
}
6840

6941
// set exit event so that openvpn will terminate
@@ -129,7 +101,6 @@ public void StopProcess(int timeout)
129101
public void Wait()
130102
{
131103
process.WaitForExit();
132-
logFile.Close();
133104
}
134105

135106
public void Restart()
@@ -158,12 +129,6 @@ public void Restart()
158129
}
159130
}
160131

161-
private void WriteToLog(object sendingProcess, DataReceivedEventArgs e)
162-
{
163-
if (e != null)
164-
logFile.WriteLine(e.Data);
165-
}
166-
167132
/// Restart after 10 seconds
168133
/// For use with unexpected terminations
169134
private void Watchdog(object sender, EventArgs e)
@@ -193,21 +158,46 @@ private void FastRestart(object sender, EventArgs e)
193158
restartTimer.Start();
194159
}
195160

161+
private const string PipeName = @"openvpn\service";
162+
196163
public void Start()
197164
{
198-
process = new System.Diagnostics.Process();
165+
using (var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
166+
{
167+
config.LogMessage("Connecting to iservice pipe...");
168+
pipeClient.Connect(5000);
169+
170+
using (var writer = new BinaryWriter(pipeClient, Encoding.Unicode))
171+
using (var reader = new StreamReader(pipeClient, Encoding.Unicode))
172+
{
173+
// send startup info
174+
var logOption = config.logAppend ? "--log-append " : "--log";
175+
var cmdLine = $"--config \"{configFile}\" {logOption} \"{logFile}\" --service \"{exitEvent}\" 0 --pull-filter ignore route-method";
176+
177+
// config_dir + \0 + options + \0 + password + \0
178+
var startupInfo = $"{config.configDir}\0{cmdLine}\0\0";
199179

200-
process.StartInfo = startInfo;
201-
process.EnableRaisingEvents = true;
180+
byte[] messageBytes = Encoding.Unicode.GetBytes(startupInfo);
181+
writer.Write(messageBytes);
182+
writer.Flush();
202183

203-
process.OutputDataReceived += WriteToLog;
204-
process.ErrorDataReceived += WriteToLog;
205-
process.Exited += Watchdog;
184+
config.LogMessage("Sent startupInfo to iservice");
206185

207-
process.Start();
208-
process.BeginErrorReadLine();
209-
process.BeginOutputReadLine();
210-
process.PriorityClass = config.priorityClass;
186+
// read openvpn process pid from the pipe
187+
string[] lines = { reader.ReadLine(), reader.ReadLine() };
188+
189+
config.LogMessage($"Read from iservice: {string.Join(" ", lines)}");
190+
var errorCode = Convert.ToInt32(lines[0], 16);
191+
var pid = Convert.ToInt32(lines[1], 16);
192+
193+
process = Process.GetProcessById(pid);
194+
process.PriorityClass = config.priorityClass;
195+
process.EnableRaisingEvents = true;
196+
process.Exited += Watchdog;
197+
198+
config.LogMessage($"Add watchdog for openvpn process, pid {pid}");
199+
}
200+
}
211201
}
212202
}
213203
}

0 commit comments

Comments
 (0)