/// <summary> /// Create a UDP header which will be added to the head of the udp payload /// </summary> /// <param name="realEndPoint"> /// The real IP endpoint that udp payload should be sent to /// </param> /// <returns> /// bytes of the udp header /// </returns> public static byte[] CreateUdpHeader(IPEndPoint realEndPoint) { int headerStructLength = Marshal.SizeOf(typeof(LspUdpHeader)); LspUdpHeader udpHeader = new LspUdpHeader(); udpHeader.Port = realEndPoint.Port; udpHeader.AddressFamily = (int)realEndPoint.AddressFamily; string strAddress = realEndPoint.Address.ToString(); byte[] addressBytes = System.Text.Encoding.ASCII.GetBytes(strAddress); udpHeader.HeaderLength = headerStructLength + addressBytes.Length; //write header and address to a byte array IntPtr p = Marshal.AllocHGlobal(headerStructLength); Marshal.StructureToPtr(udpHeader, p, true); byte[] ret = new byte[headerStructLength + addressBytes.Length]; Marshal.Copy(p, ret, 0, headerStructLength); Marshal.FreeHGlobal(p); Array.Copy(addressBytes, 0, ret, headerStructLength, addressBytes.Length); return(ret); }
public static void Visit( IVisitorUdpReceiveLoop host, ITransport server, UdpClient udpClient, ThreadManager thread, bool isLspHooked) { byte[] data = null; // get the endpoint of tcp client. IPEndPoint localEP = host.LspHookedLocalEP; while (!thread.ShouldExit) { try { // received data from server. IPEndPoint remoteEP = null; data = udpClient.Receive(ref remoteEP); if (data == null) { break; } if (isLspHooked) { int numBytesReceived = data.Length; if (numBytesReceived < Marshal.SizeOf(typeof(LspUdpHeader))) { throw new FormatException("Invalid LSP udp packet received"); } //Get udp header byte[] udpHeaderBuffer = ArrayUtility.SubArray(data, 0, Marshal.SizeOf(typeof(LspUdpHeader))); IntPtr p = Marshal.AllocHGlobal(udpHeaderBuffer.Length); Marshal.Copy(udpHeaderBuffer, 0, p, udpHeaderBuffer.Length); LspUdpHeader udpHeader = (LspUdpHeader)Marshal.PtrToStructure(p, typeof(LspUdpHeader)); Marshal.FreeHGlobal(p); //get address byte[] srcAddressArray = ArrayUtility.SubArray <byte>(data, Marshal.SizeOf(typeof(LspUdpHeader)), udpHeader.HeaderLength - Marshal.SizeOf(typeof(LspUdpHeader))); string srcAddress = Encoding.ASCII.GetString(srcAddressArray); //replacement numBytesReceived = numBytesReceived - udpHeader.HeaderLength; byte[] msgBody = new byte[numBytesReceived]; Array.Copy(data, udpHeader.HeaderLength, msgBody, 0, numBytesReceived); //endPoint is real remote client endpoint, remoteEP is LspDll's endpoint IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(srcAddress), udpHeader.Port); //map from the real endpoint to the lsp dll endpoint //when sending response to the real endpoint, response will be sent to the lsp dll endpoint //and the lsp dll will relay it to the real endpoint LspConsole.Instance.SetMappedIPEndPoint( (IPEndPoint)udpClient.Client.LocalEndPoint, (IPEndPoint)endPoint, (IPEndPoint)remoteEP, StackTransportType.Udp); host.VisitorAddReceivedData(msgBody, localEP, (IPEndPoint)endPoint); } else { host.VisitorAddReceivedData(data, localEP, remoteEP); } } catch (Exception ex) { // handle exception event, return. server.AddEvent(new TransportEvent(EventType.Exception, localEP, ex)); break; } } }