?? mdb.c
字號:
} else if (lease -> uid != &lease -> uid_buf [0]) { comp -> uid = lease -> uid; comp -> uid_max = lease -> uid_max; lease -> uid = (unsigned char *)0; lease -> uid_max = 0; comp -> uid_len = lease -> uid_len; lease -> uid_len = 0; } else { log_fatal ("corrupt lease uid."); /* XXX */ } } else { comp -> uid = (unsigned char *)0; comp -> uid_len = comp -> uid_max = 0; } if (comp -> host) host_dereference (&comp -> host, MDL); host_reference (&comp -> host, lease -> host, MDL); comp -> hardware_addr = lease -> hardware_addr; comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) | (comp -> flags & ~EPHEMERAL_FLAGS)); if (comp -> scope) binding_scope_dereference (&comp -> scope, MDL); if (lease -> scope) { binding_scope_reference (&comp -> scope, lease -> scope, MDL); binding_scope_dereference (&lease -> scope, MDL); } if (comp -> agent_options) option_chain_head_dereference (&comp -> agent_options, MDL); if (lease -> agent_options) { /* Only retain the agent options if the lease is still affirmatively associated with a client. */ if (lease -> next_binding_state == FTS_ACTIVE || lease -> next_binding_state == FTS_EXPIRED || lease -> next_binding_state == FTS_RESERVED || lease -> next_binding_state == FTS_BOOTP) option_chain_head_reference (&comp -> agent_options, lease -> agent_options, MDL); option_chain_head_dereference (&lease -> agent_options, MDL); } /* Record the hostname information in the lease. */ if (comp -> client_hostname) dfree (comp -> client_hostname, MDL); comp -> client_hostname = lease -> client_hostname; lease -> client_hostname = (char *)0; if (lease -> on_expiry) { if (comp -> on_expiry) executable_statement_dereference (&comp -> on_expiry, MDL); executable_statement_reference (&comp -> on_expiry, lease -> on_expiry, MDL); } if (lease -> on_commit) { if (comp -> on_commit) executable_statement_dereference (&comp -> on_commit, MDL); executable_statement_reference (&comp -> on_commit, lease -> on_commit, MDL); } if (lease -> on_release) { if (comp -> on_release) executable_statement_dereference (&comp -> on_release, MDL); executable_statement_reference (&comp -> on_release, lease -> on_release, MDL); } /* Record the lease in the uid hash if necessary. */ if (enter_uid && comp -> uid) { uid_hash_add (comp); } /* Record it in the hardware address hash if necessary. */ if (enter_hwaddr && lease -> hardware_addr.hlen) { hw_hash_add (comp); } #if defined (FAILOVER_PROTOCOL) comp -> cltt = lease -> cltt; comp -> tstp = lease -> tstp; comp -> tsfp = lease -> tsfp;#endif /* FAILOVER_PROTOCOL */ comp -> ends = lease -> ends; comp -> next_binding_state = lease -> next_binding_state; just_move_it: if (!comp -> pool) { log_error ("Supersede_lease: lease %s with no pool.", piaddr (comp -> ip_addr)); return 0; } /* Figure out which queue it's on. */ switch (comp -> binding_state) { case FTS_FREE: lq = &comp -> pool -> free; comp -> pool -> free_leases--; break; case FTS_ACTIVE: case FTS_RESERVED: case FTS_BOOTP: lq = &comp -> pool -> active; break; case FTS_EXPIRED: case FTS_RELEASED: case FTS_RESET: lq = &comp -> pool -> expired; break; case FTS_ABANDONED: lq = &comp -> pool -> abandoned; break; case FTS_BACKUP: lq = &comp -> pool -> backup; comp -> pool -> backup_leases--; break; default: log_error ("Lease with bogus binding state: %d", comp -> binding_state);#if defined (BINDING_STATE_DEBUG) abort ();#endif return 0; } /* Remove the lease from its current place in its current timer sequence. */ prev = (struct lease *)0; for (lp = *lq; lp; lp = lp -> next) { if (lp == comp) break; prev = lp; } if (!lp) { log_error ("Lease with binding state %s not on its queue.", (comp -> binding_state < 1 && comp -> binding_state < FTS_BOOTP) ? "unknown" : binding_state_names [comp -> binding_state - 1]); return 0; } if (prev) { lease_dereference (&prev -> next, MDL); if (comp -> next) { lease_reference (&prev -> next, comp -> next, MDL); lease_dereference (&comp -> next, MDL); } } else { lease_dereference (lq, MDL); if (comp -> next) { lease_reference (lq, comp -> next, MDL); lease_dereference (&comp -> next, MDL); } } /* Make the state transition. */ if (commit || !pimmediate) make_binding_state_transition (comp); /* Put the lease back on the appropriate queue. If the lease is corrupt (as detected by lease_enqueue), don't go any farther. */ if (!lease_enqueue (comp)) return 0; /* If this is the next lease that will timeout on the pool, zap the old timeout and set the timeout on this pool to the time that the lease's next event will happen. We do not actually set the timeout unless commit is true - we don't want to thrash the timer queue when reading the lease database. Instead, the database code calls the expiry event on each pool after reading in the lease file, and the expiry code sets the timer if there's anything left to expire after it's run any outstanding expiry events on the pool. */ if ((commit || !pimmediate) && comp -> sort_time != MIN_TIME && comp -> sort_time > cur_time && (comp -> sort_time < comp -> pool -> next_event_time || comp -> pool -> next_event_time == MIN_TIME)) { comp -> pool -> next_event_time = comp -> sort_time; add_timeout (comp -> pool -> next_event_time, pool_timer, comp -> pool, (tvref_t)pool_reference, (tvunref_t)pool_dereference); } if (commit) { if (!write_lease (comp)) return 0; if (!commit_leases ()) return 0; }#if defined (FAILOVER_PROTOCOL) if (propogate) { if (!dhcp_failover_queue_update (comp, pimmediate)) return 0; }#endif /* If the current binding state has already expired, do an expiry event right now. */ /* XXX At some point we should optimize this so that we don't XXX write the lease twice, but this is a safe way to fix the XXX problem for 3.0 (I hope!). */ if ((commit || !pimmediate) && comp -> sort_time < cur_time && comp -> next_binding_state != comp -> binding_state) pool_timer (comp -> pool); return 1;}void make_binding_state_transition (struct lease *lease){#if defined (FAILOVER_PROTOCOL) dhcp_failover_state_t *peer; if (lease && lease -> pool && lease -> pool -> failover_peer) peer = lease -> pool -> failover_peer; else peer = (dhcp_failover_state_t *)0;#endif /* If the lease was active and is now no longer active, but isn't released, then it just expired, so do the expiry event. */ if (lease -> next_binding_state != lease -> binding_state && ((#if defined (FAILOVER_PROTOCOL) peer && lease -> binding_state == FTS_EXPIRED && (lease -> next_binding_state == FTS_FREE || lease -> next_binding_state == FTS_BACKUP)) || (!peer &&#endif (lease -> binding_state == FTS_ACTIVE || lease -> binding_state == FTS_BOOTP || lease -> binding_state == FTS_RESERVED) && lease -> next_binding_state != FTS_RELEASED))) {#if defined (NSUPDATE) ddns_removals (lease);#endif if (lease -> on_expiry) { execute_statements ((struct binding_value **)0, (struct packet *)0, lease, (struct client_state *)0, (struct option_state *)0, (struct option_state *)0, /* XXX */ &lease -> scope, lease -> on_expiry); if (lease -> on_expiry) executable_statement_dereference (&lease -> on_expiry, MDL); } /* No sense releasing a lease after it's expired. */ if (lease -> on_release) executable_statement_dereference (&lease -> on_release, MDL); if (lease -> billing_class) unbill_class (lease, lease -> billing_class); /* Send the expiry time to the peer. */ lease -> tstp = lease -> ends; } /* If the lease was active and is now released, do the release event. */ if (lease -> next_binding_state != lease -> binding_state && ((#if defined (FAILOVER_PROTOCOL) peer && lease -> binding_state == FTS_RELEASED && (lease -> next_binding_state == FTS_FREE || lease -> next_binding_state == FTS_BACKUP)) || (!peer &&#endif (lease -> binding_state == FTS_ACTIVE || lease -> binding_state == FTS_BOOTP || lease -> binding_state == FTS_RESERVED) && lease -> next_binding_state == FTS_RELEASED))) {#if defined (NSUPDATE) ddns_removals (lease);#endif if (lease -> on_release) { execute_statements ((struct binding_value **)0, (struct packet *)0, lease, (struct client_state *)0, (struct option_state *)0, (struct option_state *)0, /* XXX */ &lease -> scope, lease -> on_release); executable_statement_dereference (&lease -> on_release, MDL); } /* A released lease can't expire. */ if (lease -> on_expiry) executable_statement_dereference (&lease -> on_expiry, MDL); if (lease -> billing_class) unbill_class (lease, lease -> billing_class); /* Send the release time (should be == cur_time) to the peer. */ lease -> tstp = lease -> ends; }#if defined (DEBUG_LEASE_STATE_TRANSITIONS) log_debug ("lease %s moves from %s to %s", piaddr (lease -> ip_addr), binding_state_print (lease -> binding_state), binding_state_print (lease -> next_binding_state));#endif lease -> binding_state = lease -> next_binding_state; switch (lease -> binding_state) { case FTS_ACTIVE: case FTS_BOOTP:#if defined (FAILOVER_PROTOCOL) if (lease -> pool && lease -> pool -> failover_peer) lease -> next_binding_state = FTS_EXPIRED; else#endif lease -> next_binding_state = FTS_FREE; break; case FTS_EXPIRED: case FTS_RELEASED: case FTS_ABANDONED: case FTS_RESET: lease -> next_binding_state = FTS_FREE; /* If we are not in partner_down, leases don't go from EXPIRED to FREE on a timeout - only on an update. If we're in partner_down, they expire at mclt past the time we entered partner_down. */ if (lease -> pool -> failover_peer && lease -> pool -> failover_peer -> me.state == partner_down) lease -> tsfp = (lease -> pool -> failover_peer -> me.stos + lease -> pool -> failover_peer -> mclt); break; case FTS_FREE: case FTS_BACKUP: case FTS_RESERVED: lease -> next_binding_state = lease -> binding_state; break; }#if defined (DEBUG_LEASE_STATE_TRANSITIONS) log_debug ("lease %s: next binding state %s", piaddr (lease -> ip_addr), binding_state_print (lease -> next_binding_state));#endif}/* Copy the contents of one lease into another, correctly maintaining reference counts. */int lease_copy (struct lease **lp, struct lease *lease, const char *file, int line){ struct lease *lt = (struct lease *)0; isc_result_t status; status = lease_allocate (<, MDL); if (status != ISC_R_SUCCESS) return 0; lt -> ip_addr = lease -> ip_addr; lt -> starts = lease -> starts; lt -> ends = lease -> ends; lt -> timestamp = lease -> timestamp; lt -> uid_len = lease -> uid_len; lt -> uid_max = lease -> uid_max; if (lease -> uid == lease -> uid_buf) { lt -> uid = lt -> uid_buf; memcpy (lt -> uid_buf, lease -> uid_buf, sizeof lt -> uid_buf); } else if (!lease -> uid_max) { lt -> uid = (unsigned char *)0; } else { lt -> uid = dmalloc (lt -> uid_max, MDL); if (!lt -> uid) { lease_dereference (<, MDL); return 0; } memcpy (lt -> uid, lease -> uid, lease -> uid_max); } if (lease -> client_hostname) { lt -> client_hostname = dmalloc (strlen (lease -> client_hostname) + 1, MDL); if (!lt -> client_hostname) { lease_dereference (<, MDL); return 0; } strcpy (lt -> client_hostname, lease -> client_hostname); } if (lease -> scope) binding_scope_reference (< -> scope, lease -> scope, MDL); if (lease -> agent_options) option_chain_head_reference (< -> agent_options, lease -> agent_options, MDL); host_reference (< -> host, lease -> host, file, line); subnet_reference (< -> subnet, lease -> subnet, file, line); pool_reference (< -> pool, lease -> pool, file, line); class_reference (< -> billing_class, lease -> billing_class, file, line); lt -> hardware_addr = lease -> hardware_addr; if (lease -> on_expiry) executable_statement_reference (< -> on_expiry, lease -> on_expiry, file, line); if (lease -> on_commit) executable_statement_reference (< -> on_commit, lease -> on_commit, file, line); if (lease -> on_release) executable_statement_reference (< -> on_release, lease -> on_release, file, line); lt -> flags = lease -> flags; lt -> tstp = lease -> tstp; lt -> tsfp = lease -> tsfp; lt -> cltt = lease -> cltt; lt -> binding_state = lease -> binding_state; lt -> next_binding_state = lease -> next_binding_state; status = lease_reference (lp, lt, file, line); lease_dereference (<, MDL); return status == ISC_R_SUCCESS;}/* Release the specified lease and re-hash it as appropriate. */void release_lease (lease, packet) struct lease *lease; struct packet *packet;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -