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

📄 dhcp-client-states.c

📁 this is sample about DHCP-agent
💻 C
📖 第 1 页 / 共 3 页
字号:
            /* sleep for up to ten seconds: fixme: make this configurable. */            INFO_MESSAGE("sleeping before retry (for %"PRIu16" seconds)", 10);            sleep_random(10);            INFO_MESSAGE("retrying.");            return STATE_INIT;        }    } else {        /* we timed out. retry immediately. */        INFO_MESSAGE("timed out on DHCP REQUEST. attempting DISCOVER again.");        client_cache_delete_tmp_cache(dc->cache);        return STATE_INIT;    }}/* init-reboot state: lease exists, try to acquire it. */int client_init_reboot(dhcp_client_control_t *dc){    return client_requesting_proc(dc, STATE_INIT_REBOOT);}/* request: request a lease. */int client_requesting(dhcp_client_control_t *dc){    return client_requesting_proc(dc, STATE_INIT);}/* inform: we've assigned ourselves an IP address, try to inform a dhcp server. */int client_inform(dhcp_client_control_t *dc){    /* not implemented. */    return 0;}/* rebind: try to reacquire the lease. */int client_rebinding(dhcp_client_control_t *dc){    list_t *options;    int retval;    ip_addr_t my_addr;    INFO_MESSAGE("attempting DHCP REBIND");    my_addr = rawnet_get_ip_addr(dc->rawnet);    options = client_build_rebind_option_list(dc);    build_dhcp_request_broadcast(dc->rawnet, dc->xid, dc->secs, my_addr, 0, options);    retval =        rawnet_packet_transact(dc->rawnet, dc, NULL, client_check_rebind,                               compensate_timeout_with_timer(dc));    switch (retval) {    case RAWNET_TIMEOUT:        return STATE_BOUND; /* no response. we've timed out. */    case RAWNET_OK:        break;    case RAWNET_ERROR:        ERROR_MESSAGE("received error from raw network handler.");        return STATE_FATAL_ERROR;    case RAWNET_USER_INTERRUPT:        ERROR_MESSAGE("caught user interrupt.");        return STATE_USER_INTERRUPT;    default:        FATAL_MESSAGE("invalid return value from raw network handler -- this a bug report it.");    }    if(dhcp_is_type(dc->rawnet->dhcp_p, DHCP_DHCPACK_TM)) {        /* our lease is OK. reconfigure timers. */        client_setup_timers(dc);        return STATE_BOUND;    } else if(dhcp_is_type(dc->rawnet->dhcp_p, DHCP_DHCPNAK_TM)) {        /* we've been told our lease is no good. */        /* unconfigure everything including our interface. */        client_unconfigure(dc);        /* delete our cache. */        client_cache_delete_cache(dc->cache);        return STATE_INIT;    } else {        ERROR_MESSAGE("received neither NACK nor ACK -- this should never happen because of higher filters.");        FATAL_MESSAGE("I shouldn't be here. this is a bug report me.");        exit(1); /* get rid of compiler warning. */    }}/* renew: try to renew the lease. */int client_renewing(dhcp_client_control_t *dc){        list_t *options;    int retval;    ip_addr_t my_addr;    INFO_MESSAGE("attempting DHCP RENEW");    my_addr = rawnet_get_ip_addr(dc->rawnet);        options = client_build_renew_option_list(dc);    build_dhcp_request_unicast(dc->rawnet, dc->xid, dc->secs, options, my_addr,                               dhcp_client_get_server_ip_address(dc),                               0,                               dhcp_client_get_server_hw_address(dc));    /* find out how much time we have until the next timer.     * if we have no other timers it's an error, however     * it will be caught later now just do our best. */    retval =        rawnet_packet_transact(dc->rawnet, dc, NULL, client_check_renew,                               compensate_timeout_with_timer(dc));    switch (retval) {    case RAWNET_TIMEOUT:        return STATE_BOUND; /* no response: we've timed out. */    case RAWNET_OK:        break;    case RAWNET_ERROR:        ERROR_MESSAGE("received error from raw network handler.");        return STATE_FATAL_ERROR;    case RAWNET_USER_INTERRUPT:        ERROR_MESSAGE("caught user interrupt.");        return STATE_USER_INTERRUPT;    default:        FATAL_MESSAGE            ("dhcp-client-states: invalid return value from raw network handler -- this a bug report it.");    }    if(dhcp_is_type(dc->rawnet->dhcp_p, DHCP_DHCPACK_TM)) {        /* our lease is OK. reconfigure timers. */        client_setup_timers(dc);        return STATE_BOUND;    } else if(dhcp_is_type(dc->rawnet->dhcp_p, DHCP_DHCPNAK_TM)) {        /* we've been told our lease is no good. */        /* unconfigure everything including our interface. */        client_unconfigure(dc);        /* delete our cache. */        client_cache_delete_cache(dc->cache);        return STATE_INIT;    } else {        ERROR_MESSAGE("received neither NACK nor ACK -- this should never happen because of higher filters.");        FATAL_MESSAGE("I shouldn't be here. this is a bug report me.");        exit(1); /* get rid of compiler warning. */    }}/* we're bound and should wait for lease expiry or timers. */int client_bound(dhcp_client_control_t *dc){    uint32_t next_timer = 0; /* get rid of compiler warnings. */    time_t time_before = 0; /* get rid of compiler warnings. */    time_t time_after, time_interval;    INFO_MESSAGE("entering WAIT stage");    /* take our raw network connection down. */    rawnet_down(dc->rawnet);    if(dc->lease_time_is_infinite) {        INFO_MESSAGE("lease time is infinite. waiting forever.");        /* wait for any interrupts. */        suspend_for_interrupts();    } else {        /* peek and store our next timer in case we get an interrupt         * which is not a timer interrupt. */        next_timer = timer_peek_next_timer(dc->context->timer);        time_before = time(NULL);        /* now fire off the next timer. */        if(timer_set_next(dc->context->timer)) {            FATAL_MESSAGE("no timers set. we should have at least one for lease expiry sent to us from the server.");        }        /* wait for any interrupts: we're OK. there is no race         * condition here since our suspension will unmask us         * and allow any previous signals to affect us here. */        suspend_for_interrupts();    }        /* at this point we may or may not have received a timer     * interrupt. if we have not then setup a timer to go off     * once we return by storing a new timer with the time     * difference. */    if(peek_interrupt_type() != INTERRUPT_ALARM && !dc->lease_time_is_infinite) {        time_after = time(NULL);        time_interval = time_after - time_before; /* number of seconds elapsed. */        if(time_interval < 0) {            /* someone has been b0rking the system clock. */            WARN_MESSAGE("the system clock is skewed or you've been messing with it. i'm going to just use the next timer and hope for the best.");        } else {            /* we did not receive a timer interrupt.             * put the difference as the next timer to go off. */            next_timer -= time_interval; /* this is safe since we're promoting the type                                          * and it can never be < 0 */            if(next_timer == 0)                next_timer = 1; /* give at least one second. */            /* we just set our next timer to atleast one. this             * has one implication. if we're firing off other             * signals to the daemon (HUP for example) all the             * time it will never get the alarm.  opinion: you             * shouldn't HUP your daemon constantly.  otherwise             * we at most lag by one second which is not bad. */            timer_add_trigger(dc->context->timer, next_timer, timer_get_current_id(dc->context->timer));        }    }    /* bring the raw network devices back up.  we'll probably     * need them: FIXME, revamp into one network module that uses     * raw or user level networking depending on our interface's     * state. */    rawnet_up(dc->rawnet);    return STATE_BOUND; /* we want to return back to this state if the interrupt wasn't an alarm. */}/* release a lease. */int client_release(dhcp_client_control_t *dc){    list_t *cache_options, *options;    ip_addr_t *my_addr = NULL;    ip_addr_t ciaddr;    dhcp_opt_t *option;    INFO_MESSAGE("sending DHCP RELEASE");    cache_options = client_cache_load_options(dc->cache, 0);    list_rewind(cache_options);    while((option = list_next(cache_options)) != NULL) {        if(dhcp_opt_get_tag(option) == TAG_DHCP_REQUESTED_IP_ADDRESS) {            my_addr = dhcp_opt_get_host_data(option);            break;        }    }    if(my_addr == NULL)  { /* if empty, don't release. */        dhcp_opt_destroy_option_list(cache_options);        return STATE_FATAL_ERROR;    }    ciaddr = *my_addr;    dhcp_opt_destroy_option_list(cache_options);    options = client_build_release_option_list(dc);    build_dhcp_release(dc->rawnet, dc->xid, options, ciaddr,                       dhcp_client_get_server_ip_address(dc),                       dhcp_client_get_server_hw_address(dc));    if(rawnet_send_packet(dc->rawnet) < 0) {        ERROR_MESSAGE("could not send RELEASE.");        return STATE_FATAL_ERROR;    }    /* called from do_shutdown() so no real state returned.     * however if we do take the return value into consideration     * we should handle it as an error. */    return STATE_FATAL_ERROR;}/* perform system configuration. */int client_setup(dhcp_client_control_t *dc){    INFO_MESSAGE("entering SETUP stage");    return client_configure(dc);}/* do a shutdown. */int client_shutdown(dhcp_client_control_t *dc){    INFO_MESSAGE("shutting down.");    if(dc) { /* only do clean up if we can. */        /* send our a release only if we have a cache. */        if(!client_cache_is_empty(dc->cache))            client_release(dc);        /* unconfigure everything including our interface. */        client_unconfigure(dc);        /* since we're releasing the lease we should down the interface */        INFO_MESSAGE("bringing down interface.");        rawnet_down(dc->rawnet);        rawnet_interface_down(dc->rawnet);        /* delete the PID file. */        file_delete_pid(dc->interface);        /* delete our cache. */        client_cache_delete_cache(dc->cache);        client_cache_delete_tmp_cache(dc->cache);        dhcp_client_control_destroy(dc);    }    exit(0);}/* decline a lease. */int client_decline(dhcp_client_control_t *dc){    list_t *options, *decline_options;    dhcp_opt_t *option;    ip_addr_t *passed_ip = NULL;    INFO_MESSAGE("performing DHCP decline");    options = client_cache_load_options(dc->cache, 0);    list_rewind(options);    while((option = list_next(options)) != NULL) {        if(dhcp_opt_get_tag(option) == TAG_DHCP_REQUESTED_IP_ADDRESS) {            passed_ip = dhcp_opt_get_host_data(option);            break;        }    }    if(passed_ip == NULL) {        FATAL_MESSAGE("no address assigned and we're trying to decline. this is a bug, report me.");    }    decline_options = client_build_decline_option_list(dc, *passed_ip);    dhcp_opt_destroy_option_list(options);    build_dhcp_decline(dc->rawnet, dc->xid, dc->secs, decline_options);    if(rawnet_send_packet(dc->rawnet) < 0) {        ERROR_MESSAGE("could not send DECLINE.");        return STATE_FATAL_ERROR;    }    /* a lot like release, our return here shouldn't matter since     * we are most likely called within a state. if not then the     * state simply shouldn't be handled. */    return STATE_FATAL_ERROR;}

⌨️ 快捷键说明

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