Skip to content

Instantly share code, notes, and snippets.

@cmpunches
Last active September 6, 2015 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmpunches/0118f4eacd5ca808d8fb to your computer and use it in GitHub Desktop.
Save cmpunches/0118f4eacd5ca808d8fb to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
/*
We want any connection client to be able to set it's proxy settings to 127.0.0.1:1337
We then want to route any incoming connections iteratively through a list of IP:Port entries in a configuration file delimited by newline.
If a connection fails, it will iterate to the next IP:Port on the next line.
Far from complete.
*/
namespace ConsoleProxyBouncer
{
/* OutConnection object creates a TCPListener and a TCPClient object and then manages them as a unified connection */
class OutConnection
{
public OutConnection()
{
TcpListener ThisListener = new TcpListener(this.ListenAddress, this.ListenPort);
}
// for the client
public string Protocol
{
get
{
return Protocol;
}
set
{
Protocol = value;
}
}
public IPAddress DestinationAddress
{
get
{
return DestinationAddress;
}
set
{
DestinationAddress = value;
}
}
public int DestinationPort
{
get
{
return DestinationPort;
}
set
{
DestinationPort = value;
}
}
// below for the listener
public int ListenPort
{
get
{
return ListenPort;
}
set
{
ListenPort = value;
}
}
// 127.0.0.1, this will probably end up const
public IPAddress ListenAddress
{
get
{
return ListenAddress;
}
set
{
ListenAddress = value;
}
}
// checks to see if all the properties that should be set are set
public bool CanConnect
{
get
{
}
set
{
// you can't set this
}
}
// return true if both the tcplistener and the tcpclient are connected
public bool IsConnected
{
get;
set;
}
public void Listen()
{
}
}
class Program
{
private void Throw(int ExitCode, string msg, params object[] args)
{
Console.WriteLine(String.Format(msg, args));
Environment.Exit(ExitCode);
}
// deal with the configuration
private bool IsValidIp(string addr)
{
IPAddress ip;
bool valid = !string.IsNullOrEmpty(addr) && IPAddress.TryParse(addr, out ip);
return valid;
}
private bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (char.IsDigit(c))
return false;
}
return true;
}
private OutConnection CreateConnectionHandleFromLine (string line)
{
/* expected line string format:
"TCP 123.123.123.123 9999" |
"TCP 9999 123.123.123.123" |
"123.123.123.123 9999 TCP" |
"123.123.123.123 TCP 9999" |
"9999 123.123.123.123 TCP" |
"9999 TCP 123.123.123.123"
Tabs, commas, or spaces allowed.
*/
// normalize whitespace
line = line.Replace(",", "\t");
line = line.Replace(" ", "\t");
line = line.Replace("\t\t", "\t");
// then split into a string array by tab character
string[] properties = line.Split('\t');
OutConnection NewConn = new OutConnection();
foreach (string property in properties)
{
if (IsValidIp(property))
{
// It's an IP Address.
// what a stupid way to do this
IPAddress bsval = null;
IPAddress.TryParse(property, out bsval);
// then it's an outbound IP Address, treat ityeah as such
NewConn.DestinationAddress = bsval;
}
else if (IsDigitsOnly(property))
{
// It's a port designation
NewConn.DestinationPort = Convert.ToInt32(property);
}
else if (property.Equals("TCP"))
{
// Use a TCP connection.
// Alternate UDP is not currently supported yet.
NewConn.Protocol = "TCP";
}
/* now that all the properties we're looking for from the config file are set let's see if anything went wrong
and exit if it did, return the connection if not. */
if (NewConn.CanConnect)
{
// these are instantiated but are not turned on
return NewConn;
} else {
Throw(-1, "Failed to set all the needed properties to one of the OutConnection objects.");
}
}
// This will never execute but the requirement for this line requires this line simply because it requires this line.
// HandledErrorThrow("There's a logic error in CreateConnectionHandleFromLine()", -1);
return NewConn;
}
private List<OutConnection> getProxyEntries(string filePath)
{
List<OutConnection> SocketPairs = new List<OutConnection>();
// read teh config file into a string array
string[] ConfigFile = File.ReadAllLines(@"filePath");
// for each line create a new OutConnection object and append it to a list of connection objectsro
foreach (string line in ConfigFile)
{
SocketPairs.Add(CreateConnectionHandleFromLine(line));
}
return SocketPairs;
}
public int Main(string[] args)
{
List<OutConnection> ConnectionCollection = getProxyEntries(@"C:\proxies.txt");
foreach (OutConnection Connection in ConnectionCollection)
{
if (Connection.CanConnect)
{
// wait for the connection
Connection.Listen();
while (Connection.IsConnected)
{
// do nothing, just keep rechecking until it's no longer connected
}
// once that's done, it'll iterate to the next one.
}
else
{
Throw(-1, "The connection to {0}:{1} cannot be made as the result of either a configuration or parsing issue.", Connection.DestinationAddress, Connection.DestinationPort);
}
}
return 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment