240 lines
9.1 KiB
C#
240 lines
9.1 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace MelonVPNCore
|
|
{
|
|
public static class DaemonSocketServer
|
|
{
|
|
private static Process currentVpnProcess = null;
|
|
private static bool shouldBeRunning = false;
|
|
private static bool shouldRestart = false;
|
|
private static bool isRestarting = false;
|
|
private static int startingTime = 3000;
|
|
private static int restartDelay = 250;
|
|
private static DaemonServer _srv;
|
|
private static DaemonClientMultiplexor _mlt;
|
|
private static string lastClientUpdate = Messages.EOF;
|
|
|
|
public static void StartServer()
|
|
{
|
|
_srv = new DaemonServer();
|
|
_mlt = new DaemonClientMultiplexor(_srv);
|
|
_mlt.clientMessageReceived += clientMessageReceived;
|
|
_srv.start();
|
|
}
|
|
|
|
public static bool isProcessOnline(Process p)
|
|
{
|
|
if (p == null)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (p.HasExited)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void clientMessageReceived(object sender, string data)
|
|
{
|
|
try
|
|
{
|
|
if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture) && shouldBeRunning)
|
|
{
|
|
lastClientUpdate = data;
|
|
_mlt.SendCustomMessage(lastClientUpdate);
|
|
}
|
|
else if (data == Messages.RestartOnMsg)
|
|
{
|
|
shouldRestart = true;
|
|
_mlt.SendDataMessage(DataMessage.RestartOn);
|
|
}
|
|
else if (data == Messages.RestartOffMsg)
|
|
{
|
|
shouldRestart = false;
|
|
_mlt.SendDataMessage(DataMessage.RestartOff);
|
|
}
|
|
else if (data == Messages.StatusMsg)
|
|
{
|
|
Console.WriteLine("Status requested");
|
|
if (isProcessOnline(currentVpnProcess) || shouldBeRunning)
|
|
{
|
|
if (isRestarting)
|
|
{
|
|
Console.WriteLine("Sending response: restarting");
|
|
_mlt.SendDataMessage(DataMessage.Restarting);
|
|
_mlt.SendCustomMessage(lastClientUpdate);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Sending response: online");
|
|
_mlt.SendDataMessage(DataMessage.Online);
|
|
_mlt.SendCustomMessage(lastClientUpdate);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Sending response: offline");
|
|
_mlt.SendDataMessage(DataMessage.Offline);
|
|
_mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
|
|
}
|
|
_mlt.SendDataMessage((shouldRestart) ? DataMessage.RestartOn : DataMessage.RestartOff);
|
|
}
|
|
else if (data == Messages.StartMsg)
|
|
{
|
|
if (!isProcessOnline(currentVpnProcess))
|
|
{
|
|
shouldBeRunning = true;
|
|
Console.WriteLine("Starting VPN");
|
|
try
|
|
{
|
|
Console.WriteLine("Starting embedded process");
|
|
Console.WriteLine("Sending starting reply");
|
|
_mlt.SendDataMessage(DataMessage.Starting);
|
|
if (StartEProcess(true))
|
|
{
|
|
Console.WriteLine("Sending online reply");
|
|
_mlt.SendDataMessage(DataMessage.Online);
|
|
currentVpnProcess.EnableRaisingEvents = true;
|
|
}
|
|
else { throw new InvalidOperationException("Client crashed!"); }
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
shouldBeRunning = false;
|
|
Console.WriteLine("There was an error. But I fixed it.");
|
|
Console.WriteLine("It looked like this: " + e);
|
|
currentVpnProcess.Dispose();
|
|
currentVpnProcess = null;
|
|
_mlt.SendDataMessage(DataMessage.Error);
|
|
_mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("VPN already started");
|
|
}
|
|
}
|
|
else if (data == Messages.StopMsg)
|
|
{
|
|
shouldBeRunning = false;
|
|
bool haderr = false;
|
|
if (isProcessOnline(currentVpnProcess))
|
|
{
|
|
Console.WriteLine("Stopping VPN");
|
|
try
|
|
{
|
|
currentVpnProcess.EnableRaisingEvents = false;
|
|
Console.WriteLine("Stopping embedded process");
|
|
currentVpnProcess.Kill();
|
|
currentVpnProcess = null;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("There was an error. But I fixed it.");
|
|
Console.WriteLine("It looked like this: " + e);
|
|
currentVpnProcess = null;
|
|
_mlt.SendDataMessage(DataMessage.Error);
|
|
_mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
|
|
haderr = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("VPN already stopped");
|
|
}
|
|
if (!haderr)
|
|
{
|
|
Console.WriteLine("Sending offline reply");
|
|
_mlt.SendDataMessage(DataMessage.Offline);
|
|
_mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
|
|
}
|
|
}
|
|
|
|
_mlt.SendDataMessage(DataMessage.Blank);
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
}
|
|
}
|
|
|
|
|
|
static void CurrentVpnProcess_Exited(object sender, EventArgs e)
|
|
{
|
|
Console.WriteLine("Restarting embedded process");
|
|
currentVpnProcess.Dispose();
|
|
currentVpnProcess = null;
|
|
Thread.Sleep(restartDelay);
|
|
bool imonline = false;
|
|
isRestarting = true;
|
|
while (shouldRestart && shouldBeRunning)
|
|
{
|
|
Console.WriteLine("Sending restarting reply");
|
|
_mlt.SendDataMessage(DataMessage.Restarting);
|
|
if (StartEProcess(false))
|
|
{
|
|
Console.WriteLine("Sending online reply");
|
|
_mlt.SendDataMessage(DataMessage.Online);
|
|
currentVpnProcess.EnableRaisingEvents = true;
|
|
imonline = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
currentVpnProcess.Dispose();
|
|
currentVpnProcess = null;
|
|
Thread.Sleep(restartDelay);
|
|
}
|
|
}
|
|
isRestarting = false;
|
|
if (! imonline)
|
|
{
|
|
shouldBeRunning = false;
|
|
Console.WriteLine("Sending offline reply");
|
|
_mlt.SendDataMessage(DataMessage.Offline);
|
|
_mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
|
|
}
|
|
}
|
|
|
|
static bool StartEProcess(bool reraisee)
|
|
{
|
|
if (shouldBeRunning)
|
|
{
|
|
try
|
|
{
|
|
currentVpnProcess = new Process
|
|
{
|
|
StartInfo = new ProcessStartInfo("simple-vpn", "client /etc/melon-vpn/client.cfg"),
|
|
EnableRaisingEvents = false
|
|
};
|
|
currentVpnProcess.Exited += CurrentVpnProcess_Exited;
|
|
currentVpnProcess.Start();
|
|
Thread.Sleep(startingTime);
|
|
return !currentVpnProcess.HasExited;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//Not really fixed is it?
|
|
Console.WriteLine("There was an error. But I fixed it.");
|
|
Console.WriteLine("It looked like this: " + e);
|
|
if (reraisee) { throw e; }
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|