示例#1
0
WORD e_clos( STATE_STR *st, SS_STR *ss )
{
	/* Hier werden die Zust�nde in state_str eingetragen, die von st mit EPSILON-�berg�ngen aus erreichbar sind. */
	NEA_STATE	*nea;
	REG WORD	i;
	LONG		state;
	WORD		pos;

	/* Alle Zust�nde von st auf den Stack */
	copy( st, &e_stack );
	copy( st, &e_cls );

#ifdef DUMP

	for( i = 0; i < e_cls.count; i++ )
		fprintf( stderr, "\ne_closure(%ld, EPSILON) = %ld", e_cls.states[i], e_cls.states[i] );

#endif
		
	/* Solange Zust�nde auf dem Stack sind */
	while( ( state = pop_stack( &e_stack ) ) >= 0 )
	{
		/* Zeiger auf NEA_STATE holen */
		nea = &nea_state[state];

		/* Alle Zielzust�nde von states auf EPSILON-�berg�nge pr�fen */
		for( i = 0; i < nea->bra_count; i++ )
		{
			/* Hat state EPSILON-�berg�nge ? */
			if( nea->bra_str[i].eps )
			{
#ifdef DUMP
				fprintf( stderr, "\ne_closure(%ld, EPSILON) = %ld", state, nea->bra_str[i].bra );
#endif
				/* Ja, in e_cls und auf den Stack einf�gen */
				insert_state( &e_cls, nea->bra_str[i].bra );
				insert_state( &e_stack, nea->bra_str[i].bra );
			}
#ifdef DUMP
			else
				fprintf( stderr, "\ne_closure(%ld, EPSILON) = FALSE", state );
#endif
		}
	}

	/* Nun die Zustandsmenge in DSTATES eintragen */
	if( ( pos = insert_dstates( &e_cls, ss ) ) < 0 )
		/* Fehler */
		return( -1 );

	/* Position im Stack zur�cksetzen */
	e_stack.pos = 0;
	e_stack.count = 0;

	/* e_cls zur�cksetzen */
	e_cls.count = 0;

	/* Alles OK */
	return( pos );
}
示例#2
0
static inline void instance_init(fcs_dbm_solver_instance_t *const instance,
    const fcs_dbm_variant_type_t local_variant, fcs_cache_key_t *init_state,
    long max_num_elements_in_cache)
{
    instance->local_variant = local_variant;
    instance->solution_was_found = FALSE;
    instance->should_terminate = DONT_TERMINATE;

    instance->count_num_processed = 0;
    instance->max_count_num_processed = LONG_MAX;

    instance->store = (Pvoid_t)NULL;
    instance->stack = NULL;
    instance->max_stack_depth = 0;
    instance->stack_depth = 0;

    fc_solve_meta_compact_allocator_init(&(instance->meta_alloc));
    fc_solve_compact_allocator_init(
        &(instance->derived_list_allocator), &(instance->meta_alloc));
    instance->derived_list_recycle_bin = NULL;

    fcs_pdfs_cache_init(
        &(instance->cache), max_num_elements_in_cache, &(instance->meta_alloc));

    insert_state(&(instance->store), init_state);

    instance__inspect_new_state(instance, init_state);
}
示例#3
0
void build_CFSM()
{
    GRAMMAR *G_ptr;
    Config_set *config_ptr , *tmp;
    // create the start state of CFSM
    create_new_state( G_start , G_start->rhs_string );
    
    config_ptr = state_start->config_set;
    
    while( config_ptr != NULL )
    {
        tmp = go_to0( state_start->config_set , config_ptr->dot );
        if( search_state(tmp) == FALSE )
        {
            insert_state(tmp);
            //view_state(state_num-1);
        }
        //view_config_set( tmp );
        
        config_ptr = config_ptr->set_next;
    }
    

     
}
示例#4
0
/*
 * unlink a state object from the hash table that had a zero
 * rcookie before, and rehash it into the right place
 */
void
rehash_state(struct state *st)
{
    unsigned bucket = 0;
    /* unlink from forward chain */
    struct state **p = st->st_hashchain_prev == NULL
	? state_hash(st->st_icookie, zero_cookie, &bucket)
	: &st->st_hashchain_prev->st_hashchain_next;

    DBG(DBG_CONTROL
	, DBG_log("rehashing state object #%lu from bucket %u"
                  , st->st_serialno, bucket));

    /* unlink from forward chain */
    passert(*p == st);
    *p = st->st_hashchain_next;

    /* unlink from backward chain */
    if (st->st_hashchain_next != NULL)
    {
	passert(st->st_hashchain_next->st_hashchain_prev == st);
	st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
    }

    st->st_hashchain_next = st->st_hashchain_prev = NULL;

    /* now, re-insert */
    insert_state(st);
}
示例#5
0
static inline state_t *
seize_state(uint16_t x, uint16_t y, uint16_t vx, uint16_t vy)
{
	assert(!list_is_empty(&idle_list));
	state_t *s = CONTAINER_OF(list_pop_front(&idle_list), state_t, node);
	s->x = x;
	s->y = y;
	s->vx = vx;
	s->vy = vy;
	s->dt = -1;
	s->metric = 0.0;
	s->color = 0;
	s->from.ax = 0;
	s->from.ay = 0;
	s->from.norm = 0;
	insert_state(s);
	return s;
}
示例#6
0
WORD move_it( WORD dstates_ind, WORD c )
{
	/* Hier werden die Zust�nde eingetragen, die in der Zustandsmenge dstates einen �bergang mit c haben. */
	NEA_STATE	*nea;
	REG WORD	i;
	WORD		pos = 0, flg = 0;

	/* Initialisieren */
	move.pos = move.count = 0;

	/* Solange ein Zustand da ist */
	while( pos++ < nea_count )
	{
		/* Ist das Bit gesetzt ? */
		if( dstates[dstates_ind].states[pos / CHAR_BIT] & ( 1 << ( pos % CHAR_BIT ) ) )
		{
			/* Zeiger auf NEA_STATE holen */
			nea = &nea_state[pos];

			/* Alle Zielzust�nde von states auf c-�berg�nge pr�fen */
			for( i = 0; i < nea->bra_count; i++ )
			{
				/* Hat state einen �bergang mit c ? */
				if( nea->bra_str[i].ccl_str.ccl[c / CHAR_BIT] & ( 1 << ( c % CHAR_BIT ) ) )
				{
#ifdef DUMP
					fprintf( stderr, "\nMOVE[%d][%c] = %d", pos, ( BYTE ) c, ( WORD ) nea->bra_str[i].bra );
#endif
					/* Ja, in move eintragen */
					insert_state( &move, nea->bra_str[i].bra );

					/* Flag setzen */
					flg++;
				}
			}
		}
	}

	/* Wert zur�ckliefern */
	return( flg > 0 ? 0 : 1 );
}
示例#7
0
static inline void instance__inspect_new_state(
    fcs_dbm_solver_instance_t *const instance, fcs_cache_key_t *const state)
{
    instance->count_num_processed++;

    if (fcs_pdfs_cache_does_key_exist(&(instance->cache), &(state->s)))
    {
        instance->stack_depth--;
        return;
    }
    const fcs_dbm_variant_type_t local_variant = instance->local_variant;
    const int depth = (instance->stack_depth);
    const int max_depth = instance->max_stack_depth;
    if (depth == max_depth)
    {
        instance->stack =
            SREALLOC(instance->stack, ++(instance->max_stack_depth));
        pseduo_dfs_stack_item_t *const stack_item = instance->stack + max_depth;
        stack_item->next_states = NULL;
        stack_item->max_count_next_states = 0;
    }
    pseduo_dfs_stack_item_t *const stack_item = instance->stack + depth;
    stack_item->curr_state = state;

    fcs_derived_state_t *derived_list = NULL, *derived_iter = NULL;

    if (instance_solver_thread_calc_derived_states(instance->local_variant,
            state, NULL, &derived_list, &(instance->derived_list_recycle_bin),
            &(instance->derived_list_allocator), TRUE))
    {
        instance->should_terminate = SOLUTION_FOUND_TERMINATE;
        instance->solution_was_found = TRUE;
        return;
    }

    stack_item->count_next_states = 0;
    stack_item->next_state_idx = 0;
    fcs_kv_state_t kv;
    /* Now recycle the derived_list */
    while (derived_list)
    {
        kv.key = &(derived_list->state.s);
        kv.val = &(derived_list->state.info);
        fc_solve_canonize_state(kv.key, FREECELLS_NUM, STACKS_NUM);

        if (!lookup_state(
                &(instance->store), &(instance->cache), &(derived_list->state)))
        {
            int i = (stack_item->count_next_states)++;
            if (i >= stack_item->max_count_next_states)
            {
                stack_item->next_states = SREALLOC(stack_item->next_states,
                    ++(stack_item->max_count_next_states));
            }
            stack_item->next_states[i] = derived_list->state;
            insert_state(&(instance->store), &(stack_item->next_states[i]));
        }
#define derived_list_next derived_iter
        derived_list_next = derived_list->next;
        derived_list->next = instance->derived_list_recycle_bin;
        instance->derived_list_recycle_bin = derived_list;
        derived_list = derived_list_next;
#undef derived_list_next
    }

    return;
}
示例#8
0
WORD gen_dea( VOID )
{
	/* Hier wird nun aus den NEAen DEAen. */
	REG LONG	i;
/*
	/* Alle SCs */
	for( i = 0; i < ss_str_count; i++ )
	{
*/

#ifndef NO_MIN_DEA

		/* Die Zustandsminimierung durchf�hren */
		if( gen_d( &ss_str[0] ) < 0 )
			/* Fehler */
			return( -1 );
#endif

		/* Die NEAen in DEAen wandeln */
		if( gen_dtran( &ss_str[0] ) < 0 )
			/* Fehler */
			return( -1 );

#ifndef NO_MIN_DEA

		/* Die Zustandsmenge des DEA minimieren */
		if( min_dfa() < 0 )
			/* Fehler */
			return( -1 );
#endif

		output_dstates();

/*
		/* Die Zustandsminimierung durchf�hren */
		if( gen_d( &ss_str[0] ) < 0 )
			/* Fehler */
			return( -1 );

		/* Die Zustandsmenge des DEA minimieren */
		if( min_dfa() < 0 )
			/* Fehler */
			return( -1 );

		/* Den Zeiger auf DTRAN in die SS_STR eintragen */
		ss_str[i].dtran = dtran;

		/* Speicher freigeben */
		free( ( VOID * ) dtran );
*/

#ifdef DUMP3
		push_tab();
#endif

/*	}
*/
	/* Alles OK */
	return( 0 );
}


WORD init( VOID )
{
	/* Hier werden ein paar wichtige Datenstrukturen initialisiert. */

	/* Array f�r die Zust�nde */
	if( ( e_cls.states = ( LONG * ) malloc( sizeof( LONG ) * nea_count ) ) == NULL )
		/* Fehler */
		return( -1 );

	/* Array f�r die Zust�nde */
	if( ( e_stack.states = ( LONG * ) malloc( sizeof( LONG ) * nea_count ) ) == NULL )
		/* Fehler */
		return( -1 );

	/* Array f�r die Zust�nde */
	if( ( move.states = ( LONG * ) malloc( sizeof( LONG ) * nea_count ) ) == NULL )
		/* Fehler */
		return( -1 );

	/* Alles OK */
	return( 0 );
}


WORD gen_dtran( SS_STR *ss )
{
	/* Hier werden die NEAen in der SC ss zu DEAen. */
	REG WORD	i;
	WORD		pos, ind = 0;

	/* Anzahl der Zust�nde dieses NEAs festlegen */
	nea_states = nea_str[ss->nea_all].state_arr_count;

	/* Ersteinmal ein bi�chen initialisieren */
	if( init() < 0 )
		/* Fehler */
		return( -1 );

	/* Den Startzustand des NEA eintragen, der alle die beinhaltet, die am Zeilenanfang stehen d�rfen */
	insert_state( &move, nea_str[ss->nea_all].start_state );

	/* e_closure(0) */
	if( ( pos = e_clos( &move, ss ) ) < 0 )
		/* Fehler */
		return( -1 );

	/* Solange es einen unmarkierten Zustand in DSTATES gibt */
	while( ( ind < dstates_count ) && !dstates[ind].marked )
	{
		/* Zustand markieren */
		dstates[ind].marked++;

		/* Nun alle Eingabezeichen, move etc. */
		for( i = 0; i < all_char_count; i++ )
		{
			/* Die Zust�nde bestimmen, die aus e_cls einen Sprung�bergang mit i haben */
			if( !( move_it( ind, all_char[i] ) ) )
			{
				/* Nun die e_closure-Menge berechnen */
				if( ( pos = e_clos( &move, ss ) ) < 0 )
					/* Fehler */
					return( -1 );

				/* Zu Zustandsmenge in DTRAN eintragen */
				insert_dtran( ind, pos, all_char[i] );
			}
		}

		/* N�chsten Eintrag in DSTATES untersuchen */
		ind++;
	}

	/* Alles OK */
	return( 0 );
}
示例#9
0
Config_set *go_to0( Config_set *Set , TOKEN *X )
{
    Config_set *ptr , *tmp , *new_set , *new_set_start;
    GRAMMAR *G_ptr;

        
    new_set = NULL;
    for ( ptr = Set ; ptr != NULL ; ptr = ptr->set_next )
    {
        if( ptr->dot == NULL )
            if( X == NULL )
            {
                // add A -> £]X¡E£^ to new_set
                if ( new_set == NULL )
                {
                    new_set = create_config_set( ptr->rule , ptr->dot->next );
                    new_set_start = new_set;
                }
                else
                {
                    new_set->set_next = create_config_set( ptr->rule , ptr->dot->next );
                    new_set = new_set->set_next;
                }    
            }    
            else
                continue;
            
        if ( strcmp( ptr->dot->string , X->string ) == 0 )
        {
            // add A -> £]X¡E£^ to new_set
            if ( new_set == NULL )
            {
                new_set = create_config_set( ptr->rule , ptr->dot->next );
                new_set_start = new_set;
            }
            else
            {
                new_set->set_next = create_config_set( ptr->rule , ptr->dot->next );
                new_set = new_set->set_next;
            }
        }
    }
    
    if( search_state(new_set_start) == TRUE )
        return NULL;
    
    //printf("dot: %s\n",new_set_start->dot->string);
    //do closure 0
    for( ptr = new_set_start ; ptr != NULL ; ptr = ptr->set_next )
    {
         if( ptr->dot == NULL )
             continue;
         G_ptr = search_grammar( G_start , ptr->dot->string );
         do{
             if ( G_ptr == NULL )
                 break;
             insert_config( new_set_start , G_ptr );
             G_ptr = G_ptr->next;
             if( G_ptr == NULL )
                 break;             
         }while( strcmp( G_ptr->lhs , ptr->dot->string ) == 0 );
    }

    insert_state(new_set_start);
    // go to next level
    ptr = new_set_start;    
    while( ptr != NULL )
    {
        if( ptr->dot != NULL )
            tmp = go_to0( new_set_start , ptr->dot );
            //return new_set_start;
        
        
        //if(  tmp != NULL && search_state(tmp) == FALSE )
        //{
            //view_config_set( tmp );
            //insert_state(tmp);
        //}
        //else
        //    free_config(&tmp);
       
        
        ptr = ptr->set_next;
    }
    
    
    //view_config_set(new_set_start);
    return new_set_start;
}
示例#10
0
/*
 * set some bits on a range in the tree.
 */
int set_extent_bits(struct extent_io_tree *tree, u64 start,
                    u64 end, int bits, gfp_t mask)
{
    struct extent_state *state;
    struct extent_state *prealloc = NULL;
    struct cache_extent *node;
    int err = 0;
    u64 last_start;
    u64 last_end;
again:
    if (!prealloc) {
        prealloc = alloc_extent_state();
        if (!prealloc)
            return -ENOMEM;
    }

    /*
     * this search will find the extents that end after
     * our range starts
     */
    node = search_cache_extent(&tree->state, start);
    if (!node) {
        err = insert_state(tree, prealloc, start, end, bits);
        BUG_ON(err == -EEXIST);
        prealloc = NULL;
        goto out;
    }

    state = container_of(node, struct extent_state, cache_node);
    last_start = state->start;
    last_end = state->end;

    /*
     * | ---- desired range ---- |
     * | state |
     *
     * Just lock what we found and keep going
     */
    if (state->start == start && state->end <= end) {
        state->state |= bits;
        merge_state(tree, state);
        if (last_end == (u64)-1)
            goto out;
        start = last_end + 1;
        goto search_again;
    }
    /*
     *     | ---- desired range ---- |
     * | state |
     *   or
     * | ------------- state -------------- |
     *
     * We need to split the extent we found, and may flip bits on
     * second half.
     *
     * If the extent we found extends past our
     * range, we just split and search again.  It'll get split
     * again the next time though.
     *
     * If the extent we found is inside our range, we set the
     * desired bit on it.
     */
    if (state->start < start) {
        err = split_state(tree, state, prealloc, start);
        BUG_ON(err == -EEXIST);
        prealloc = NULL;
        if (err)
            goto out;
        if (state->end <= end) {
            state->state |= bits;
            start = state->end + 1;
            merge_state(tree, state);
            if (last_end == (u64)-1)
                goto out;
            start = last_end + 1;
        } else {
            start = state->start;
        }
        goto search_again;
    }
    /*
     * | ---- desired range ---- |
     *     | state | or               | state |
     *
     * There's a hole, we need to insert something in it and
     * ignore the extent we found.
     */
    if (state->start > start) {
        u64 this_end;
        if (end < last_start)
            this_end = end;
        else
            this_end = last_start -1;
        err = insert_state(tree, prealloc, start, this_end,
                           bits);
        BUG_ON(err == -EEXIST);
        prealloc = NULL;
        if (err)
            goto out;
        start = this_end + 1;
        goto search_again;
    }
    /*
     * | ---- desired range ---- |
     * | ---------- state ---------- |
     * We need to split the extent, and set the bit
     * on the first half
     */
    err = split_state(tree, state, prealloc, end + 1);
    BUG_ON(err == -EEXIST);

    state->state |= bits;
    merge_state(tree, prealloc);
    prealloc = NULL;
out:
    if (prealloc)
        btrfs_free_extent_state(prealloc);
    return err;
search_again:
    if (start > end)
        goto out;
    goto again;
}
示例#11
0
static stf_status aggr_inI1_outR1_common(struct msg_digest *md,
					 int authtype)
{
	/* With Aggressive Mode, we get an ID payload in this, the first
	 * message, so we can use it to index the preshared-secrets
	 * when the IP address would not be meaningful (i.e. Road
	 * Warrior).  So our first task is to unravel the ID payload.
	 */
	struct state *st;
	struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
	struct connection *c = find_host_connection(&md->iface->ip_addr,
						    md->iface->port,
						    &md->sender,
						    md->sender_port, LEMPTY);

#if 0
	if (c == NULL && md->iface->ike_float) {
		c = find_host_connection(&md->iface->addr,
					 pluto_nat_port,
					 &md->sender, md->sender_port, LEMPTY);
	}
#endif

	if (c == NULL) {
		/* see if a wildcarded connection can be found */
		pb_stream pre_sa_pbs = sa_pd->pbs;
		lset_t policy = preparse_isakmp_sa_body(&pre_sa_pbs) |
				POLICY_AGGRESSIVE;

		c = find_host_connection(&md->iface->ip_addr, pluto_port,
					 (ip_address*)NULL, md->sender_port,
					 policy);
		if (c == NULL || (c->policy & POLICY_AGGRESSIVE) == 0) {
			ipstr_buf b;

			loglog(RC_LOG_SERIOUS, "initial Aggressive Mode message from %s"
			       " but no (wildcard) connection has been configured%s%s",
			       ipstr(&md->sender, &b),
			       (policy != LEMPTY) ? " with policy=" : "",
			       (policy != LEMPTY) ?
			       bitnamesof(sa_policy_bit_names, policy) : "");
			/* XXX notification is in order! */
			return STF_IGNORE;
		}
		/* Create a temporary connection that is a copy of this one.
		 * His ID isn't declared yet.
		 */
		c = rw_instantiate(c, &md->sender, NULL, NULL);
	}

	/* Set up state */
	cur_state = md->st = st = new_state();  /* (caller will reset cur_state) */
	st->st_connection = c;
	st->st_remoteaddr = md->sender;
	st->st_remoteport = md->sender_port;
	st->st_localaddr  = md->iface->ip_addr;
	st->st_localport  = md->iface->port;
	st->st_interface  = md->iface;
	change_state(st, STATE_AGGR_R1);

	/* until we have clue who this is, then be conservative about allocating
	 * them any crypto bandwidth
	 */
	st->st_import = pcim_stranger_crypto;

	st->st_policy |= POLICY_AGGRESSIVE;

	st->st_oakley.auth = authtype;

	if (!ikev1_decode_peer_id(md, FALSE, TRUE)) {
		char buf[IDTOA_BUF];
		ipstr_buf b;

		(void) idtoa(&st->st_connection->spd.that.id, buf,
			     sizeof(buf));
		loglog(RC_LOG_SERIOUS,
		       "initial Aggressive Mode packet claiming to be from %s"
		       " on %s but no connection has been authorized",
		       buf, ipstr(&md->sender, &b));
		/* XXX notification is in order! */
		return STF_FAIL + INVALID_ID_INFORMATION;
	}

	c = st->st_connection;

	extra_debugging(c);
	st->st_try = 0;                                 /* Not our job to try again from start */
	st->st_policy = c->policy & ~POLICY_IPSEC_MASK; /* only as accurate as connection */

	memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
	get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);

	insert_state(st); /* needs cookies, connection, and msgid (0) */

	st->st_doi = ISAKMP_DOI_IPSEC;
	st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */

	{
		ipstr_buf b;

		libreswan_log("responding to Aggressive Mode, state #%lu, connection \"%s\" from %s",
			st->st_serialno, st->st_connection->name,
			ipstr(&c->spd.that.host_addr, &b));
	}

	merge_quirks(st, md);

	set_nat_traversal(st, md);

	/* save initiator SA for HASH */
	clonereplacechunk(st->st_p1isa, sa_pd->pbs.start,
		pbs_room(&sa_pd->pbs), "sa in aggr_inI1_outR1()");

	/*
	 * parse_isakmp_sa picks the right group, which we need to know
	 * before we do any calculations. We will call it again to have it
	 * emit the winning SA into the output.
	 */
	/* SA body in */
	{
		pb_stream sabs = sa_pd->pbs;

		RETURN_STF_FAILURE(parse_isakmp_sa_body(&sabs,
							&sa_pd->payload.sa,
							NULL, FALSE, st));
	}

	/* KE in */
	RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group,
				     &md->chain[ISAKMP_NEXT_KE]->pbs));

	/* Ni in */
	RETURN_STF_FAILURE(accept_v1_nonce(md, &st->st_ni, "Ni"));

	{
		struct ke_continuation *ke = alloc_thing(
			struct ke_continuation,
			"outI2 KE");

		ke->ke_md = md;
		set_suspended(st, md);

		if (!st->st_sec_in_use) {
			/* need to calculate KE and Nonce */
			pcrc_init(&ke->ke_pcrc, aggr_inI1_outR1_continue1);
			return build_ke(&ke->ke_pcrc, st, st->st_oakley.group,
					st->st_import);
		} else {
			/* KE and Nonce calculated */
			ke->ke_pcrc.pcrc_serialno = st->st_serialno;	/* transitional */
			return aggr_inI1_outR1_tail(&ke->ke_pcrc, NULL);
		}
	}
}