⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessionmgr.c

📁 Vista 核心Rally技术之-LLTD 实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * LICENSE NOTICE.
 *
 * Use of the Microsoft Windows Rally Development Kit is covered under
 * the Microsoft Windows Rally Development Kit License Agreement,
 * which is provided within the Microsoft Windows Rally Development
 * Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
 * want a license from Microsoft to use the software in the Microsoft
 * Windows Rally Development Kit, you must (1) complete the designated
 * "licensee" information in the Windows Rally Development Kit License
 * Agreement, and (2) sign and return the Agreement AS IS to Microsoft
 * at the address provided in the Agreement.
 */

/*
 * Copyright (c) Microsoft Corporation 2005.  All rights reserved.
 * This software is provided with NO WARRANTY.
 */

/* This is the session-manager state machine (smS) event distributor */

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "globals.h"

#include "statemachines.h"
#include "packetio.h"

static bool_t
is_acking_me(void)
{
    etheraddr_t             *p  = (etheraddr_t*)(g_discover_hdr + 1);
    etheraddr_t          *limit = (etheraddr_t*)(((char*)g_ethernet_hdr) + g_rcvd_pkt_len);

    uint16_t                gen = ntohs(g_discover_hdr->mh_gen);
    uint16_t        numstations = ntohs(g_discover_hdr->mh_numstations);

    bool_t               acking = FALSE;
    int  i;

    if (g_this_event.isAckingMe == TRUE)  return TRUE;

    IF_TRACED(TRC_PACKET)
	dbgprintf("gen=%d, numsta=%d, stations=[", gen, numstations);
    END_TRACE

    /* parse seenlist, and decide if we are acked in this frame */

    for (i=0; p+1 <= limit && i<numstations; i++, p++)
    {
        IF_TRACED(TRC_PACKET)
	    dbgprintf(ETHERADDR_FMT " ", ETHERADDR_PRINT(p));
        END_TRACE

	if (ETHERADDR_EQUALS(p, &g_hwaddr))
	{
	    acking = TRUE;
	    /* we could break out early, but we also want to test the
	     * numstations count is accurate so we loop over all the
	     * acked addresses */
	}
    }
    IF_TRACED(TRC_PACKET)
	dbgprintf("]\n");
    END_TRACE

    if (i != numstations)
	warn("rx_discover: truncated frame: ended at station %d, "
	     "but numstations claimed %d\n", i, numstations);

    return acking;
}


static bool_t
is_conflicting_ssn( session_t *ssn )
{
    if ((g_topo_session) && (g_topo_session->ssn_is_valid==TRUE) && /* if there already IS a topo-session, */
        (ssn != g_topo_session) &&			 /* and this is not the same session,   */
        (ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) && /* and this IS a topo-ssn Discover,    */
                                                         /* and the real-addresses don't match, */
        !(ETHERADDR_EQUALS(&ssn->ssn_mapper_real, &g_topo_session->ssn_mapper_real)))
    { /* then this is a conflicting Discover */
        return TRUE;
    }
    return FALSE;
}

/*====================== S T A T E   H A N D L E R S ======================*/


/***********************  N A S C E N T   S T A T E  ***********************/

static
enum sm_Status
smS_NascentHandler  ( protocol_event_t *evt )
{
    IF_TRACED(TRC_STATE)
        printf("smS (Nascent): Entered with event %s",smEvent_names[evt->evtType]);
        if (g_this_event.evtType==evtPacketRcvd)
        {
            printf(" (%s)\n",Topo_opcode_names[g_opcode]);
        } else {
            puts("");
        }
    END_TRACE

    switch (evt->evtType)
    {
      case evtDiscoverRcvd:
        /* The first Topo ssn is the definitive one */
/**/    DEBUG({printf("session's ToS is %s %d\n",Lld2_tos_names[evt->ssn->ssn_TypeOfSvc],evt->ssn->ssn_TypeOfSvc);})
        if ((evt->ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) &&
            ((g_topo_session == NULL) || (g_topo_session->ssn_is_valid==FALSE)))
        {
/**/        DEBUG({printf("noting new TOPO session @ %X\n",(uint)evt->ssn);})
            g_topo_session = evt->ssn;
        }
        /* check for a conflicting TOPO Discover (rogue mapper) */
        if (is_conflicting_ssn( evt->ssn ))
        {
            evt->ssn->ssn_state = smS_Temporary;
        } else {
/**/        DEBUG({puts("not conflicting....");})
            if (is_acking_me())
            {
/**/            DEBUG({puts("is acking me....");})
                evt->isAckingMe = TRUE;
                IF_TRACED(TRC_STATE)
                    printf("smS[%X] (Nascent): Leaving for Complete.\n", (uint)evt->ssn);
                END_TRACE
                evt->ssn->ssn_state = smS_Complete;
                restart_inactivity_timer((evt->ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) ? TOPO_CMD_ACTIVITYTIMEOUT : TOPO_GENERAL_ACTIVITYTIMEOUT);
            } else {
/**/            DEBUG({puts("is NOT acking me....");})
                evt->isAckingMe = FALSE;
                IF_TRACED(TRC_STATE)
                    printf("smS[%X] (Nascent): Leaving for Pending.\n", (uint)evt->ssn);
                END_TRACE
                evt->ssn->ssn_state = smS_Pending;
                restart_inactivity_timer(TOPO_HELLO_ACTIVITYTIMEOUT);
            }
        }
        break;

      case evtPacketRcvd:
      case evtEmitRcvd:
      case evtResetRcvd:

      case evtBlockTimeout:
      case evtChargeTimeout:
      case evtEmitTimeout:
      case evtHelloDelayTimeout:
      case evtInactivityTimeout:
      default :
        IF_TRACED(TRC_STATE)
            printf("smS: Nascent handler ignored event %s\n",smEvent_names[evt->evtType]);
        END_TRACE
        break;
    }

    return PROCESSING_COMPLETED;
}

/***********************  P E N D I N G   S T A T E  ***********************/

static
enum sm_Status
smS_PendingHandler  ( protocol_event_t *evt )
{
    IF_TRACED(TRC_STATE)
        printf("smS[%p%s] (Pending): Entered with event %s", evt->ssn,
               (evt->ssn == g_topo_session)?"-T":"", smEvent_names[evt->evtType]);
        if (g_this_event.evtType==evtPacketRcvd)
        {
            printf(" (%s)\n",Topo_opcode_names[g_opcode]);
        } else {
            puts("");
        }
    END_TRACE

     switch (evt->evtType)
    {
      case evtDiscoverRcvd:
        /* Normally, we are entered with isAckingMe initialized to FALSE,
         * but the faked events from other state machines will all have it
         * set to TRUE already, which will be recognized in is_acking_me() */

        /* The changed-XID arcs must also be handled here */

        if (is_acking_me())
        {
//*/        DEBUG({puts("is acking me....");})
            evt->isAckingMe = TRUE;

            /* Discover-acking-changed-XID arc says we must reset the smT if this
             * event is associated with the topo-session. Then we process it as
             * the Discover, afterwards. */
            if (g_sequencenum  &&  evt->ssn->ssn_XID != g_sequencenum  &&  g_topo_session == evt->ssn)
            {
                bool_t  isActuallyInternal = g_this_event.isInternalEvt;

                IF_TRACED(TRC_PACKET)
                    printf("smS (Pending): Discover-ack, new XID (%d) != old XID (%d); resetting topo session....\n",
                           g_sequencenum, evt->ssn->ssn_XID);
                END_TRACE
                g_this_event.evtType = evtResetRcvd;
                g_this_event.isInternalEvt = TRUE;
                smT_process_event( &g_this_event );
                g_this_event.evtType = evtDiscoverRcvd;
                g_this_event.isInternalEvt = isActuallyInternal;
                IF_TRACED(TRC_PACKET)
                    printf("smS (Pending): After topo reset, re-creating the topo-session ptr....\n");
                END_TRACE
                g_topo_session = evt->ssn;
                /* Regardless of whether this is acking or not, we must accept the new XID, unless it's zero */
                evt->ssn->ssn_XID = g_sequencenum;
            }

            IF_TRACED(TRC_STATE)
                printf("smS[%X] (Pending): Leaving for Complete.\n", (uint)evt->ssn);
            END_TRACE
            evt->ssn->ssn_state = smS_Complete;
            restart_inactivity_timer((evt->ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) ? TOPO_CMD_ACTIVITYTIMEOUT : TOPO_GENERAL_ACTIVITYTIMEOUT);
        } else {
            /* Discover-noack-changed-XID arc says we must reset the smT if this
             * event is associated with the topo-session. Then we process it as
             * the Discover, afterwards. */
            if (g_sequencenum  &&  evt->ssn->ssn_XID != g_sequencenum  &&  g_topo_session == evt->ssn)
            {
                bool_t  isActuallyInternal = g_this_event.isInternalEvt;

                IF_TRACED(TRC_PACKET)
                    printf("smS (Pending): Discover-noack, new XID (%d) != old XID (%d); resetting topo session....\n",
                           g_sequencenum, evt->ssn->ssn_XID);
                END_TRACE
                g_this_event.evtType = evtResetRcvd;
                g_this_event.isInternalEvt = TRUE;
                smT_process_event( &g_this_event );
                g_this_event.evtType = evtDiscoverRcvd;
                g_this_event.isInternalEvt = isActuallyInternal;
                IF_TRACED(TRC_PACKET)
                    printf("smS (Pending): After topo reset, re-creating the topo-session ptr....\n");
                END_TRACE
                g_topo_session = evt->ssn;
                /* Regardless of whether this is acking or not, we must accept the new XID, unless it's zero */
                evt->ssn->ssn_XID = g_sequencenum;
            }
            restart_inactivity_timer(TOPO_HELLO_ACTIVITYTIMEOUT);
        }
        break;

      case evtInactivityTimeout:
      case evtResetRcvd:
        /* is this session the topology session? */
        if (evt->ssn == g_topo_session  &&  g_topo_session->ssn_is_valid == TRUE)
        {
            /* Must reset the Temporary sessions, as well, then. */
            session_t   *ssn = &g_sessions[0];
            int i;
            for (i=0; i < MAX_NUM_SESSIONS; ssn++, i++)
            {
                if ( (ssn->ssn_is_valid) && (ssn->ssn_state==smS_Temporary) )
                {
                    IF_TRACED(TRC_STATE)
                        printf("smS[%X] (Temporary): Leaving for Nascent.\n", (uint)ssn);
                    END_TRACE
                    ssn->ssn_state = smS_Nascent;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -