Changed a lot

This commit is contained in:
2015-03-04 22:21:34 +00:00
parent cd21034b41
commit 8264cbfa7b
54 changed files with 2014 additions and 529 deletions
+18 -20
View File
@@ -5,25 +5,23 @@ using System.Text;
using System.Net.Sockets;
using System.Net;
namespace NetMonitorServer
{
abstract class ActionClass
{
protected UdpClient outputNetworkStream;
protected IPEndPoint outputNetworkPort;
internal void SetAnswerStream(UdpClient udpClient, IPEndPoint iPEndPoint)
{
this.outputNetworkStream = udpClient;
this.outputNetworkPort = iPEndPoint;
}
abstract internal bool Run(Queue<string> arguments);
protected void sendMessage(string message)
{
Console.WriteLine(message);
byte[] answ = Encoding.UTF8.GetBytes(message);
outputNetworkStream.Send(answ, answ.Length, outputNetworkPort);
}
namespace NetMonitorServer {
abstract class ActionClass {
protected UdpClient outputNetworkStream;
protected IPEndPoint outputNetworkPort;
internal void SetAnswerStream(UdpClient udpClient, IPEndPoint iPEndPoint) {
this.outputNetworkStream = udpClient;
this.outputNetworkPort = iPEndPoint;
}
abstract internal bool Run(Queue<string> arguments);
protected void sendMessage(string message) {
Console.WriteLine(message);
byte[] answ = Encoding.UTF8.GetBytes(message);
outputNetworkStream.Send(answ, answ.Length, outputNetworkPort);
}
protected ServerModel Model = ServerModel.Instance;
}
}
+157 -5
View File
@@ -5,11 +5,13 @@ using System.Text;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
namespace NetMonitorServer
{
class SetNetworks : ActionClass
{
private string netsh_output = "";
private bool setNetworkWins(Queue<string> data)
{
if (data.Count != 2)
@@ -42,7 +44,7 @@ namespace NetMonitorServer
}
string ip = data.Dequeue();
string name = data.Dequeue();
string netsh = "interface ipv4 set dnsservers name=\"" + name + (ip == "auto" ? "\" source=dhcp" : "\" static " + ip + "primary");
string netsh = "interface ipv4 set dnsservers name=\"" + name + (ip == "auto" ? "\" source=dhcp" : "\" static " + ip + " primary");
try
{
this.runProgramNetsh(netsh);
@@ -94,7 +96,7 @@ namespace NetMonitorServer
{
if (data.Count != 1)
{
this.sendMessage("To less arguments for SetNetworks.setNetworkDns class");
this.sendMessage("To less arguments for SetNetworks.setNetworkAuto class");
return false;
}
string name = data.Dequeue();
@@ -113,8 +115,155 @@ namespace NetMonitorServer
return true;
}
private bool getNetwork(Queue<string> arguments)
{
if(arguments.Count != 1) {
this.sendMessage("To less arguments for SetNetworks.getNetwork class");
return false;
}
string adapter = arguments.Dequeue();
string ip = "";
string subnet = "";
string gateway = "";
string dns = "";
string wins = "";
try
{
this.runProgramNetsh("interface ipv4 show interfaces");
string[] text = this.netsh_output.Trim().Split('\n');
foreach (string line in text)
{
string l = line.Trim();
if (l == "")
{
continue;
}
if (Regex.IsMatch(l, "disconnected[ ]+"+adapter+"$", RegexOptions.IgnoreCase))
{
this.sendMessage("disconnected");
return true;
}
}
this.runProgramNetsh("interface ipv4 show addresses");
text = this.netsh_output.Trim().Split('\n');
bool match = false;
foreach (string line in text)
{
string l = line.Trim();
if (l == "")
{
continue;
}
if (Regex.IsMatch(l, "^Konfiguration der Schnittstelle", RegexOptions.IgnoreCase))
{
match = false;
}
if (Regex.IsMatch(l, "^[a-z0-9 ]+\""+adapter+"\"", RegexOptions.IgnoreCase))
{
match = true;
}
if (match)
{
if (Regex.IsMatch(l, "DHCP aktiviert:\\s+Ja", RegexOptions.IgnoreCase))
{
ip = "auto";
break;
}
if (Regex.IsMatch(l, "IP-Adresse:\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", RegexOptions.IgnoreCase))
{
ip = Regex.Match(l, "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").ToString();
}
if (Regex.IsMatch(l, "Subnetzpräfix:\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\/[0-9]+ \\(Maske [0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\)", RegexOptions.IgnoreCase))
{
subnet = Regex.Match(l, "\\(Maske ([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)\\)").Groups[1].ToString();
}
if (Regex.IsMatch(l, "Standardgateway:\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", RegexOptions.IgnoreCase))
{
gateway = Regex.Match(l, "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").ToString();
}
}
}
this.runProgramNetsh("interface ipv4 show dnsservers");
text = this.netsh_output.Trim().Split('\n');
match = false;
foreach (string line in text)
{
string l = line.Trim();
if (l == "")
{
continue;
}
if (Regex.IsMatch(l, "^Konfiguration der Schnittstelle", RegexOptions.IgnoreCase))
{
match = false;
}
if (Regex.IsMatch(l, "^[a-z0-9 ]+\"" + adapter + "\"", RegexOptions.IgnoreCase))
{
match = true;
}
if (match)
{
if (Regex.IsMatch(l, "Über DHCP konfigurierte DNS-Server:\\s+", RegexOptions.IgnoreCase))
{
dns = "auto";
}
if (Regex.IsMatch(l, "Statisch konfigurierte DNS-Server:\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", RegexOptions.IgnoreCase))
{
dns = Regex.Match(l, "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").ToString();
}
}
}
this.runProgramNetsh("interface ipv4 show winsservers");
text = this.netsh_output.Trim().Split('\n');
match = false;
foreach (string line in text)
{
string l = line.Trim();
if (l == "")
{
continue;
}
if (Regex.IsMatch(l, "^Konfiguration der Schnittstelle", RegexOptions.IgnoreCase))
{
match = false;
}
if (Regex.IsMatch(l, "^[a-z0-9 ]+\"" + adapter + "\"", RegexOptions.IgnoreCase))
{
match = true;
}
if (match)
{
if (Regex.IsMatch(l, "Über DHCP konfigurierte WINS-Server:\\s+", RegexOptions.IgnoreCase))
{
wins = "auto";
}
if (Regex.IsMatch(l, "Statisch konfigurierte WINS-Server:\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", RegexOptions.IgnoreCase))
{
wins = Regex.Match(l, "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").ToString();
}
}
}
}
catch (Exception e)
{
this.sendMessage(e.Message);
return false;
}
if (ip == "")
{
this.sendMessage("unknown");
return false;
}
this.sendMessage("[" + ip + "|" + subnet + "|" + gateway + "|" + dns + "|" + wins + "]");
return true;
}
private bool runProgramNetsh(string args)
{
//Console.WriteLine("netsh args: "+args);
Process p = new Process();
p.StartInfo.Arguments = args;
p.StartInfo.FileName = "netsh";
@@ -122,14 +271,14 @@ namespace NetMonitorServer
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
string output = p.StandardOutput.ReadToEnd();
this.netsh_output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output.Trim());
//Console.WriteLine(this.netsh_output.Trim());
if (p.ExitCode == 0)
{
return true;
}
throw new Exception(output.Trim());
throw new Exception(this.netsh_output.Trim());
}
internal override bool Run(Queue<string> arguments)
{
@@ -144,8 +293,11 @@ namespace NetMonitorServer
case "ip": return this.setNetworkIp(arguments);
case "dns": return this.setNetworkDns(arguments);
case "wins": return this.setNetworkWins(arguments);
case "network": return this.getNetwork(arguments);
default: this.sendMessage("Wrong arguments for service on SetNetwork class"); return false;
}
}
}
}
+104 -8
View File
@@ -2,14 +2,110 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using BlubbFish.Utils;
using NetMonitorServer.Controller;
namespace NetMonitorServer
{
class SetOpenVPNService : ActionClass
{
internal override bool Run(Queue<string> arguments)
{
throw new NotImplementedException();
}
namespace NetMonitorServer {
class SetOpenVPNService : ActionClass {
internal override bool Run(Queue<string> arguments) {
if(arguments.Count < 2) {
this.sendMessage("To less arguments for SetOpenVpnService class");
return false;
}
switch(arguments.Dequeue().ToLower()) {
case "status":
return this.getVpn(arguments);
case"start":
return this.getVpnStart(arguments);
case"stop":
return this.getVpnStop(arguments);
default:
this.sendMessage("Wrong arguments for service on SetOpenVpnService class");
return false;
}
}
private bool getVpnStop(Queue<string> arguments) {
string config = arguments.Dequeue();
if(Model.openvpnInstances.Keys.Contains(config)) { //schon in der Liste
OpenVpnController o = Model.openvpnInstances[config];
if(o.HasExited) { //läuft nicht! Fehler!
this.sendMessage("Fehler! Openvpn schon beendet! " + config + " Config");
return false;
}
o.Kill();
} else { //Noch nicht in der liste
this.sendMessage("Fehler! Openvpn noch nie gestartet! " + config + " Config");
return false;
}
this.sendMessage("true");
return false;
}
private bool getVpnStart(Queue<string> arguments) {
string config = arguments.Dequeue();
if(Model.openvpnInstances.Keys.Contains(config)) { //schon in der Liste
OpenVpnController o = Model.openvpnInstances[config];
if(!o.HasExited) { //läuft noch! Fehler!
this.sendMessage("Fehler! Openvpn Läuft noch! " + config + " Config");
return false;
}
try {
o.Start();
} catch(Exception e) {
this.sendMessage("Fehler beim Starten von OpenVPN: " + e.Message);
return false;
}
this.sendMessage("true");
return true;
} else { //Noch nicht in der liste
string ovpn = InIReader.getInstance("config.ini").getValue("program", "openvpn");
ovpn = (ovpn.EndsWith("\\")) ? ovpn : ovpn + "\\";
try {
OpenVpnController o = new OpenVpnController(ovpn, config);
Model.openvpnInstances.Add(config, o);
o.Start();
} catch(Exception e) {
this.sendMessage("Fehler beim Starten von OpenVPN: " + e.Message);
return false;
}
this.sendMessage("true");
return true;
}
}
private bool getVpn(Queue<string> arguments) {
if(arguments.Count != 1) {
this.sendMessage("To less arguments for SetOpenVpnService.getVpn class");
return false;
}
string config = arguments.Dequeue();
string run = "";
try {
if(Model.openvpnInstances.Keys.Contains(config)) {
OpenVpnController o = Model.openvpnInstances[config];
if(o.HasExited) {
run = "disconnected";
} else if(o.Conntected) {
run = "connected|" + o.Ip + "|" + o.Dhcp + "|" + o.DhcpLease + "|" + o.IpDate + "|" + o.SuccessDate;
} else {
run = "conntecting";
}
}
} catch(Exception e) {
this.sendMessage(e.Message);
return false;
}
if(run == "") {
this.sendMessage("unknown");
return false;
}
this.sendMessage("[" + run + "]");
return true;
}
}
}
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
namespace NetMonitorServer.Controller {
class OpenVpnController {
private Process proc;
public bool HasExited { get; private set; }
public bool Conntected { get; private set; }
public string Error { get; private set; }
public string Ip { get; private set; }
public string Dhcp { get; private set; }
public string DhcpLease { get; private set; }
public string IpDate { get; private set; }
public string SuccessDate { get; private set; }
public OpenVpnController(string path, string config) {
// TODO: Complete member initialization
this.proc = new Process();
this.proc.StartInfo.Arguments = "--config " + config;
this.proc.StartInfo.FileName = path + "bin\\openvpn.exe";
this.proc.StartInfo.WorkingDirectory = path + "config";
this.HasExited = true;
this.Conntected = false;
this.Error = "";
}
private void VpnOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) {
if(!String.IsNullOrEmpty(outLine.Data)) {
string pattern = "^(.*?) N.*?IP/netmask of ([0-9\\./]*).*?DHCP-serv: ([0-9\\.]*).*?lease-time: ([0-9]*)";
Match match = Regex.Match(outLine.Data, pattern);
if(match.Success) {
this.IpDate = match.Groups[1].Value;
this.Ip = match.Groups[2].Value;
this.Dhcp = match.Groups[3].Value;
this.DhcpLease = match.Groups[4].Value;
}
pattern = "^(.*?) Initialization Sequence Completed";
match = Regex.Match(outLine.Data, pattern);
if(match.Success) {
this.SuccessDate = match.Groups[1].Value;
this.Conntected = true;
}
//Console.WriteLine("L: |" + outLine.Data + "|");
}
}
private void VpnErrorHandler(object sendingProcess, DataReceivedEventArgs outLine) {
this.Error += outLine.Data;
}
internal bool Start() {
if(!this.HasExited) {
return false;
}
this.HasExited = false;
this.Conntected = false;
this.Error = "";
this.proc.StartInfo.UseShellExecute = false;
this.proc.StartInfo.RedirectStandardOutput = true;
this.proc.StartInfo.RedirectStandardError = true;
this.proc.StartInfo.RedirectStandardInput = true;
this.proc.OutputDataReceived += new DataReceivedEventHandler(VpnOutputHandler);
this.proc.ErrorDataReceived += new DataReceivedEventHandler(VpnErrorHandler);
this.proc.Start();
this.proc.BeginOutputReadLine();
this.proc.BeginErrorReadLine();
return true;
}
internal bool Kill() {
this.proc.CancelErrorRead();
this.proc.CancelOutputRead();
this.proc.Kill();
this.proc.WaitForExit();
this.HasExited = true;
this.Conntected = false;
return true;
}
}
}
+14 -17
View File
@@ -4,22 +4,19 @@ using System.Linq;
using System.Text;
using BlubbFish.Utils;
namespace NetMonitorServer
{
class Factory
{
internal static ActionClass getAction(string className)
{
if (className.Substring(0, 3).ToLower() == "net")
return new SetNetworks();
if (className.Substring(0, 7).ToLower() == "service")
return new SetService();
if (className.Substring(0, 7).ToLower() == "openvpn")
return new SetOpenVPNService();
return null;
}
internal static InIReader getSettings() {
return InIReader.getInstance("config.ini");
}
namespace NetMonitorServer {
class Factory {
internal static ActionClass getAction(string className) {
if(className.ToLower() == "net")
return new SetNetworks();
if(className.ToLower() == "service")
return new SetService();
if(className.ToLower() == "openvpn")
return new SetOpenVPNService();
return null;
}
internal static InIReader getSettings() {
return InIReader.getInstance("config.ini");
}
}
}
+42 -7
View File
@@ -14,6 +14,21 @@
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<PublishUrl>veröffentlichen\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -43,6 +58,9 @@
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration.Install" />
@@ -57,6 +75,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ActionClass.cs" />
<Compile Include="Controller\OpenVpnController.cs" />
<Compile Include="Factory.cs" />
<Compile Include="Actions\SetOpenVPNService.cs" />
<Compile Include="Actions\SetService.cs" />
@@ -71,19 +90,13 @@
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Actions\SetNetworks.cs" />
<Compile Include="ServerModel.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MainService.resx">
<DependentUpon>MainService.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="ClassDiagram1.cd" />
<None Include="config.ini">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
@@ -93,6 +106,28 @@
<Name>Utils</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.manifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -2,8 +2,20 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<StartArguments>-r</StartArguments>
<StartAction>Program</StartAction>
<StartProgram>D:\Visual Studio 2012\Projects\netmonitor\bin\Debug\NetMonitorServer.exe</StartProgram>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<StartArguments>-r</StartArguments>
</PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>veröffentlichen\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>de-DE</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>
+31
View File
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using NetMonitorServer.Controller;
namespace NetMonitorServer {
class ServerModel {
private static volatile ServerModel instance;
private static object syncRoot = new Object();
public static ServerModel Instance {
get {
if(instance == null) {
lock(syncRoot) {
if(instance == null)
instance = new ServerModel();
}
}
return instance;
}
}
private ServerModel() {
openvpnInstances = new Dictionary<string, OpenVpnController>();
}
/// <summary>
/// Openvpn Instanzen Dictionary
/// </summary>
public Dictionary<string, OpenVpnController> openvpnInstances;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC-Manifestoptionen
Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den
requestedExecutionLevel-Knoten durch eines der folgenden Elemente.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert.
Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts-
kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<!-- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application> -->
<!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist.
Windows wählt automatisch die am stärksten kompatible Umgebung aus.-->
<!-- Wenn die Anwendung mit Windows Vista kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
<!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
<!-- Wenn die Anwendung mit Windows 8 kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
<!-- </application>
</compatibility> -->
<!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>
-4
View File
@@ -1,4 +0,0 @@
[ports]
server=54323
client_from=54330
client_to=54340