Ticket #2531: dhcp.5.diff

File dhcp.5.diff, 9.8 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);
    386416    int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
    387     if (socket < 0)
     417    if (socket < 0) {
     418        LND;
    388419        return errno;
     420    }
    389421
    390422    sockaddr_in local;
    391423    memset(&local, 0, sizeof(struct sockaddr_in));
     
    396428
    397429    if (bind(socket, (struct sockaddr *)&local, sizeof(local)) < 0) {
    398430        close(socket);
     431        LND;
    399432        return errno;
    400433    }
    401434
     
    410443    setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
    411444
    412445    if (state == INIT) {
     446        LND;
    413447        // The local interface does not have an address yet, bind the socket
    414448        // to the device directly.
    415449        int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0);
    416450        if (linkSocket >= 0) {
     451            LND;
    417452            // we need to know the index of the device to be able to bind to it
    418453            ifreq request;
    419454            prepare_request(request, fDevice.String());
    420455            if (ioctl(linkSocket, SIOCGIFINDEX, &request, sizeof(struct ifreq))
    421456                    == 0) {
     457                LND;
    422458                setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE,
    423459                    &request.ifr_index, sizeof(int));
    424460            }
     
    448484        state != RENEWAL ? broadcast : fServer);
    449485    if (status < B_OK) {
    450486        close(socket);
     487        LND;
    451488        return status;
    452489    }
    453490
    454491    // receive loop until we've got an offer and acknowledged it
    455492
     493    LND;
     494
    456495    while (state != ACKNOWLEDGED) {
     496        LND;
     497        trace_dhcp_state(state);
    457498        char buffer[2048];
    458499        ssize_t bytesReceived = recvfrom(socket, buffer, sizeof(buffer),
    459500            0, NULL, NULL);
    460501        if (bytesReceived < 0 && errno == B_TIMED_OUT) {
     502            LND;
    461503            // depending on the state, we'll just try again
    462504            if (!_TimeoutShift(socket, timeout, tries)) {
     505                LND;
    463506                close(socket);
    464507                return B_TIMED_OUT;
    465508            }
     
    467510            if (state == INIT)
    468511                status = _SendMessage(socket, discover, broadcast);
    469512            else {
     513                LND;
    470514                status = _SendMessage(socket, request, state != RENEWAL
    471515                    ? broadcast : fServer);
    472516            }
    473517
    474518            if (status < B_OK)
    475519                break;
     520            LND;
    476521        } else if (bytesReceived < B_OK)
    477522            break;
     523        LND;
    478524
    479525        dhcp_message *message = (dhcp_message *)buffer;
    480526        if (message->transaction_id != htonl(fTransactionID)
    481527            || !message->HasOptions()
    482528            || memcmp(message->mac_address, discover.mac_address,
    483529                discover.hardware_address_length)) {
     530            LND;
    484531            // this message is not for us
    485532            continue;
    486533        }
     
    488535        switch (message->Type()) {
    489536            case DHCP_NONE:
    490537            default:
     538                LND;
    491539                // ignore this message
    492540                break;
    493541
    494542            case DHCP_OFFER:
    495543            {
     544                LND;
    496545                // first offer wins
    497546                if (state != INIT)
    498547                    break;
     548                LND;
    499549
    500550                // collect interface options
    501551
     
    516566
    517567                _ResetTimeout(socket, timeout, tries);
    518568                state = REQUESTING;
     569                trace_dhcp_state(state);
    519570                _PrepareMessage(request, state);
    520571
    521572                status = _SendMessage(socket, request, broadcast);
     
    526577
    527578            case DHCP_ACK:
    528579            {
     580                LND;
     581                trace_dhcp_state(state);
    529582                if (state != REQUESTING && state != REBINDING
    530583                    && state != RENEWAL)
    531584                    continue;
     585                LND;
    532586
    533587                // TODO: we might want to configure the stuff, don't we?
    534588                BMessage address;
     
    548602            }
    549603
    550604            case DHCP_NACK:
     605            LND;
    551606                if (state != REQUESTING)
    552607                    continue;
     608                LND;
    553609
    554610                // try again (maybe we should prefer other servers if this
    555611                // happens more than once)
     
    559615                break;
    560616        }
    561617    }
     618    LND;
     619    trace_dhcp_state(state);
    562620
    563621    close(socket);
    564622
    565623    if (status == B_OK && fLeaseTime > 0) {
     624        LND;
    566625        // notify early enough when the lease is
    567626        if (fRenewalTime == 0)
    568627            fRenewalTime = fLeaseTime * 2/3;
    569628        if (fRebindingTime == 0)
    570629            fRebindingTime = fLeaseTime * 5/6;
    571630
     631        LND;
    572632        _RestartLease(fRenewalTime);
    573633
    574634        bigtime_t now = system_time();
     
    577637        fRebindingTime += now;
    578638            // make lease times absolute
    579639    } else {
     640        LND;
     641        ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    580642        fLeaseTime = previousLeaseTime;
    581643        bigtime_t now = system_time();
    582644        fRenewalTime = (fLeaseTime - now) * 2/3 + now;
    583645        fRebindingTime = (fLeaseTime - now) * 5/6 + now;
     646        ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    584647    }
     648    LND;
    585649
    586650    return status;
    587651}
     
    590654void
    591655DHCPClient::_RestartLease(bigtime_t leaseTime)
    592656{
     657    LND;
    593658    if (leaseTime == 0)
    594659        return;
     660    ktrace_printf("DHCP: _RestartLease: leaseTime %lld\n", leaseTime);
    595661
    596662    BMessage lease(kMsgLeaseTime);
    597     fRunner = new BMessageRunner(this, &lease, leaseTime, 1);
     663    fRunner = new BMessageRunner(this, &lease, leaseTime+1000, 1);
    598664}
    599665
    600666
     
    798864DHCPClient::_CurrentState() const
    799865{
    800866    bigtime_t now = system_time();
     867
     868    ktrace_printf("DHCP: %d: now %lld, fLeaseTime %lld, fRebindingTime %lld, fRenewalTime %lld\n",__LINE__, system_time(), fLeaseTime, fRebindingTime, fRenewalTime);
    801869   
    802870    if (now > fLeaseTime || fStatus < B_OK)
    803871        return INIT;
     
    819887            dhcp_state state = _CurrentState();
    820888
    821889            bigtime_t next;
     890            LND;
     891            trace_dhcp_state(state);
    822892            if (_Negotiate(state) == B_OK) {
    823893                switch (state) {
    824894                    case RENEWAL:
     
    841911                }
    842912            }
    843913
     914            LND;
    844915            _RestartLease(next - system_time());
    845916            break;
    846917        }
  • 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);