Ticket #2531: dhcp.5.2.diff

File dhcp.5.2.diff, 10.0 KB (added by Adek336, 16 years ago)
  • src/servers/net/DHCPClient.cpp

     
    2121#include <sys/time.h>
    2222
    2323
     24#define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0)
     25
     26void trace_dhcp_state(dhcp_state state)
     27{
     28    char *state_name=NULL;
     29    switch(state)
     30    {
     31        case INIT: state_name = "INIT"; break;
     32        case REQUESTING: state_name = "REQUESTING"; break;
     33        case BOUND: state_name = "BOUND"; break;
     34        case RENEWAL: state_name="RENEWAL"; break;
     35        case REBINDING: state_name="REBINDING"; break;
     36        case ACKNOWLEDGED: state_name="ACKNOWLEDGED"; break;
     37        default: break;
     38    }
     39    if (state_name == NULL)
     40        ktrace_printf("DHCP: state 0x%x\n", (unsigned)state);
     41    else
     42        ktrace_printf("DHCP: state %s\n", state_name);
     43}
     44
    2445// See RFC 2131 for DHCP, see RFC 1533 for BOOTP/DHCP options
    2546
    2647#define DHCP_CLIENT_PORT    68
     
    336357    fRunner(NULL),
    337358    fLeaseTime(0)
    338359{
     360    LND;
    339361    fStartTime = system_time();
    340362    fTransactionID = (uint32)fStartTime;
    341363
    342364    fStatus = get_mac_address(device, fMAC);
    343     if (fStatus < B_OK)
     365    if (fStatus < B_OK) {
     366        LND;
    344367        return;
     368    }
    345369
    346370    memset(&fServer, 0, sizeof(struct sockaddr_in));
    347371    fServer.sin_family = AF_INET;
    348372    fServer.sin_len = sizeof(struct sockaddr_in);
    349373    fServer.sin_port = htons(DHCP_SERVER_PORT);
     374    LND;
    350375}
    351376
    352377
    353378DHCPClient::~DHCPClient()
    354379{
     380    LND;
    355381    if (fStatus != B_OK)
    356382        return;
    357383
     
    374400status_t
    375401DHCPClient::Initialize()
    376402{
     403    LND;
     404    trace_dhcp_state(INIT);
    377405    fStatus = _Negotiate(INIT);
    378406    printf("DHCP for %s, status: %s\n", fDevice.String(), strerror(fStatus));
    379407    return fStatus;
    380408}
    381409
    382 
    383410status_t
    384411DHCPClient::_Negotiate(dhcp_state state)
    385412{
     413    LND;
     414    ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
     415    trace_dhcp_state(state);
     416    if (state != INIT
     417        && state != REBINDING
     418        && state != RENEWAL)
     419        fprintf(stderr, "DHCP client: negotiating: unexpected state %d\n", state);
     420
    386421    int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
    387     if (socket < 0)
     422    if (socket < 0) {
     423        LND;
    388424        return errno;
     425    }
    389426
    390427    sockaddr_in local;
    391428    memset(&local, 0, sizeof(struct sockaddr_in));
     
    396433
    397434    if (bind(socket, (struct sockaddr *)&local, sizeof(local)) < 0) {
    398435        close(socket);
     436        LND;
    399437        return errno;
    400438    }
    401439
     
    410448    setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
    411449
    412450    if (state == INIT) {
     451        LND;
    413452        // The local interface does not have an address yet, bind the socket
    414453        // to the device directly.
    415454        int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
    416455        if (linkSocket >= 0) {
     456            LND;
    417457            // we need to know the index of the device to be able to bind to it
    418458            ifreq request;
    419459            prepare_request(request, fDevice.String());
    420460            if (ioctl(linkSocket, SIOCGIFINDEX, &request, sizeof(struct ifreq))
    421461                    == 0) {
     462                LND;
    422463                setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE,
    423464                    &request.ifr_index, sizeof(int));
    424465            }
     
    448489        state != RENEWAL ? broadcast : fServer);
    449490    if (status < B_OK) {
    450491        close(socket);
     492        LND;
    451493        return status;
    452494    }
    453495
    454496    // receive loop until we've got an offer and acknowledged it
    455497
     498    LND;
     499
    456500    while (state != ACKNOWLEDGED) {
     501        LND;
     502        trace_dhcp_state(state);
    457503        char buffer[2048];
    458504        ssize_t bytesReceived = recvfrom(socket, buffer, sizeof(buffer),
    459505            0, NULL, NULL);
    460506        if (bytesReceived < 0 && errno == B_TIMED_OUT) {
     507            LND;
    461508            // depending on the state, we'll just try again
    462509            if (!_TimeoutShift(socket, timeout, tries)) {
     510                LND;
    463511                close(socket);
    464512                return B_TIMED_OUT;
    465513            }
     
    467515            if (state == INIT)
    468516                status = _SendMessage(socket, discover, broadcast);
    469517            else {
     518                LND;
    470519                status = _SendMessage(socket, request, state != RENEWAL
    471520                    ? broadcast : fServer);
    472521            }
    473522
    474523            if (status < B_OK)
    475524                break;
     525            LND;
    476526        } else if (bytesReceived < B_OK)
    477527            break;
     528        LND;
    478529
    479530        dhcp_message *message = (dhcp_message *)buffer;
    480531        if (message->transaction_id != htonl(fTransactionID)
    481532            || !message->HasOptions()
    482533            || memcmp(message->mac_address, discover.mac_address,
    483534                discover.hardware_address_length)) {
     535            LND;
    484536            // this message is not for us
    485537            continue;
    486538        }
     
    488540        switch (message->Type()) {
    489541            case DHCP_NONE:
    490542            default:
     543                LND;
    491544                // ignore this message
    492545                break;
    493546
    494547            case DHCP_OFFER:
    495548            {
     549                LND;
    496550                // first offer wins
    497551                if (state != INIT)
    498552                    break;
     553                LND;
    499554
    500555                // collect interface options
    501556
     
    516571
    517572                _ResetTimeout(socket, timeout, tries);
    518573                state = REQUESTING;
     574                trace_dhcp_state(state);
    519575                _PrepareMessage(request, state);
    520576
    521577                status = _SendMessage(socket, request, broadcast);
     
    526582
    527583            case DHCP_ACK:
    528584            {
     585                LND;
     586                trace_dhcp_state(state);
    529587                if (state != REQUESTING && state != REBINDING
    530588                    && state != RENEWAL)
    531589                    continue;
     590                LND;
    532591
    533592                // TODO: we might want to configure the stuff, don't we?
    534593                BMessage address;
     
    548607            }
    549608
    550609            case DHCP_NACK:
     610            LND;
    551611                if (state != REQUESTING)
    552612                    continue;
     613                LND;
    553614
    554615                // try again (maybe we should prefer other servers if this
    555616                // happens more than once)
     
    559620                break;
    560621        }
    561622    }
     623    LND;
     624    trace_dhcp_state(state);
    562625
    563626    close(socket);
    564627
    565628    if (status == B_OK && fLeaseTime > 0) {
     629        LND;
    566630        // notify early enough when the lease is
    567631        if (fRenewalTime == 0)
    568632            fRenewalTime = fLeaseTime * 2/3;
    569633        if (fRebindingTime == 0)
    570634            fRebindingTime = fLeaseTime * 5/6;
    571635
     636        LND;
    572637        _RestartLease(fRenewalTime);
    573638
    574639        bigtime_t now = system_time();
     
    577642        fRebindingTime += now;
    578643            // make lease times absolute
    579644    } else {
     645        LND;
     646        ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    580647        fLeaseTime = previousLeaseTime;
    581648        bigtime_t now = system_time();
    582649        fRenewalTime = (fLeaseTime - now) * 2/3 + now;
    583650        fRebindingTime = (fLeaseTime - now) * 5/6 + now;
     651        ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    584652    }
     653    LND;
    585654
    586655    return status;
    587656}
     
    590659void
    591660DHCPClient::_RestartLease(bigtime_t leaseTime)
    592661{
     662    LND;
    593663    if (leaseTime == 0)
    594664        return;
     665    ktrace_printf("DHCP: _RestartLease: leaseTime %lld\n", leaseTime);
    595666
    596667    BMessage lease(kMsgLeaseTime);
    597     fRunner = new BMessageRunner(this, &lease, leaseTime, 1);
     668    fRunner = new BMessageRunner(this, &lease, leaseTime+1000, 1);
    598669}
    599670
    600671
     
    798869DHCPClient::_CurrentState() const
    799870{
    800871    bigtime_t now = system_time();
     872
     873    ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    801874   
    802875    if (now > fLeaseTime || fStatus < B_OK)
    803876        return INIT;
     
    819892            dhcp_state state = _CurrentState();
    820893
    821894            bigtime_t next;
     895            LND;
     896            trace_dhcp_state(state);
    822897            if (_Negotiate(state) == B_OK) {
    823898                switch (state) {
    824899                    case RENEWAL:
     
    841916                }
    842917            }
    843918
     919            LND;
    844920            _RestartLease(next - system_time());
    845921            break;
    846922        }
  • src/servers/net/NetServer.cpp

     
    3737#include <string.h>
    3838#include <unistd.h>
    3939
     40#define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0)
    4041
     42
    4143static const char *kSignature = "application/x-vnd.haiku-net_server";
    4244
    4345
     
    315317            if (socket < 0)
    316318                break;
    317319
     320            LND;
    318321            status_t status = _ConfigureInterface(socket, *message, true);
    319322
    320323            BMessage reply(B_REPLY);
     
    485488status_t
    486489NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage)
    487490{
     491    LND;
     492
    488493    const char *device;
    489494    if (interface.FindString("device", &device) != B_OK)
    490495        return B_BAD_VALUE;
     
    675680        }
    676681    }
    677682
     683    LND;
    678684    if (startAutoConfig) {
    679685        // start auto configuration
     686        LND;
    680687        AutoconfigLooper* looper = new AutoconfigLooper(this, device);
    681688        looper->Run();
    682689
     
    725732    address.AddBool("auto config", true);
    726733    interface.AddMessage("address", &address);
    727734
     735    LND;
     736
    728737    return _ConfigureInterface(socket, interface);
    729738}
    730739
     
    746755            continue;
    747756
    748757        if (S_ISBLK(stat.st_mode) || S_ISCHR(stat.st_mode)) {
     758            LND;
    749759            if (suggestedInterface != NULL
    750760                && suggestedInterface->RemoveName("device") == B_OK
    751761                && suggestedInterface->AddString("device", path.Path()) == B_OK
     
    782792            }
    783793        }
    784794
     795        LND;
    785796        _ConfigureInterface(socket, interface);
    786797    }
    787798}
     
    817828        address.AddString("address", "127.0.0.1");
    818829        interface.AddMessage("address", &address);
    819830
     831        LND;
    820832        _ConfigureInterface(socket, interface);
    821833    }
    822834
  • src/servers/net/AutoconfigLooper.cpp

     
    1818#include <sys/socket.h>
    1919#include <sys/sockio.h>
    2020
     21#define LND do { ktrace_printf("DHCP: %s: %s: %d\n", __FILE__, __func__, __LINE__); } while(0)
    2122
     23
    2224static const uint32 kMsgReadyToRun = 'rdyr';
    2325
    2426
     
    2729    fTarget(target),
    2830    fDevice(device)
    2931{
     32    LND;
    3033    BMessage ready(kMsgReadyToRun);
    3134    PostMessage(&ready);
    3235}
     
    4043void
    4144AutoconfigLooper::_ReadyToRun()
    4245{
     46    LND;
    4347    ifreq request;
    4448    if (!prepare_request(request, fDevice.String()))
    4549        return;
     50    LND;
    4651
    4752    // set IFF_CONFIGURING flag on interface
    4853
     
    5863    close(socket);
    5964
    6065    // start with DHCP
     66    LND;
    6167
    6268    DHCPClient* client = new DHCPClient(fTarget, fDevice.String());
    6369    AddHandler(client);
     
    7480    // TODO: have a look at zeroconf
    7581    // TODO: this could also be done add-on based
    7682
     83    LND;
    7784    BMessage interface(kMsgConfigureInterface);
    7885    interface.AddString("device", fDevice.String());
    7986    interface.AddBool("auto", true);