Ticket #7346: net_server.patch

File net_server.patch, 8.4 KB (added by phoudoin, 11 years ago)

Improved patch, which move the logic in DHCPClient, not in AutoconfigLooper.

  • DHCPClient.cpp

     
    422422    fConfiguration(kMsgConfigureInterface),
    423423    fResolverConfiguration(kMsgConfigureResolver),
    424424    fRunner(NULL),
     425    fAssignedAddress(0),
    425426    fServer(AF_INET, NULL, DHCP_SERVER_PORT),
    426427    fLeaseTime(0)
    427428{
     
    436437
    437438    memcpy(fMAC, link.LinkLevelAddress(), sizeof(fMAC));
    438439
     440    if ((interface.Flags() & IFF_AUTO_CONFIGURED) != 0) {
     441        // Check for interface previous auto-configured address, if any.
     442        BNetworkInterfaceAddress interfaceAddress;
     443        int index = interface.FindFirstAddress(AF_INET);
     444        if (index >= 0
     445            && interface.GetAddressAt(index, interfaceAddress) == B_OK) {
     446            BNetworkAddress address = interfaceAddress.Address();
     447            const sockaddr_in& addr = (sockaddr_in&)address.SockAddr();
     448            fAssignedAddress = addr.sin_addr.s_addr;
     449        }
     450    }
     451
    439452    openlog_thread("DHCP", 0, LOG_DAEMON);
    440453}
    441454
     
    466479status_t
    467480DHCPClient::Initialize()
    468481{
    469     fStatus = _Negotiate(INIT);
    470     syslog(LOG_DEBUG, "DHCP for %s, status: %s\n", Device(), strerror(fStatus));
     482    fStatus = _Negotiate(fAssignedAddress == 0 ? INIT : INIT_REBOOT);
     483    syslog(LOG_DEBUG, "%s: DHCP status = %s\n", Device(), strerror(fStatus));
    471484    return fStatus;
    472485}
    473486
     
    527540
    528541    // send discover/request message
    529542    _SendMessage(socket, state == INIT ? discover : request,
    530         state != RENEWAL ? broadcast : fServer);
     543        state != RENEWING ? broadcast : fServer);
    531544        // no need to check the status; in case of an error we'll just send
    532545        // the message again
    533546
    534547    // receive loop until we've got an offer and acknowledged it
    535548
    536     while (state != ACKNOWLEDGED) {
     549    while (state != BOUND) {
    537550        char buffer[2048];
    538551        struct sockaddr_in from;
    539552        socklen_t fromLength = sizeof(from);
     
    546559                return B_TIMED_OUT;
    547560            }
    548561
    549             if (state == INIT)
    550                 _SendMessage(socket, discover, broadcast);
    551             else {
    552                 _SendMessage(socket, request,
    553                     state != RENEWAL ? broadcast : fServer);
    554             }
     562            _SendMessage(socket, state == INIT ? discover : request,
     563                state != RENEWING ? broadcast : fServer);
    555564
    556565            continue;
    557566        } else if (bytesReceived < 0)
     
    566575            continue;
    567576        }
    568577
    569         syslog(LOG_DEBUG, "Received %s from %s for %s\n",
    570             dhcp_message::TypeToString(message->Type()),
    571                 _AddressToString(from.sin_addr.s_addr).String(), Device());
     578        // advance from startup state
     579        if (state == INIT)
     580            state = SELECTING;
     581        else if (state == INIT_REBOOT)
     582            state = REBOOTING;
    572583
     584        syslog(LOG_DEBUG, "%s: Received %s from %s\n",
     585            Device(), dhcp_message::TypeToString(message->Type()),
     586            _AddressToString(from.sin_addr.s_addr).String());
     587
    573588        switch (message->Type()) {
    574589            case DHCP_NONE:
    575590            default:
     
    579594            case DHCP_OFFER:
    580595            {
    581596                // first offer wins
    582                 if (state != INIT)
     597                if (state != SELECTING)
    583598                    break;
    584599
    585600                // collect interface options
     
    590605
    591606                fConfiguration.MakeEmpty();
    592607                fConfiguration.AddString("device", Device());
    593                 fConfiguration.AddBool("auto", true);
     608                fConfiguration.AddBool("auto_configured", true);
    594609
    595610                BMessage address;
    596611                address.AddString("family", "inet");
     
    614629
    615630            case DHCP_ACK:
    616631            {
    617                 if (state != REQUESTING && state != REBINDING
    618                     && state != RENEWAL)
     632                if (state != REQUESTING
     633                    && state != REBOOTING
     634                    && state != REBINDING
     635                    && state != RENEWING)
    619636                    continue;
    620637
    621638                // TODO: we might want to configure the stuff, don't we?
     
    626643                    // way
    627644
    628645                // our address request has been acknowledged
    629                 state = ACKNOWLEDGED;
     646                state = BOUND;
    630647
    631648                // configure interface
    632649                BMessage reply;
     
    644661            }
    645662
    646663            case DHCP_NACK:
    647                 if (state != REQUESTING)
     664                if (state != REQUESTING
     665                    && state != REBOOTING
     666                    && state != REBINDING
     667                    && state != RENEWING)
    648668                    continue;
    649669
     670                if (state == REBOOTING) {
     671                    // server reject our request on previous assigned address
     672                    // back to square one...
     673                    fAssignedAddress = 0;
     674                }
     675
    650676                // try again (maybe we should prefer other servers if this
    651677                // happens more than once)
    652678                status = _SendMessage(socket, discover, broadcast);
     
    819845                    (uint32)server.sin_addr.s_addr);
    820846            }
    821847
    822             if (state == INIT || state == REQUESTING) {
     848            if (state == INIT || state == INIT_REBOOT
     849                || state == REQUESTING) {
    823850                next = message.PutOption(next, OPTION_REQUEST_IP_ADDRESS,
    824851                    (uint32)fAssignedAddress);
    825852            } else
     
    866893        if (++tries > 2)
    867894            return false;
    868895    }
    869     syslog(LOG_DEBUG, "Timeout shift for %s: %lu secs (try %lu)\n",
     896    syslog(LOG_DEBUG, "%s: Timeout shift: %lu secs (try %lu)\n",
    870897        Device(), timeout, tries);
    871898
    872899    struct timeval value;
     
    898925DHCPClient::_SendMessage(int socket, dhcp_message& message,
    899926    const BNetworkAddress& address) const
    900927{
    901     syslog(LOG_DEBUG, "Send %s to %s on %s\n",
    902         dhcp_message::TypeToString(message.Type()),
    903             address.ToString().String(), Device());
     928    message_type type = message.Type();
     929    BString text;
     930    text << dhcp_message::TypeToString(type);
     931 
     932    const uint8* requestAddress = message.FindOption(OPTION_REQUEST_IP_ADDRESS);
     933    if (type == DHCP_REQUEST && requestAddress != NULL)
     934        text << " for " << _AddressToString(requestAddress).String();
     935   
     936    syslog(LOG_DEBUG, "%s: Send %s to %s\n", Device(), text.String(),
     937        address.ToString().String());
    904938
    905939    ssize_t bytesSent = sendto(socket, &message, message.Size(),
    906940        address.IsBroadcast() ? MSG_BCAST : 0, address, address.Length());
     
    921955    if (now >= fRebindingTime)
    922956        return REBINDING;
    923957    if (now >= fRenewalTime)
    924         return RENEWAL;
     958        return RENEWING;
    925959
    926960    return BOUND;
    927961}
     
    938972            bigtime_t next;
    939973            if (_Negotiate(state) == B_OK) {
    940974                switch (state) {
    941                     case RENEWAL:
     975                    case RENEWING:
    942976                        next = fRebindingTime;
    943977                        break;
    944978                    case REBINDING:
     
    948982                }
    949983            } else {
    950984                switch (state) {
    951                     case RENEWAL:
     985                    case RENEWING:
    952986                        next = (fLeaseTime - fRebindingTime) / 4 + system_time();
    953987                        break;
    954988                    case REBINDING:
  • NetServer.cpp

     
    443443        flags = IFF_UP;
    444444
    445445    bool autoConfigured;
    446     if (message.FindBool("auto", &autoConfigured) == B_OK && autoConfigured)
     446    if (message.FindBool("auto_configured", &autoConfigured) == B_OK && autoConfigured)
    447447        flags |= IFF_AUTO_CONFIGURED;
    448448
    449449    int32 mtu;
     
    532532            if (addressMessage.FindString("broadcast", &string) == B_OK)
    533533                parse_address(family, string, broadcast);
    534534        }
    535 
     535       
    536536        if (autoConfig) {
    537537            _QuitLooperForDevice(name);
    538538            startAutoConfig = true;
  • AutoconfigLooper.cpp

     
    5858void
    5959AutoconfigLooper::_Configure()
    6060{
     61    // start with DHCP
     62   
     63    if (fCurrentClient == NULL) {
     64        fCurrentClient = new DHCPClient(fTarget, fDevice.String());
     65        AddHandler(fCurrentClient);
     66    }
     67   
    6168    // set IFF_CONFIGURING flag on interface
    6269
    6370    BNetworkInterface interface(fDevice.String());
    6471    int32 flags = interface.Flags() & ~IFF_AUTO_CONFIGURED;
    6572    interface.SetFlags(flags | IFF_CONFIGURING);
    6673
    67     // remove current handler
    68 
    69     _RemoveClient();
    70 
    71     // start with DHCP
    72 
    73     fCurrentClient = new DHCPClient(fTarget, fDevice.String());
    74     AddHandler(fCurrentClient);
    75 
    7674    if (fCurrentClient->Initialize() == B_OK)
    7775        return;
    7876
     
    9189
    9290    BMessage message(kMsgConfigureInterface);
    9391    message.AddString("device", fDevice.String());
    94     message.AddBool("auto", true);
     92    message.AddBool("auto_configured", true);
    9593
    9694    BNetworkAddress link;
    9795    uint8 last = 56;
  • DHCPClient.h

     
    2222
    2323enum dhcp_state {
    2424    INIT,
     25    SELECTING,
     26    INIT_REBOOT,
     27    REBOOTING,
    2528    REQUESTING,
    2629    BOUND,
    27     RENEWAL,
     30    RENEWING,
    2831    REBINDING,
    29     ACKNOWLEDGED,
    3032};
    3133
    3234
     
    5557            bool                _TimeoutShift(int socket, time_t& timeout,
    5658                                    uint32& tries);
    5759            void                _RestartLease(bigtime_t lease);
    58            
     60
    5961    static  BString             _AddressToString(const uint8* data);
    60     static  BString             _AddressToString(in_addr_t address);
     62    static  BString             _AddressToString(in_addr_t address);
    6163
    6264private:
    6365            BMessage            fConfiguration;