/// <summary> /// Start listener at selected port, accept connections and create remote socket. This function is blocking one. /// </summary> /// <param name="listenerInterface">local, client side interface</param> /// <param name="outgoingInterface">local, remote server side interface</param> /// <param name="listenerPort">port for both interfaces</param> /// <param name="listNo">listener number</param> public static void RunListener(IPAddress listenerInterface, int listenerPort) { listeners = ArrayList.Synchronized(listeners); sockets = ArrayList.Synchronized(sockets); TcpListener listener = new TcpListener(listenerInterface, listenerPort); listeners.Add(listener); listener.Start(); Console.WriteLine("started at {0}:{1}", listenerInterface.ToString(), listenerPort); while (true) { Socket incoming_socket = listener.AcceptSocket(); var endPoint = (IPEndPoint)incoming_socket.RemoteEndPoint; IPAddress outgoingInterface = endPoint.Address; int listNo = endPoint.Port; Console.WriteLine("listener {0} is waiting for a new client", listNo); Console.WriteLine("listener {0}: client connected", listNo); // connecting remote host Console.WriteLine("listener {0} is connecting to remote host {1}:{2}", listNo, TARGET_IPADDR, listenerPort); Socket remote_socket = ConnectSocket(new IPEndPoint(outgoingInterface, 0), TARGET_IPADDR, listenerPort); if (remote_socket == null) { Console.WriteLine("listener {0}: outgoing connection failed", listNo); continue; } Console.WriteLine("listener {0}: connected to remote host {1}:{2}", listNo, TARGET_IPADDR, listenerPort); // begin receive on input SocketStateObj iso = new SocketStateObj(incoming_socket, remote_socket); sockets.Add(iso); incoming_socket.BeginReceive(iso.buffer, 0, SocketStateObj.BUFF_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), iso); // begin receive on output SocketStateObj oso = new SocketStateObj(remote_socket, incoming_socket); sockets.Add(oso); remote_socket.BeginReceive(oso.buffer, 0, SocketStateObj.BUFF_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), oso); } }
private static void Read_Callback(IAsyncResult ar) { Socket s1 = null; Socket s2 = null; try { // retrieve SocketStateObj SocketStateObj so = (SocketStateObj)ar.AsyncState; s1 = so.in_socket; s2 = so.out_socket; int count = s1.EndReceive(ar); if (count > 0) { // copy of buffer data byte[] tmpbuff = new byte[PACKET_BUFFSIZE]; so.buffer.CopyTo(tmpbuff, 0); // async. wait for next packet s1.BeginReceive(so.buffer, 0, SocketStateObj.BUFF_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), so); // <-- packet filtering --> #region show packet info Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("[{0}] packet {1} -> S: {2} D: {3} len: {4}", DateTime.Now.ToString("HH:mm:ss"), packet_no++, s2.LocalEndPoint.ToString(), s1.LocalEndPoint.ToString(), count); Console.ResetColor(); #endregion // send packet to destination (if not filtered) s2.Send(tmpbuff, 0, count, SocketFlags.None); // <-- packet injection or re-sending --> } else { // close connections if packet has empty data Console.WriteLine("connection {0} <-> {1} closed", s2.LocalEndPoint.ToString(), s1.LocalEndPoint.ToString()); s1.Close(); s2.Close(); } } catch (Exception ex) { // <-- socket exception handling code --> //Console.WriteLine("Read_Callback exception: {0}", ex.Message); try { s1.Close(); s2.Close(); } catch (Exception) { } } }