cloud.insecurity.docker/cloud.insecurity.docker.ipam/Ipam.cs

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;
}
}
}
}