I have a proxy program which resend network traffic. It listens specific port, and addresses server with another port. It works, but I need to add some encryption between 2 instances of my proxy. When encryption is not enabled two sequential proxy work good, but with encryption don't work. Here is code:
public class CommunicationContext
开发者_StackOverflow社区{
/// <summary>Define buffer max size. Influence on memory usage.</summary>
public const int MaxBuffer = 16 * 1024;
/// <summary>Unique counter...</summary>
private static int _uniqueCounter = 0;
public readonly Socket SocketIn;
public readonly Socket SocketOut;
public readonly PortMapping Mapping;
public byte[] BufferIn;
public byte[] BufferOut;
public bool IsShutdown;
public readonly object SyncObject = new object();
public readonly int UniqueId;
public CommunicationContext(Socket socketIn, Socket socketOut, PortMapping map){
SocketIn = socketIn;
SocketOut = socketOut;
Mapping = map;
UniqueId = Interlocked.Increment( ref _uniqueCounter );
}
public void InitializeBuffers(){
this.BufferIn = new byte[MaxBuffer];
this.BufferOut = new byte[MaxBuffer];
}
}
private static void ReadInputSocket( IAsyncResult ar ){
CommunicationContext context = (CommunicationContext)ar.AsyncState;
try{
int length = context.SocketIn.EndReceive( ar );
if( length <= 0 )
throw new NoDataSocketException();
lock( context.SyncObject ){
Switches.GeneralLog.Verbose( "==> Client data size: " + length );
SocketFlags flags = ( context.SocketIn.Available == 0 ) ? SocketFlags.None : SocketFlags.Partial;
if(!CryptoTools.CryptEnabled){
//without encrypion works fine
}
else if(CryptoTools.CryptInner){
context.BufferIn = CryptoTools.Crypt(context.BufferIn);
}else{
context.BufferIn = CryptoTools.Decrypt(context.BufferIn);
}
context.SocketOut.Send(context.BufferIn, 0, length, flags);
}
Thread.Sleep( 0 );
context.SocketIn.BeginReceive(context.BufferIn, 0, MaxBuffer, SocketFlags.None, ReadInputSocket, context);
}
catch( Exception ex ){
Switches.GeneralLog.Verbose( ex );
Switches.GeneralLog.Info( ex.Message );
ShutdownCommunication( context );
}
}
private static void ReadOutputSocket(IAsyncResult ar ){
CommunicationContext context = (CommunicationContext)ar.AsyncState;
try{
int length = context.SocketOut.EndReceive( ar);
if( length <= 0 )
throw new NoDataSocketException();
lock( context.SyncObject )
{
Switches.GeneralLog.Verbose( "<== Server data size: " + length );
SocketFlags flags = ( context.SocketOut.Available == 0 ) ? SocketFlags.None : SocketFlags.Partial;
if (!CryptoTools.CryptEnabled){
//without encrypion works fine
}
else if (CryptoTools.CryptInner){
context.BufferOut = CryptoTools.Decrypt(context.BufferOut);
}
else{
context.BufferOut = CryptoTools.Crypt(context.BufferOut);
}
context.SocketIn.Send(context.BufferOut, 0, length, flags);
}
context.SocketOut.BeginReceive(context.BufferOut, 0, MaxBuffer, SocketFlags.None, ReadOutputSocket, context);
}
catch( Exception ex )
{
Switches.GeneralLog.Verbose( ex );
Switches.GeneralLog.Info( ex.Message );
ShutdownCommunication( context );
}
}
Edit from comments:
What not works: Data keep getting corrupted.
I get no exceptions. Just malformed data. I used different methods for Crypt/Decrypt. I made them even both equal - simple XOR. Encryption algorithm has not significance, for example, XOR was used.
My configuration is like this Client <--> Proxy1 <--enc--> Proxy2 <---> Server
. Between two proxies must be the encrypted stream.
精彩评论