/// <summary>
        /// Bind the local and remote IPEndPoint.
        /// for tcp: map from lsp dll tcp endpoint to the real tcp endpoint
        /// for udp: map from the real udp endpoint to lsp dll udp endpoint
        /// </summary>
        /// <param name="localEndpoint">Local server endpoint of sdk</param>
        /// <param name="srcEndPoint">the tcp/udp endpoint</param>
        /// <param name="mappedEndPoint">the tcp/udp endpoint </param>
        /// <param name="transportType">Tcp or Udp </param>
        internal void SetMappedIPEndPoint(IPEndPoint localEndpoint, IPEndPoint srcEndPoint,
                                          IPEndPoint mappedEndPoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            Dictionary <string, IPEndPoint> endPointMap;

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();

            if (sessionMap.ContainsKey(strKey))
            {
                endPointMap = sessionMap[strKey].endPoints;
            }
            else
            {
                return;
            }

            strKey = srcEndPoint.Serialize().ToString();
            endPointMap[strKey] = mappedEndPoint;

            //For tcp, each endpoint-to-endpoint pair has two records in the dictionary.
            if (transportType == StackTransportType.Tcp)
            {
                strKey = mappedEndPoint.Serialize().ToString();
                endPointMap[strKey] = srcEndPoint;
            }
        }
        /// <summary>
        /// Disconnect the remote EndPoint, and clean up the resources.
        /// </summary>
        /// <param name="localEndpoint">SDK listening endpoint</param>
        /// <param name="remoteEndpoint">the endpoint of real remote client</param>
        /// <param name="transportType">Tcp or Udp</param>
        internal void Disconnect(IPEndPoint localEndpoint, IPEndPoint remoteEndpoint,
                                 StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();

            if (sessionMap.ContainsKey(strKey))
            {
                Dictionary <string, IPEndPoint> endPointMap =
                    sessionMap[strKey].endPoints;
                strKey = remoteEndpoint.Serialize().ToString();
                if (transportType == StackTransportType.Udp)
                {
                    endPointMap.Remove(strKey);
                }
                else
                {
                    //For tcp, each endpoint-to-endpoint pair has two records in the dictionary.
                    IPEndPoint mappedEndpoint = endPointMap[strKey];
                    endPointMap.Remove(strKey);
                    endPointMap.Remove(mappedEndpoint.Serialize().ToString());
                }
            }
        }
        /// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress.
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint)
        {
            if (disposed)
            {
                return;
            }

            string strKey = transportType.ToString() + interceptedEndPoint.Serialize().ToString();

            endPointsToHook[strKey] = isBlocking;
        }
        internal void UnblockTraffic(IPEndPoint localServerEndpoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            String strKey = null;

            foreach (KeyValuePair <string, LspSessionInfoCollection> kvp in sessionMap)
            {
                //sessionMap key is local listening endpoint
                //sessionMap value is remote intertecpted endpoint
                if (kvp.Value.lspSession.InterceptedEndPoint.protocolType == transportType &&
                    kvp.Value.lspSession.InterceptedEndPoint.endPoint.Equals(localServerEndpoint))
                {
                    LspSession session = kvp.Value.lspSession;

                    if (!isConnected)
                    {
                        Connect();
                    }

                    LspUnblockRequest request = new LspUnblockRequest(session);
                    InternalSend(request.Encode());

                    byte[] recvBuf;
                    int    recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspUnblockResponseMsg)), out recvBuf);
                    if (recvLen != Marshal.SizeOf(typeof(LspUnblockResponseMsg)))
                    {
                        throw new InvalidOperationException("UnBlockTraffic failed");
                    }

                    LspUnblockResponse response = LspUnblockResponse.Decode(recvBuf) as LspUnblockResponse;

                    strKey = kvp.Key;

                    if (response == null || response.Status != 0)
                    {
                        throw new InvalidOperationException("UnBlockTraffic failed");
                    }

                    break;
                }
            }

            //remove it from session map
            if (strKey != null)
            {
                sessionMap.Remove(strKey);
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="transportType">Transport type: TCP/UDP?</param>
        /// <param name="isBlocking">Blocking mode or not</param>
        /// <param name="serviceEndPoint">Intercepted windows service IPEndPoint. </param>
        /// <param name="sdkEndPoint">Listening SDK's IPEndPoint. </param>
        public LspInterceptionRequest(StackTransportType transportType, bool isBlocking,
            IPEndPoint serviceEndPoint, IPEndPoint sdkEndPoint)
            : base(LspMessageType.InterceptionRequest)
        {
            if (StackTransportType.Tcp != transportType && StackTransportType.Udp != transportType)
            {
                throw new NotSupportedException("Not only TCP and UDP are supported");
            }

            this.sessionId = -1;
            this.transportType = transportType;
            this.isBlocking = isBlocking;
            this.serviceEndPoint.endPoint = serviceEndPoint;
            this.serviceEndPoint.protocolType = transportType;
            this.sdkEndPoint = sdkEndPoint;
        }
예제 #6
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="transportType">Transport type: TCP/UDP?</param>
        /// <param name="isBlocking">Blocking mode or not</param>
        /// <param name="serviceEndPoint">Intercepted windows service IPEndPoint. </param>
        /// <param name="sdkEndPoint">Listening SDK's IPEndPoint. </param>
        public LspInterceptionRequest(StackTransportType transportType, bool isBlocking,
                                      IPEndPoint serviceEndPoint, IPEndPoint sdkEndPoint)
            : base(LspMessageType.InterceptionRequest)
        {
            if (StackTransportType.Tcp != transportType && StackTransportType.Udp != transportType)
            {
                throw new NotSupportedException("Not only TCP and UDP are supported");
            }

            this.sessionId                    = -1;
            this.transportType                = transportType;
            this.isBlocking                   = isBlocking;
            this.serviceEndPoint.endPoint     = serviceEndPoint;
            this.serviceEndPoint.protocolType = transportType;
            this.sdkEndPoint                  = sdkEndPoint;
        }
        /// <summary>
        /// start at the specified endpoint<para/>
        /// the underlayer transport must be TcpServer, UdpServer or NetbiosServer.
        /// </summary>
        /// <param name="localEndPoint">
        /// an object that specifies the listener.
        /// </param>
        /// <exception cref="ObjectDisposedException">
        /// thrown when this object is disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when localEndPoint is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// thrown when localEndPoint is not an IPEndPoint/port.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// thrown when the specified endpoint has been started.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// thrown when localEndPoint is an int port, but the LocalIpAddress is not configured.
        /// </exception>
        public void Start(object localEndPoint)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("UdpServerTransport");
            }

            if (localEndPoint == null)
            {
                throw new ArgumentNullException("localEndPoint");
            }

            IPEndPoint requiredLocalEP = localEndPoint as IPEndPoint;

            if (requiredLocalEP == null)
            {
                requiredLocalEP = Utility.GetEndPointByPort(this.socketConfig, localEndPoint);
            }

            if (this.listeners.ContainsKey(requiredLocalEP))
            {
                throw new InvalidOperationException("the specified endpoint has been started.");
            }

            bool isLspHooked;
            bool isBlocking;
            StackTransportType type = this.socketConfig.Type;

            // get the replaced endpoint from LSP.
            IPEndPoint actualListenedLocalEP =
                LspConsole.Instance.GetReplacedEndPoint(type, requiredLocalEP, out isLspHooked, out isBlocking);

            UdpClient         udpClient = new UdpClient(actualListenedLocalEP);
            UdpServerListener listener  = new UdpServerListener(udpClient, this, isLspHooked);

            // if LSP is enabled, intercept the traffic
            if (isLspHooked)
            {
                LspConsole.Instance.InterceptTraffic(
                    type, isBlocking, requiredLocalEP, udpClient.Client.LocalEndPoint as IPEndPoint);
            }

            listener.Start(requiredLocalEP);
            this.listeners[requiredLocalEP] = listener;

            this.started = true;
        }
        internal void ChangeToBlockingMode(IPEndPoint localServerEndpoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            foreach (KeyValuePair <string, LspSessionInfoCollection> kvp in sessionMap)
            {
                //sessionMap key is local listening endpoint
                //sessionMap value is remote intertecpted endpoint
                if (kvp.Value.lspSession.InterceptedEndPoint.protocolType == transportType &&
                    kvp.Value.lspSession.InterceptedEndPoint.endPoint.Equals(localServerEndpoint))
                {
                    LspSession      session = kvp.Value.lspSession;
                    LspBlockRequest request = new LspBlockRequest(session);
                    InternalSend(request.Encode());
                    byte[] recvBuf;
                    int    recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspBlockResponseMsg)), out recvBuf);
                    if (recvLen != Marshal.SizeOf(typeof(LspBlockResponseMsg)))
                    {
                        throw new InvalidOperationException("BlockTraffic failed");
                    }

                    LspBlockResponse response = LspBlockResponse.Decode(recvBuf) as LspBlockResponse;

                    if (response == null || response.Status != 0)
                    {
                        throw new InvalidOperationException("BlockTraffic failed");
                    }

                    return;
                }
            }

            throw new InvalidOperationException("The specified endpoint isn't in intercepted mode");
        }
 /// <summary>
 /// Map the intercepted IPEndPoint to the LspSession.
 /// </summary>
 /// <param name="index">Intercepted IPEndPoint. </param>
 /// <param name="transportType">Tcp or Udp</param>
 /// <returns>Mapped LspSession</returns>
 private LspSessionInfoCollection this[IPEndPoint index, StackTransportType transportType]
 {
     get
     {
         string strKey = transportType.ToString() + index.Serialize().ToString();
         if (sessionMap.ContainsKey(strKey))
         {
             return(sessionMap[strKey]);
         }
         else
         {
             return(null);
         }
     }
     set
     {
         string strKey = transportType.ToString() + index.Serialize().ToString();
         sessionMap[strKey] = value;
     }
 }
        /// <summary>
        /// get a replaced endpoint.<para/>
        /// if the localEndPoint (that specifies the server to listen at) is not available,
        /// LSP will give another endpoint to listen at, and intercept the traffic.<para/>
        /// if the output bool value isLspHooked is set to true, user must invoke the InterceptTraffic.
        /// </summary>
        /// <param name="transportType">
        /// a StackTransportType that specifies the type of transport. it must be Tcp or Udp.
        /// </param>
        /// <param name="localEndPoint">
        /// an IPEndPoint object that specifies the local endpoint for server to listen at.
        /// </param>
        /// <param name="isLspHooked">
        /// output a bool value that specifies whether LSP work.<para/>
        /// if true, must invoke InterceptTraffic.
        /// </param>
        /// <param name="isBlocking">
        /// output a bool value that specifies whether LSP is block mode.<para/>
        /// it's used to pass to InterceptTraffic.
        /// </param>
        /// <returns>
        /// return an IPEndPoint object that specifies the replaced endpoint.
        /// </returns>
        internal IPEndPoint GetReplacedEndPoint(
            StackTransportType transportType, IPEndPoint localEndPoint, out bool isLspHooked, out bool isBlocking)
        {
            if (disposed)
            {
                isLspHooked = false;
                isBlocking  = false;

                return(localEndPoint);
            }

            IPEndPoint replacedEndpoint;

            isBlocking = false;

            string strKey = transportType.ToString() + localEndPoint.Serialize().ToString();

            if (endPointsToHook.ContainsKey(strKey))
            {
                replacedEndpoint = new IPEndPoint(localEndPoint.Address, 0);
                //sdk local listening endpoint address is fixed as loopback address
                if (replacedEndpoint.AddressFamily == AddressFamily.InterNetwork)
                {
                    replacedEndpoint.Address = IPAddress.Loopback;
                }
                else
                {
                    replacedEndpoint.Address = IPAddress.IPv6Loopback;
                }
                isBlocking = endPointsToHook[strKey];
                endPointsToHook.Remove(strKey);
                isLspHooked = true;
            }
            else
            {
                replacedEndpoint = localEndPoint;
                isLspHooked      = false;
            }

            return(replacedEndpoint);
        }
        /// <summary>
        /// start at the specified endpoint<para/>
        /// the underlayer transport must be TcpServer, UdpServer or NetbiosServer.
        /// </summary>
        /// <param name="localEndPoint">
        /// an object that specifies the listener.
        /// </param>
        /// <exception cref="ObjectDisposedException">
        /// thrown when this object is disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when localEndPoint is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// thrown when localEndPoint is not an IPEndPoint/port.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// thrown when the udp client is started.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// thrown when the received thread does not cleanup.
        /// </exception>
        public void Start(object localEndPoint)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("UdpClientTransport");
            }

            if (localEndPoint == null)
            {
                throw new ArgumentNullException("localEndPoint");
            }

            if (this.udpClient != null)
            {
                throw new InvalidOperationException("udp client is started.");
            }

            if (this.thread != null)
            {
                throw new InvalidOperationException("the received thread does not cleanup.");
            }

            IPEndPoint requiredLocalEP = localEndPoint as IPEndPoint;

            if (requiredLocalEP == null)
            {
                if (this.socketConfig.LocalIpAddress == null)
                {
                    this.socketConfig.LocalIpAddress = IPAddress.Any;
                }
                requiredLocalEP = Utility.GetEndPointByPort(this.socketConfig, localEndPoint);
            }

            this.socketConfig.LocalIpAddress = requiredLocalEP.Address;
            this.socketConfig.LocalIpPort    = requiredLocalEP.Port;

            this.eventQueue.Clear();
            this.packetCache.Clear();
            this.buffer.Clear();

            bool isLspHooked;
            bool isBlocking;
            StackTransportType type = this.socketConfig.Type;

            // get the replaced endpoint from LSP.
            IPEndPoint actualListenedLocalEP =
                LspConsole.Instance.GetReplacedEndPoint(type, requiredLocalEP, out isLspHooked, out isBlocking);

            // store the lsp state.
            this.lspHooked = isLspHooked;

            this.udpClient = new UdpClient(actualListenedLocalEP);

            if (socketConfig.LocalIpPort == 0)
            {
                //If set local Port to 0, a free port will be selected
                socketConfig.LocalIpPort = (udpClient.Client.LocalEndPoint as IPEndPoint).Port;
            }

            // if LSP is enabled, intercept the traffic
            if (isLspHooked)
            {
                LspConsole.Instance.InterceptTraffic(type, isBlocking, requiredLocalEP, (IPEndPoint)this.udpClient.Client.LocalEndPoint);
            }

            this.thread = new ThreadManager(this.UdpClientReceiveLoop, this.UnblockReceiveThread);
            this.thread.Start();
        }
        /// <summary>
        /// Disconnect the remote EndPoint, and clean up the resources.
        /// </summary>
        /// <param name="localEndpoint">SDK listening endpoint</param>
        /// <param name="remoteEndpoint">the endpoint of real remote client</param>
        /// <param name="transportType">Tcp or Udp</param>
        internal void Disconnect(IPEndPoint localEndpoint, IPEndPoint remoteEndpoint, 
            StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();
            if (sessionMap.ContainsKey(strKey))
            {
                Dictionary<string, IPEndPoint> endPointMap =
                    sessionMap[strKey].endPoints;
                strKey = remoteEndpoint.Serialize().ToString();
                if (transportType == StackTransportType.Udp)
                {
                    endPointMap.Remove(strKey);
                }
                else
                {
                    //For tcp, each endpoint-to-endpoint pair has two records in the dictionary.
                    IPEndPoint mappedEndpoint = endPointMap[strKey];
                    endPointMap.Remove(strKey);
                    endPointMap.Remove(mappedEndpoint.Serialize().ToString());
                }
            }
        }
        /// <summary>
        /// get a replaced endpoint.<para/>
        /// if the localEndPoint (that specifies the server to listen at) is not available, 
        /// LSP will give another endpoint to listen at, and intercept the traffic.<para/>
        /// if the output bool value isLspHooked is set to true, user must invoke the InterceptTraffic.
        /// </summary>
        /// <param name="transportType">
        /// a StackTransportType that specifies the type of transport. it must be Tcp or Udp.
        /// </param>
        /// <param name="localEndPoint">
        /// an IPEndPoint object that specifies the local endpoint for server to listen at.
        /// </param>
        /// <param name="isLspHooked">
        /// output a bool value that specifies whether LSP work.<para/>
        /// if true, must invoke InterceptTraffic.
        /// </param>
        /// <param name="isBlocking">
        /// output a bool value that specifies whether LSP is block mode.<para/>
        /// it's used to pass to InterceptTraffic.
        /// </param>
        /// <returns>
        /// return an IPEndPoint object that specifies the replaced endpoint.
        /// </returns>
        internal IPEndPoint GetReplacedEndPoint(
            StackTransportType transportType, IPEndPoint localEndPoint, out bool isLspHooked, out bool isBlocking)
        {
            if (disposed)
            {
                isLspHooked = false;
                isBlocking = false;

                return localEndPoint;
            }

            IPEndPoint replacedEndpoint;

            isBlocking = false;

            string strKey = transportType.ToString() + localEndPoint.Serialize().ToString();
            if (endPointsToHook.ContainsKey(strKey))
            {
                replacedEndpoint = new IPEndPoint(localEndPoint.Address, 0);
                //sdk local listening endpoint address is fixed as loopback address
                if (replacedEndpoint.AddressFamily == AddressFamily.InterNetwork)
                {
                    replacedEndpoint.Address = IPAddress.Loopback;
                }
                else
                {
                    replacedEndpoint.Address = IPAddress.IPv6Loopback;
                }
                isBlocking = endPointsToHook[strKey];
                endPointsToHook.Remove(strKey);
                isLspHooked = true;
            }
            else
            {
                replacedEndpoint = localEndPoint;
                isLspHooked = false;
            }

            return replacedEndpoint;
        }
        /// <summary>
        /// Get the local IPEndPoint by remote IPEndPoint. The key is remote IPEndPoint.
        /// for tcp: map from lsp dll tcp endpoint to the real tcp endpoint
        /// for udp: map from the real udp endpoint to lsp dll udp endpoint
        /// </summary>
        /// <param name="localEndpoint">Local server endpoint of sdk</param>
        /// <param name="srcEndPoint">source endpoint</param>
        /// <param name="transportType">tcp or udp</param>
        /// <returns>Local LspClient socket</returns>
        internal IPEndPoint GetMappedIPEndPoint(IPEndPoint localEndpoint, IPEndPoint srcEndPoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return null;
            }

            Dictionary<string, IPEndPoint> endPointMap;

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();
            if (sessionMap.ContainsKey(strKey))
            {
                endPointMap = sessionMap[strKey].endPoints;
            }
            else
            {
                return null;
            }

            strKey = srcEndPoint.Serialize().ToString();
            if (endPointMap.ContainsKey(strKey))
            {
                return endPointMap[strKey];
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress. 
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint)
        {
            if (disposed)
            {
                return;
            }

            string strKey = transportType.ToString() + interceptedEndPoint.Serialize().ToString();
            endPointsToHook[strKey] = isBlocking;
        }
        /// <summary>
        /// Get the local IPEndPoint by remote IPEndPoint. The key is remote IPEndPoint.
        /// for tcp: map from lsp dll tcp endpoint to the real tcp endpoint
        /// for udp: map from the real udp endpoint to lsp dll udp endpoint
        /// </summary>
        /// <param name="localEndpoint">Local server endpoint of sdk</param>
        /// <param name="srcEndPoint">source endpoint</param>
        /// <param name="transportType">tcp or udp</param>
        /// <returns>Local LspClient socket</returns>
        internal IPEndPoint GetMappedIPEndPoint(IPEndPoint localEndpoint, IPEndPoint srcEndPoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return(null);
            }

            Dictionary <string, IPEndPoint> endPointMap;

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();

            if (sessionMap.ContainsKey(strKey))
            {
                endPointMap = sessionMap[strKey].endPoints;
            }
            else
            {
                return(null);
            }

            strKey = srcEndPoint.Serialize().ToString();
            if (endPointMap.ContainsKey(strKey))
            {
                return(endPointMap[strKey]);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress. 
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        /// <param name="sdkLocalListeningEndPoint">The IP/Port listened by SDK . </param>
        /// <returns>LspSession, which is corresponding to each intercepted endpoint. Return null if failed.</returns>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint,
            IPEndPoint sdkLocalListeningEndPoint)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            if (sdkLocalListeningEndPoint == null)
            {
                throw new ArgumentNullException("sdkLocalListeningEndPoint");
            }

            if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetwork &&
                sdkLocalListeningEndPoint.Address == IPAddress.Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.Loopback;
            }
            else if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetworkV6 &&
                sdkLocalListeningEndPoint.Address == IPAddress.IPv6Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.IPv6Loopback;
            }

            LspInterceptionRequest request = new LspInterceptionRequest(transportType, isBlocking,
                interceptedEndPoint, sdkLocalListeningEndPoint);
            InternalSend(request.Encode());

            byte[] recvBuf;
            int recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspInterceptionResponseMsg)), out recvBuf);
            if (recvLen != Marshal.SizeOf(typeof(LspInterceptionResponseMsg)))
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }

            LspInterceptionResponse response = LspInterceptionResponse.Decode(recvBuf) as LspInterceptionResponse;

            if (response != null && response.Status == 0) //success
            {
                LspSessionInfoCollection sessionInfoCollection = new LspSessionInfoCollection();
                sessionInfoCollection.lspSession = response.Session;
                sessionInfoCollection.lspSession.InterceptedEndPoint = response.InterceptedEndPoint;
                sessionInfoCollection.endPoints = new Dictionary<string, IPEndPoint>();
                this[sdkLocalListeningEndPoint, transportType] = sessionInfoCollection;
            }
            else
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }
        }
        /// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress.
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        /// <param name="sdkLocalListeningEndPoint">The IP/Port listened by SDK . </param>
        /// <returns>LspSession, which is corresponding to each intercepted endpoint. Return null if failed.</returns>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint,
                                       IPEndPoint sdkLocalListeningEndPoint)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            if (sdkLocalListeningEndPoint == null)
            {
                throw new ArgumentNullException("sdkLocalListeningEndPoint");
            }

            if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetwork &&
                sdkLocalListeningEndPoint.Address == IPAddress.Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.Loopback;
            }
            else if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetworkV6 &&
                     sdkLocalListeningEndPoint.Address == IPAddress.IPv6Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.IPv6Loopback;
            }

            LspInterceptionRequest request = new LspInterceptionRequest(transportType, isBlocking,
                                                                        interceptedEndPoint, sdkLocalListeningEndPoint);

            InternalSend(request.Encode());


            byte[] recvBuf;
            int    recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspInterceptionResponseMsg)), out recvBuf);

            if (recvLen != Marshal.SizeOf(typeof(LspInterceptionResponseMsg)))
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }

            LspInterceptionResponse response = LspInterceptionResponse.Decode(recvBuf) as LspInterceptionResponse;

            if (response != null && response.Status == 0) //success
            {
                LspSessionInfoCollection sessionInfoCollection = new LspSessionInfoCollection();
                sessionInfoCollection.lspSession = response.Session;
                sessionInfoCollection.lspSession.InterceptedEndPoint = response.InterceptedEndPoint;
                sessionInfoCollection.endPoints = new Dictionary <string, IPEndPoint>();
                this[sdkLocalListeningEndPoint, transportType] = sessionInfoCollection;
            }
            else
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }
        }
        internal void ChangeToBlockingMode(IPEndPoint localServerEndpoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            foreach (KeyValuePair<string, LspSessionInfoCollection> kvp in sessionMap)
            {
                //sessionMap key is local listening endpoint
                //sessionMap value is remote intertecpted endpoint
                if(kvp.Value.lspSession.InterceptedEndPoint.protocolType == transportType
                    && kvp.Value.lspSession.InterceptedEndPoint.endPoint.Equals(localServerEndpoint))
                {
                    LspSession session = kvp.Value.lspSession;
                    LspBlockRequest request = new LspBlockRequest(session);
                    InternalSend(request.Encode());
                    byte[] recvBuf;
                    int recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspBlockResponseMsg)), out recvBuf);
                    if (recvLen != Marshal.SizeOf(typeof(LspBlockResponseMsg)))
                    {
                        throw new InvalidOperationException("BlockTraffic failed");
                    }

                    LspBlockResponse response = LspBlockResponse.Decode(recvBuf) as LspBlockResponse;

                    if (response == null || response.Status != 0)
                    {
                        throw new InvalidOperationException("BlockTraffic failed");
                    }

                    return;
                }
            }

            throw new InvalidOperationException("The specified endpoint isn't in intercepted mode");
        }
 public static void UnblockTraffic(StackTransportType transportType, IPEndPoint localServerEndpoint)
 {
     LspConsole.Instance.UnblockTraffic(localServerEndpoint, transportType);
 }
 public static void ChangeToBlockingMode(StackTransportType transportType, IPEndPoint localServerEndpoint)
 {
     LspConsole.Instance.ChangeToBlockingMode(localServerEndpoint, transportType);
 }
        /// <summary>
        /// Bind the local and remote IPEndPoint.
        /// for tcp: map from lsp dll tcp endpoint to the real tcp endpoint
        /// for udp: map from the real udp endpoint to lsp dll udp endpoint
        /// </summary>
        /// <param name="localEndpoint">Local server endpoint of sdk</param>
        /// <param name="srcEndPoint">the tcp/udp endpoint</param>
        /// <param name="mappedEndPoint">the tcp/udp endpoint </param>
        /// <param name="transportType">Tcp or Udp </param>
        internal void SetMappedIPEndPoint(IPEndPoint localEndpoint, IPEndPoint srcEndPoint,
            IPEndPoint mappedEndPoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            Dictionary<string, IPEndPoint> endPointMap;

            IPEndPoint connectableEndpoint = GetConnectableEndpoint(localEndpoint);

            string strKey = transportType.ToString() + connectableEndpoint.Serialize().ToString();
            if (sessionMap.ContainsKey(strKey))
            {
                endPointMap = sessionMap[strKey].endPoints;
            }
            else
            {
                return;
            }

            strKey = srcEndPoint.Serialize().ToString();
            endPointMap[strKey] = mappedEndPoint;

            //For tcp, each endpoint-to-endpoint pair has two records in the dictionary.
            if (transportType == StackTransportType.Tcp)
            {
                strKey = mappedEndPoint.Serialize().ToString();
                endPointMap[strKey] = srcEndPoint;
            }
        }
        internal void UnblockTraffic(IPEndPoint localServerEndpoint, StackTransportType transportType)
        {
            if (disposed)
            {
                return;
            }

            String strKey = null;
            foreach (KeyValuePair<string, LspSessionInfoCollection> kvp in sessionMap)
            {
                //sessionMap key is local listening endpoint
                //sessionMap value is remote intertecpted endpoint
                if(kvp.Value.lspSession.InterceptedEndPoint.protocolType == transportType
                    && kvp.Value.lspSession.InterceptedEndPoint.endPoint.Equals(localServerEndpoint))
                {
                    LspSession session = kvp.Value.lspSession;

                    if (!isConnected)
                    {
                        Connect();
                    }

                    LspUnblockRequest request = new LspUnblockRequest(session);
                    InternalSend(request.Encode());

                    byte[] recvBuf;
                    int recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspUnblockResponseMsg)), out recvBuf);
                    if (recvLen != Marshal.SizeOf(typeof(LspUnblockResponseMsg)))
                    {
                        throw new InvalidOperationException("UnBlockTraffic failed");
                    }

                    LspUnblockResponse response = LspUnblockResponse.Decode(recvBuf) as LspUnblockResponse;

                    strKey = kvp.Key;

                    if (response == null || response.Status != 0)
                    {
                        throw new InvalidOperationException("UnBlockTraffic failed");
                    }

                    break;
                }
            }

            //remove it from session map
            if (strKey != null)
            {
                sessionMap.Remove(strKey);
            }
        }
 /// <summary>
 /// Intercept the ip traffic in a designated address. 
 /// Sdk is listening to the same IP/port to the intercepted address. 
 /// </summary>
 /// <param name="transportType">TCP or UDP . </param>
 /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
 /// <exception cref="NotSupportedException">Thrown when the transport doesn't support this 
 /// operation</exception>
 public static void InterceptTraffic(StackTransportType transportType, IPEndPoint interceptedEndPoint)
 {
     LspConsole.Instance.InterceptTraffic(transportType, false, interceptedEndPoint);
 }
 /// <summary>
 /// constructor
 /// </summary>
 protected TransportConfig()
 {
     this.bufferSize = DefaultBufferSize;
     this.role       = Role.None;
     this.type       = StackTransportType.None;
 }
 /// <summary>
 /// constructor
 /// </summary>
 protected TransportConfig()
 {
     this.bufferSize = DefaultBufferSize;
     this.role = Role.None;
     this.type = StackTransportType.None;
 }
 /// <summary>
 /// Map the intercepted IPEndPoint to the LspSession.
 /// </summary>
 /// <param name="index">Intercepted IPEndPoint. </param>
 /// <param name="transportType">Tcp or Udp</param>
 /// <returns>Mapped LspSession</returns>
 private LspSessionInfoCollection this[IPEndPoint index, StackTransportType transportType]
 {
     get
     {
         string strKey = transportType.ToString() + index.Serialize().ToString();
         if (sessionMap.ContainsKey(strKey))
         {
             return sessionMap[strKey];
         }
         else
         {
             return null;
         }
     }
     set
     {
         string strKey = transportType.ToString() + index.Serialize().ToString();
         sessionMap[strKey] = value;
     }
 }