Last active
September 6, 2015 05:58
-
-
Save cmpunches/0118f4eacd5ca808d8fb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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