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 ); }
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); }
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; } }
/* * 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); }
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; }
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 ); }
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; }
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 ); }
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; }
/* * 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; }
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); } } }