22using System . Collections . Generic ;
33using System . Diagnostics ;
44using System . IO ;
5+ using System . IO . Pipes ;
56using System . Linq ;
67using System . Text ;
78using 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