117 lines
3.6 KiB
C#
117 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO.Pipes;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using cloud.insecurity.http;
|
|
using log4net;
|
|
|
|
|
|
namespace cloud.insecurity.docker.ipam
|
|
{
|
|
internal class Ipam
|
|
{
|
|
private static log4net.ILog Log
|
|
{
|
|
get
|
|
{
|
|
return log4net.LogManager.GetLogger(typeof(Ipam));
|
|
}
|
|
}
|
|
internal static void Main(string[] args)
|
|
{
|
|
Task<Task> UnixSocketProxy;
|
|
log4net.Config.XmlConfigurator.Configure();
|
|
|
|
var tasks = new Task<Task>[]
|
|
{
|
|
HttpServer.Server.Start(new string[]
|
|
{
|
|
@"http://127.0.0.1:65467/",
|
|
}),
|
|
ProxyRequestsFromUnixSocket()
|
|
};
|
|
|
|
Console.CancelKeyPress += (sender, eventArgs) =>
|
|
{
|
|
Console.WriteLine("shutting down, waiting for unfinished tasks..");
|
|
HttpServer.Server.Stop();
|
|
tasks.ToList().ForEach(t => t.Wait());
|
|
Environment.Exit(0);
|
|
};
|
|
|
|
cKey:
|
|
switch (Console.ReadKey())
|
|
{
|
|
default:
|
|
goto cKey;
|
|
}
|
|
}
|
|
|
|
private static async Task<Task> ProxyRequestsFromUnixSocket()
|
|
{
|
|
var listeningPort = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
|
|
var endPoint = new UnixDomainSocketEndPoint(@"/run/cloud.insecurity.docker/ipam.sock");
|
|
|
|
listeningPort.Bind(endPoint);
|
|
listeningPort.Listen(0);
|
|
|
|
ManualResetEvent AcceptFinished = new ManualResetEvent(false);
|
|
|
|
while (HttpServer.Server.Running)
|
|
{
|
|
listeningPort.BeginAccept(ConnectionAccepted,
|
|
new Tuple<Socket, ManualResetEvent>(listeningPort, AcceptFinished));
|
|
|
|
AcceptFinished.WaitOne();
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private static void ConnectionAccepted(IAsyncResult ar)
|
|
{
|
|
ManualResetEvent ReceiveFinished = new ManualResetEvent(false);
|
|
|
|
var socket = (ar.AsyncState as Tuple<Socket, ManualResetEvent>)?.Item1;
|
|
var finished = (ar.AsyncState as Tuple<Socket, ManualResetEvent>)?.Item2;
|
|
var ProxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
|
|
ProxySocket.Connect(new IPEndPoint(0x7f000001, 0xffbb));
|
|
|
|
var buffer = new List<ArraySegment<byte>>();
|
|
bool ReceivedFromClient = false;
|
|
|
|
recv:
|
|
while (!Encoding.UTF8.GetString(buffer.SelectMany(bytes => bytes)
|
|
.ToArray())
|
|
.EndsWith("\r\n\r\n"))
|
|
{
|
|
(ReceivedFromClient ? ProxySocket : socket)?.BeginReceive(buffer,
|
|
SocketFlags.None, result =>
|
|
{
|
|
(result.AsyncState as ManualResetEvent)?.Set();
|
|
}, ReceiveFinished);
|
|
|
|
ReceiveFinished.WaitOne();
|
|
}
|
|
|
|
if (ReceivedFromClient)
|
|
{
|
|
socket?.Send(buffer);
|
|
finished?.Set();
|
|
}
|
|
else
|
|
{
|
|
ProxySocket.Send(buffer);
|
|
buffer = new List<ArraySegment<byte>>();
|
|
ReceivedFromClient = true;
|
|
goto recv;
|
|
}
|
|
}
|
|
}
|
|
} |