Changeset b417559 in mainline


Ignore:
Timestamp:
2013-09-24T21:00:52Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b0602a3
Parents:
66ec63a
Message:

Retransmit DHCP discover and request messages on timeout. Introduce DHCP link states.

Location:
uspace/srv/net
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/dhcp/dhcp.c

    r66ec63a rb417559  
    3737#include <adt/list.h>
    3838#include <bitops.h>
     39#include <fibril_synch.h>
    3940#include <inet/addr.h>
    4041#include <inet/dnsr.h>
     
    5253#include "transport.h"
    5354
     55#define DHCP_DISCOVER_TIMEOUT_VAL (5 * 1000 * 1000)
     56#define DHCP_REQUEST_TIMEOUT_VAL (1 * 1000 * 1000)
     57
    5458#define MAX_MSG_SIZE 1024
    5559static uint8_t msgbuf[MAX_MSG_SIZE];
    5660
     61/** List of registered links (of dhcp_link_t) */
    5762static list_t dhcp_links;
     63
     64static void dhcpsrv_discover_timeout(void *);
     65static void dhcpsrv_request_timeout(void *);
     66
     67typedef enum {
     68        ds_bound,
     69        ds_init,
     70        ds_init_reboot,
     71        ds_rebinding,
     72        ds_renewing,
     73        ds_requesting,
     74        ds_selecting
     75} dhcp_state_t;
    5876
    5977typedef struct {
     
    7189
    7290typedef struct {
     91        /** Link to dhcp_links list */
    7392        link_t links;
     93        /** Link service ID */
    7494        service_id_t link_id;
     95        /** Link info */
    7596        inet_link_info_t link_info;
     97        /** Transport */
    7698        dhcp_transport_t dt;
     99        /** Transport timeout */
     100        fibril_timer_t *timeout;
     101        /** Link state */
     102        dhcp_state_t state;
     103        /** Last received offer */
     104        dhcp_offer_t offer;
    77105} dhcp_link_t;
    78106
     
    366394}
    367395
     396void dhcpsrv_links_init(void)
     397{
     398        list_initialize(&dhcp_links);
     399}
     400
     401static dhcp_link_t *dhcpsrv_link_find(service_id_t link_id)
     402{
     403        list_foreach(dhcp_links, links, dhcp_link_t, dlink) {
     404                if (dlink->link_id == link_id)
     405                        return dlink;
     406        }
     407
     408        return NULL;
     409}
     410
    368411int dhcpsrv_link_add(service_id_t link_id)
    369412{
     
    372415
    373416        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id);
     417
     418        if (dhcpsrv_link_find(link_id) != NULL) {
     419                log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu already added",
     420                    link_id);
     421                return EEXIST;
     422        }
    374423
    375424        dlink = calloc(1, sizeof(dhcp_link_t));
     
    378427
    379428        dlink->link_id = link_id;
     429        dlink->timeout = fibril_timer_create();
     430        if (dlink->timeout == NULL) {
     431                rc = ENOMEM;
     432                goto error;
     433        }
    380434
    381435        /* Get link hardware address */
     
    396450        }
    397451
     452        dlink->state = ds_selecting;
     453
    398454        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
    399455        rc = dhcp_send_discover(dlink);
     
    403459        }
    404460
    405         if (0) list_append(&dlink->links, &dhcp_links);
     461        fibril_timer_set(dlink->timeout, DHCP_DISCOVER_TIMEOUT_VAL,
     462            dhcpsrv_discover_timeout, dlink);
     463
     464        list_append(&dlink->links, &dhcp_links);
    406465
    407466        return EOK;
    408467error:
     468        if (dlink != NULL && dlink->timeout != NULL)
     469                fibril_timer_destroy(dlink->timeout);
    409470        free(dlink);
    410471        return rc;
     
    416477}
    417478
     479static void dhcpsrv_recv_offer(dhcp_link_t *dlink, dhcp_offer_t *offer)
     480{
     481        int rc;
     482
     483        if (dlink->state != ds_selecting) {
     484                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received offer in state "
     485                    " %d, ignoring.", (int)dlink->state);
     486                return;
     487        }
     488
     489        fibril_timer_clear(dlink->timeout);
     490        dlink->offer = *offer;
     491        dlink->state = ds_requesting;
     492
     493        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPREQUEST");
     494        rc = dhcp_send_request(dlink, offer);
     495        if (rc != EOK) {
     496                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error sending request.");
     497                return;
     498        }
     499
     500        fibril_timer_set(dlink->timeout, DHCP_REQUEST_TIMEOUT_VAL,
     501            dhcpsrv_request_timeout, dlink);
     502}
     503
     504static void dhcpsrv_recv_ack(dhcp_link_t *dlink, dhcp_offer_t *offer)
     505{
     506        int rc;
     507
     508        if (dlink->state != ds_requesting) {
     509                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received ack in state "
     510                    " %d, ignoring.", (int)dlink->state);
     511                return;
     512        }
     513
     514        fibril_timer_clear(dlink->timeout);
     515        dlink->offer = *offer;
     516        dlink->state = ds_bound;
     517
     518        rc = dhcp_cfg_create(dlink->link_id, offer);
     519        if (rc != EOK) {
     520                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error creating configuration.");
     521                return;
     522        }
     523}
     524
    418525static void dhcpsrv_recv(void *arg, void *msg, size_t size)
    419526{
     
    430537        }
    431538
    432         if (offer.msg_type == msg_dhcpoffer) {
    433                 rc = dhcp_send_request(dlink, &offer);
    434                 if (rc != EOK) {
    435                         log_msg(LOG_DEFAULT, LVL_DEBUG, "Error sending request.");
    436                         return;
    437                 }
    438         }
    439 
    440         if (offer.msg_type == msg_dhcpack) {
    441                 rc = dhcp_cfg_create(dlink->link_id, &offer);
    442                 if (rc != EOK) {
    443                         log_msg(LOG_DEFAULT, LVL_DEBUG, "Error creating configuration.");
    444                         return;
    445                 }
    446         }
     539        switch (offer.msg_type) {
     540        case msg_dhcpoffer:
     541                dhcpsrv_recv_offer(dlink, &offer);
     542                break;
     543        case msg_dhcpack:
     544                dhcpsrv_recv_ack(dlink, &offer);
     545                break;
     546        default:
     547                log_msg(LOG_DEFAULT, LVL_DEBUG, "Received unexpected "
     548                    "message type. %d", (int)offer.msg_type);
     549                break;
     550        }
     551}
     552
     553static void dhcpsrv_discover_timeout(void *arg)
     554{
     555        dhcp_link_t *dlink = (dhcp_link_t *)arg;
     556        int rc;
     557
     558        assert(dlink->state == ds_selecting);
     559        log_msg(LOG_DEFAULT, LVL_NOTE, "dcpsrv_discover_timeout");
     560
     561        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
     562        rc = dhcp_send_discover(dlink);
     563        if (rc != EOK) {
     564                log_msg(LOG_DEFAULT, LVL_ERROR, "Error sending DHCPDISCOVER");
     565                return;
     566        }
     567
     568        fibril_timer_set(dlink->timeout, DHCP_DISCOVER_TIMEOUT_VAL,
     569            dhcpsrv_discover_timeout, dlink);
     570}
     571
     572static void dhcpsrv_request_timeout(void *arg)
     573{
     574        dhcp_link_t *dlink = (dhcp_link_t *)arg;
     575        int rc;
     576
     577        assert(dlink->state == ds_requesting);
     578        log_msg(LOG_DEFAULT, LVL_NOTE, "dcpsrv_request_timeout");
     579
     580        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPREQUEST");
     581        rc = dhcp_send_request(dlink, &dlink->offer);
     582        if (rc != EOK) {
     583                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error sending request.");
     584                return;
     585        }
     586
     587        fibril_timer_set(dlink->timeout, DHCP_REQUEST_TIMEOUT_VAL,
     588            dhcpsrv_request_timeout, dlink);
    447589}
    448590
  • uspace/srv/net/dhcp/dhcp.h

    r66ec63a rb417559  
    4040#include <ipc/loc.h>
    4141
     42extern void dhcpsrv_links_init(void);
    4243extern int dhcpsrv_link_add(service_id_t);
    4344extern int dhcpsrv_link_remove(service_id_t);
  • uspace/srv/net/dhcp/main.c

    r66ec63a rb417559  
    5656
    5757        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_init()");
     58
     59        dhcpsrv_links_init();
    5860
    5961        rc = inetcfg_init();
  • uspace/srv/net/inetsrv/inet_link.c

    r66ec63a rb417559  
    5656
    5757static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
     58static inet_link_t *inet_link_get_by_id_locked(sysarg_t);
    5859
    5960static iplink_ev_ops_t inet_iplink_ev_ops = {
     
    183184
    184185        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
     186
     187        fibril_mutex_lock(&inet_links_lock);
     188
     189        if (inet_link_get_by_id_locked(sid) != NULL) {
     190                fibril_mutex_unlock(&inet_links_lock);
     191                log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu already open",
     192                    sid);
     193                rc = EEXIST;
     194                goto error;
     195        }
     196
    185197        list_append(&ilink->link_list, &inet_links);
     198        fibril_mutex_unlock(&inet_links_lock);
    186199
    187200        inet_addrobj_t *addr = NULL;
     
    412425}
    413426
     427static inet_link_t *inet_link_get_by_id_locked(sysarg_t link_id)
     428{
     429        assert(fibril_mutex_is_locked(&inet_links_lock));
     430
     431        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     432                if (ilink->svc_id == link_id)
     433                        return ilink;
     434        }
     435
     436        return NULL;
     437}
     438
    414439inet_link_t *inet_link_get_by_id(sysarg_t link_id)
    415440{
     441        inet_link_t *ilink;
     442
    416443        fibril_mutex_lock(&inet_links_lock);
    417 
    418         list_foreach(inet_links, link_list, inet_link_t, ilink) {
    419                 if (ilink->svc_id == link_id) {
    420                         fibril_mutex_unlock(&inet_links_lock);
    421                         return ilink;
    422                 }
    423         }
    424 
     444        ilink = inet_link_get_by_id_locked(link_id);
    425445        fibril_mutex_unlock(&inet_links_lock);
    426         return NULL;
     446
     447        return ilink;
    427448}
    428449
Note: See TracChangeset for help on using the changeset viewer.