/// <summary>
        /// Register an interface and turn on automatic accept bind request.
        /// </summary>
        /// <param name="ifId">
        /// If_id to accept the bind. Null to accept all interface regardless the if_id.
        /// </param>
        /// <param name="ifMajorVer">
        /// If_major_ver to accept the bind. Null to accept all interface regardless the if_major_ver.
        /// </param>
        /// <param name="ifMinorVer">
        /// If_minor_ver to accept the bind. Null to accept all interface regardless the if_minor_ver.
        /// </param>
        public void RegisterInterface(
            Guid ifId,
            ushort ifMajorVer,
            ushort ifMinorVer)
        {
            RpcIf rpcIf = new RpcIf(ifId, ifMajorVer, ifMinorVer);

            this.registeredInterfaceList.Add(rpcIf);
        }
        /// <summary>
        /// Calling this method to be notified when a new RPC connection is coming.
        /// </summary>
        /// <param name="ifMatchFunc">Matching function.</param>
        /// <param name="timeout">Timeout of expecting a connection.</param>
        /// <param name="sessionContext">The sessionContext of binded connection.</param>
        /// <returns>If bind succeeded, return true; otherwise, false.</returns>
        private bool InternalExpectBind(
            RpcIfMatchFunc ifMatchFunc,
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu       receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
            RpceCoBindPdu bindPdu     = receivedPdu as RpceCoBindPdu;

            if (bindPdu == null)
            {
                throw new InvalidOperationException("Expect bind_pdu, but received others.");
            }

            RpcIf rpcIf = new RpcIf(sessionContext.InterfaceId, sessionContext.InterfaceMajorVersion, sessionContext.InterfaceMinorVersion);

            if (!ifMatchFunc(rpcIf))
            {
                // Interface doesn't match, response BindNak
                RpceCoBindNakPdu bindNakPdu =
                    rpceServer.CreateCoBindNakPdu(sessionContext, p_reject_reason_t.REASON_NOT_SPECIFIED, null);
                FragmentAndSendPdu(sessionContext, bindNakPdu);
                return(false);
            }

            RpceCoBindAckPdu bindAckPdu = rpceServer.CreateCoBindAckPdu(sessionContext);

            FragmentAndSendPdu(sessionContext, bindAckPdu);

            while (sessionContext.SecurityContext != null && sessionContext.SecurityContextNeedContinueProcessing)
            {
                receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
                RpceCoAlterContextPdu alterContextPdu = receivedPdu as RpceCoAlterContextPdu;
                RpceCoAuth3Pdu        auth3Pdu        = receivedPdu as RpceCoAuth3Pdu;

                if (alterContextPdu != null)
                {
                    RpceCoAlterContextRespPdu alterContextRespPdu =
                        rpceServer.CreateCoAlterContextRespPdu(sessionContext);

                    FragmentAndSendPdu(sessionContext, alterContextRespPdu);
                }
                else if (auth3Pdu != null)
                {
                    //Do nothing
                }
            }

            return(true);
        }
 /// <summary>
 /// Unregister an interface. If last interface is removed, turn off automatic accept bind request.
 /// </summary>
 /// <param name="ifId">
 /// If_id to accept the bind. Null to accept all interface regardless the if_id.
 /// </param>
 /// <param name="ifMajorVer">
 /// If_major_ver to accept the bind. Null to accept all interface regardless the if_major_ver.
 /// </param>
 /// <param name="ifMinorVer">
 /// If_minor_ver to accept the bind. Null to accept all interface regardless the if_minor_ver.
 /// </param>
 public void UnregisterInterface(
     Guid ifId,
     ushort ifMajorVer,
     ushort ifMinorVer)
 {
     for (int i = 0; i < this.registeredInterfaceList.Count; i++)
     {
         RpcIf rpcIf = this.registeredInterfaceList[i];
         if (rpcIf.id == ifId && rpcIf.majorVer == ifMajorVer && rpcIf.minorVer == ifMinorVer)
         {
             this.registeredInterfaceList.RemoveAt(i);
             break;
         }
     }
 }
        /// <summary>
        /// Calling this method to be notified when a new RPC connection is coming. 
        /// </summary>
        /// <param name="ifMatchFunc">Matching function.</param>
        /// <param name="timeout">Timeout of expecting a connection.</param>
        /// <param name="sessionContext">The sessionContext of binded connection.</param>
        /// <returns>If bind succeeded, return true; otherwise, false.</returns>
        private bool InternalExpectBind(
            RpcIfMatchFunc ifMatchFunc,
            TimeSpan timeout,
            ref RpceServerSessionContext sessionContext)
        {
            RpcePdu receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
            RpceCoBindPdu bindPdu = receivedPdu as RpceCoBindPdu;

            if (bindPdu == null)
            {
                throw new InvalidOperationException("Expect bind_pdu, but received others.");
            }

            RpcIf rpcIf = new RpcIf(sessionContext.InterfaceId, sessionContext.InterfaceMajorVersion, sessionContext.InterfaceMinorVersion);
            if (!ifMatchFunc(rpcIf))
            {
                // Interface doesn't match, response BindNak
                RpceCoBindNakPdu bindNakPdu =
                    rpceServer.CreateCoBindNakPdu(sessionContext, p_reject_reason_t.REASON_NOT_SPECIFIED, null);
                FragmentAndSendPdu(sessionContext, bindNakPdu);
                return false;
            }

            RpceCoBindAckPdu bindAckPdu = rpceServer.CreateCoBindAckPdu(sessionContext);

            FragmentAndSendPdu(sessionContext, bindAckPdu);

            while (sessionContext.SecurityContext != null && sessionContext.SecurityContextNeedContinueProcessing)
            {
                receivedPdu = ReceiveAndReassemblePdu(timeout, ref sessionContext);
                RpceCoAlterContextPdu alterContextPdu = receivedPdu as RpceCoAlterContextPdu;
                RpceCoAuth3Pdu auth3Pdu = receivedPdu as RpceCoAuth3Pdu;

                if (alterContextPdu != null)
                {
                    RpceCoAlterContextRespPdu alterContextRespPdu =
                        rpceServer.CreateCoAlterContextRespPdu(sessionContext);

                    FragmentAndSendPdu(sessionContext, alterContextRespPdu);
                }
                else if (auth3Pdu != null)
                {
                    //Do nothing
                }
            }

            return true;
        }
 /// <summary>
 /// Register an interface and turn on automatic accept bind request.
 /// </summary>
 /// <param name="ifId">
 /// If_id to accept the bind. Null to accept all interface regardless the if_id.
 /// </param>
 /// <param name="ifMajorVer">
 /// If_major_ver to accept the bind. Null to accept all interface regardless the if_major_ver.
 /// </param>
 /// <param name="ifMinorVer">
 /// If_minor_ver to accept the bind. Null to accept all interface regardless the if_minor_ver.
 /// </param>
 public void RegisterInterface(
     Guid ifId,
     ushort ifMajorVer,
     ushort ifMinorVer)
 {
     RpcIf rpcIf = new RpcIf(ifId, ifMajorVer, ifMinorVer);
     this.registeredInterfaceList.Add(rpcIf);
 }