public RoutingEntry(ConnId connID, string guid)
 {
     SocketID.LocalEP  = new IPEndPoint(IPAddress.Parse(Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address), connID.lPort);
     SocketID.RemoteEP = new IPEndPoint(IPAddress.Parse(connID.rIp.ToString()), connID.rPort);
     SocketID.Protocol = (IP.ProtocolFamily)connID.protocol;
     InterfaceGuid     = guid;
 }
            public static RoutingObject IsUdpConn(Packet packet)
            {
                RequestAccess();
                RoutingObject routingObject = new RoutingObject();

                if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
                {
                    ConnId connId = new ConnId(packet.Ethernet.IpV4.Tcp.DestinationPort, packet.Ethernet.IpV4.Source, packet.Ethernet.IpV4.Tcp.SourcePort, IpV4Protocol.Udp);
                    Guid   guid;
                    if (guidList.TryGetValue(connId, out guid))
                    {
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.ifIndex      = routingTable[guid];
                    }
                    else
                    {
                        routingObject.ifIndex = -1;
                    }
                }
                ReleaseAccess();
                return(routingObject);
            }
 public RoutingEntry(ConnId connID, Guid guid)
 {
     SocketID.LocalEP = new IPEndPoint(IPAddress.Parse(Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address), connID.lPort);
     SocketID.RemoteEP = new IPEndPoint(IPAddress.Parse(connID.rIp.ToString()), connID.rPort);
     SocketID.Protocol = (IP.ProtocolFamily)connID.protocol;
     InterfaceGuid = guid;
 }
 public static RoutingObject IsUdpConn(Packet packet)
 {
     RequestAccess();
     RoutingObject routingObject = new RoutingObject();
     if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
     {
         ConnId connId = new ConnId(packet.Ethernet.IpV4.Tcp.DestinationPort, packet.Ethernet.IpV4.Source, packet.Ethernet.IpV4.Tcp.SourcePort, IpV4Protocol.Udp);
         Guid guid;
         if (guidList.TryGetValue(connId, out guid))
         {
             connStatus[guid].timeStamp = DateTime.Now;
             routingObject.ifIndex = routingTable[guid];
         }
         else
         {
             routingObject.ifIndex = -1;
         }
     }
     ReleaseAccess();
     return routingObject;
 }
            public static RoutingObject GetInterface(Packet packet)
            {
                RequestAccess();
                RoutingObject routingObject = new RoutingObject();
                if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp)
                {
                    ConnId connId = new ConnId(packet.Ethernet.IpV4.Tcp.SourcePort, packet.Ethernet.IpV4.Destination, packet.Ethernet.IpV4.Tcp.DestinationPort, IpV4Protocol.Tcp);
                    Guid guid;
                    if (guidList.TryGetValue(connId, out guid))
                    {
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.response = 0;
                        routingObject.ifIndex = routingTable[guid];
                        routingObject.guid = guid;
                        if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Reset) > 0)
                        {
                            connStatus[guid].localEPFin = true;
                            connStatus[guid].remoteEPFin = true;
                            routingObject.response = -1;
                            lock (connParams[guid])
                            {
                                connParams[guid].socket.Close();
                            }
                        }
                        else if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Fin) > 0)
                        {
                            routingObject.response = -2;
                        }
                        if (!connStatus[guid].localEPFin && packet.Ethernet.IpV4.Tcp.SequenceNumber == connStatus[guid].expectedSeq)
                        {
                            connStatus[guid].UpdateExpectedSeq(packet);
                            if (connStatus[guid].state == 2)
                                connStatus[guid].state = 3;
                        }
                        else if (packet.Ethernet.IpV4.Tcp.SequenceNumber == IpFunctions.SubM32(connStatus[guid].expectedSeq, 1) &&
                            (packet.Ethernet.IpV4.Tcp.ControlBits & (TcpControlBits.Fin | TcpControlBits.Synchronize)) == 0 &&
                            (packet.Ethernet.IpV4.Tcp.PayloadLength == 0 || packet.Ethernet.IpV4.Tcp.PayloadLength == 1) &&
                            !connStatus[guid].remoteEPFin)
                            routingObject.response = -3; // KeepAlive
                        else
                            routingObject.response = -1;
                    }
                    else
                    {
                        if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Synchronize) == TcpControlBits.Synchronize)
                        {
                            guid = Guid.NewGuid();
                            guidList.TryAdd(connId, guid);
                            int routingInterface = LoadBalancer.routingInterface;
                            routingTable.TryAdd(guid, routingInterface);
                            connParams.TryAdd(guid, new ConnParams());
                            connParams[guid].ack = packet.Ethernet.IpV4.Tcp.SequenceNumber;
                            connParams[guid].UpdateAck(1);
                            connParams[guid].localPort = packet.Ethernet.IpV4.Tcp.SourcePort;
                            connParams[guid].remoteIp = packet.Ethernet.IpV4.Destination;
                            connParams[guid].remotePort = packet.Ethernet.IpV4.Tcp.DestinationPort;
                            connStatus.TryAdd(guid, new ConnStatus());
                            connStatus[guid].timeStamp = DateTime.Now;
                            connStatus[guid].expectedSeq = packet.Ethernet.IpV4.Tcp.SequenceNumber;
                            connStatus[guid].UpdateExpectedSeq(packet);
                            connStatus[guid].state = 1;
                            foreach (TcpOption tcpOption in packet.Ethernet.IpV4.Tcp.Options.OptionsCollection)
                            {
                                if (tcpOption.OptionType == TcpOptionType.WindowScale)
                                    connParams[guid].windowScale = ((TcpOptionWindowScale)tcpOption).ScaleFactorLog;
                            }
                            connParams[guid].windowSize = packet.Ethernet.IpV4.Tcp.Window;
                            connParams[guid].freeWindow = (int)((packet.Ethernet.IpV4.Tcp.Window << RoutingTable.connParams[guid].windowScale) - (RoutingTable.connParams[guid].seq - packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber));
                            connParams[guid].socket = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            try
                            {
                                connParams[guid].socket.Bind(new IPEndPoint(new System.Net.IPAddress(physicalWorkers[routingInterface].ifProtocolAddressByte), 0));
                                connParams[guid].socket.BeginConnect(new IPEndPoint(new IPAddress(packet.Ethernet.IpV4.Destination.ToString().Split('.').Select(byte.Parse).ToArray()), (int)packet.Ethernet.IpV4.Tcp.DestinationPort), new AsyncCallback(physicalWorkers[routingInterface].ConnectCallback), guid);
                            }
                            catch (Exception)
                            {
                                connStatus[guid].localEPFin = true;
                                connStatus[guid].remoteEPFin = true;
                            }

                        }
                        routingObject.response = -1;
                    }
                }
                else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
                {
                    ConnId connId = new ConnId(packet.Ethernet.IpV4.Udp.SourcePort, packet.Ethernet.IpV4.Destination, packet.Ethernet.IpV4.Udp.DestinationPort, IpV4Protocol.Udp);
                    Guid guid;
                    if (guidList.TryGetValue(connId, out guid))
                    {
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.ifIndex = routingTable[guid];
                        routingObject.guid = guid;
                    }
                    else
                    {
                        guid = Guid.NewGuid();
                        guidList.TryAdd(connId, guid);
                        int routingInterface = LoadBalancer.routingInterface;
                        routingTable.TryAdd(guid, routingInterface);
                        connStatus.TryAdd(guid, new ConnStatus());
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.ifIndex = routingInterface;
                        routingObject.guid = guid;
                    }
                }
                else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.InternetControlMessageProtocol)
                    routingObject = new RoutingObject(0, LoadBalancer.routingInterface);
                else
                    routingObject = new RoutingObject(-1, 0);
                ReleaseAccess();
                return routingObject;
            }
            public static RoutingObject GetInterface(Packet packet)
            {
                RequestAccess();
                RoutingObject routingObject = new RoutingObject();

                if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp)
                {
                    ConnId connId = new ConnId(packet.Ethernet.IpV4.Tcp.SourcePort, packet.Ethernet.IpV4.Destination, packet.Ethernet.IpV4.Tcp.DestinationPort, IpV4Protocol.Tcp);
                    Guid   guid;
                    if (guidList.TryGetValue(connId, out guid))
                    {
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.response     = 0;
                        routingObject.ifIndex      = routingTable[guid];
                        routingObject.guid         = guid;
                        if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Reset) > 0)
                        {
                            connStatus[guid].localEPFin  = true;
                            connStatus[guid].remoteEPFin = true;
                            routingObject.response       = -1;
                            lock (connParams[guid])
                            {
                                connParams[guid].socket.Close();
                            }
                        }
                        else if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Fin) > 0)
                        {
                            routingObject.response = -2;
                        }
                        if (!connStatus[guid].localEPFin && packet.Ethernet.IpV4.Tcp.SequenceNumber == connStatus[guid].expectedSeq)
                        {
                            connStatus[guid].UpdateExpectedSeq(packet);
                            if (connStatus[guid].state == 2)
                            {
                                connStatus[guid].state = 3;
                            }
                        }
                        else if (packet.Ethernet.IpV4.Tcp.SequenceNumber == IpFunctions.SubM32(connStatus[guid].expectedSeq, 1) &&
                                 (packet.Ethernet.IpV4.Tcp.ControlBits & (TcpControlBits.Fin | TcpControlBits.Synchronize)) == 0 &&
                                 (packet.Ethernet.IpV4.Tcp.PayloadLength == 0 || packet.Ethernet.IpV4.Tcp.PayloadLength == 1) &&
                                 !connStatus[guid].remoteEPFin)
                        {
                            routingObject.response = -3; // KeepAlive
                        }
                        else
                        {
                            routingObject.response = -1;
                        }
                    }
                    else
                    {
                        if ((packet.Ethernet.IpV4.Tcp.ControlBits & TcpControlBits.Synchronize) == TcpControlBits.Synchronize)
                        {
                            guid = Guid.NewGuid();
                            guidList.TryAdd(connId, guid);
                            int routingInterface = LoadBalancer.routingInterface;
                            routingTable.TryAdd(guid, routingInterface);
                            connParams.TryAdd(guid, new ConnParams());
                            connParams[guid].ack = packet.Ethernet.IpV4.Tcp.SequenceNumber;
                            connParams[guid].UpdateAck(1);
                            connParams[guid].localPort  = packet.Ethernet.IpV4.Tcp.SourcePort;
                            connParams[guid].remoteIp   = packet.Ethernet.IpV4.Destination;
                            connParams[guid].remotePort = packet.Ethernet.IpV4.Tcp.DestinationPort;
                            connStatus.TryAdd(guid, new ConnStatus());
                            connStatus[guid].timeStamp   = DateTime.Now;
                            connStatus[guid].expectedSeq = packet.Ethernet.IpV4.Tcp.SequenceNumber;
                            connStatus[guid].UpdateExpectedSeq(packet);
                            connStatus[guid].state = 1;
                            foreach (TcpOption tcpOption in packet.Ethernet.IpV4.Tcp.Options.OptionsCollection)
                            {
                                if (tcpOption.OptionType == TcpOptionType.WindowScale)
                                {
                                    connParams[guid].windowScale = ((TcpOptionWindowScale)tcpOption).ScaleFactorLog;
                                }
                            }
                            connParams[guid].windowSize = packet.Ethernet.IpV4.Tcp.Window;
                            connParams[guid].freeWindow = (int)((packet.Ethernet.IpV4.Tcp.Window << RoutingTable.connParams[guid].windowScale) - (RoutingTable.connParams[guid].seq - packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber));
                            connParams[guid].socket     = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            try
                            {
                                connParams[guid].socket.Bind(new IPEndPoint(new System.Net.IPAddress(physicalWorkers[routingInterface].ifProtocolAddressByte), 0));
                                connParams[guid].socket.BeginConnect(new IPEndPoint(new IPAddress(packet.Ethernet.IpV4.Destination.ToString().Split('.').Select(byte.Parse).ToArray()), (int)packet.Ethernet.IpV4.Tcp.DestinationPort), new AsyncCallback(physicalWorkers[routingInterface].ConnectCallback), guid);
                            }
                            catch (Exception)
                            {
                                connStatus[guid].localEPFin  = true;
                                connStatus[guid].remoteEPFin = true;
                            }
                        }
                        routingObject.response = -1;
                    }
                }
                else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
                {
                    ConnId connId = new ConnId(packet.Ethernet.IpV4.Udp.SourcePort, packet.Ethernet.IpV4.Destination, packet.Ethernet.IpV4.Udp.DestinationPort, IpV4Protocol.Udp);
                    Guid   guid;
                    if (guidList.TryGetValue(connId, out guid))
                    {
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.ifIndex      = routingTable[guid];
                        routingObject.guid         = guid;
                    }
                    else
                    {
                        guid = Guid.NewGuid();
                        guidList.TryAdd(connId, guid);
                        int routingInterface = LoadBalancer.routingInterface;
                        routingTable.TryAdd(guid, routingInterface);
                        connStatus.TryAdd(guid, new ConnStatus());
                        connStatus[guid].timeStamp = DateTime.Now;
                        routingObject.ifIndex      = routingInterface;
                        routingObject.guid         = guid;
                    }
                }
                else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.InternetControlMessageProtocol)
                {
                    routingObject = new RoutingObject(0, LoadBalancer.routingInterface);
                }
                else
                {
                    routingObject = new RoutingObject(-1, 0);
                }
                ReleaseAccess();
                return(routingObject);
            }