Ticket #13385: dhcp.patch

File dhcp.patch, 5.1 KB (added by tqh, 8 years ago)

Updated with header

  • src/servers/net/DHCPClient.cpp

    diff --git a/src/servers/net/DHCPClient.cpp b/src/servers/net/DHCPClient.cpp
    index d5ffd0e..9d88257 100644
    a b  
    3939#define DHCP_CLIENT_PORT    68
    4040#define DHCP_SERVER_PORT    67
    4141
    42 #define DEFAULT_TIMEOUT     4   // secs
    43 #define MAX_TIMEOUT         64  // secs
     42#define DEFAULT_TIMEOUT     0.25    // secs
     43#define MAX_TIMEOUT         64      // secs
     44
     45#define AS_USECS(t) (1000000 * t)
    4446
    4547#define MAX_RETRIES         5
    4648
    struct dhcp_message {  
    152154    static const char* TypeToString(message_type type);
    153155} _PACKED;
    154156
     157struct socket_timeout {
     158    socket_timeout(int socket)
     159        :
     160        timeout(AS_USECS(DEFAULT_TIMEOUT)),
     161        tries(0)
     162    {
     163        UpdateSocket(socket);
     164    }
     165
     166    time_t timeout; // in micro secs
     167    int tries;
     168
     169    bool Shift(int socket, bigtime_t stateMaxTime, const char* device);
     170    void UpdateSocket(int socket) const;
     171};
     172
    155173#define DHCP_FLAG_BROADCAST     0x8000
    156174
    157175#define ARP_HARDWARE_TYPE_ETHER 1
    dhcp_message::TypeToString(message_type type)  
    417435}
    418436
    419437
     438void
     439socket_timeout::UpdateSocket(int socket) const
     440{
     441    struct timeval value;
     442    value.tv_sec = timeout / 1000000;
     443    value.tv_usec = timeout % 1000000;
     444    setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
     445}
     446
     447
     448bool
     449socket_timeout::Shift(int socket, bigtime_t stateMaxTime, const char* device)
     450{
     451    tries++;
     452    timeout += timeout;
     453    if (timeout > AS_USECS(MAX_TIMEOUT))
     454        timeout = AS_USECS(MAX_TIMEOUT);
     455
     456    if (tries > MAX_RETRIES) {
     457        if (stateMaxTime == -1)
     458            return false;
     459        bigtime_t remaining = (stateMaxTime - system_time()) / 2 + 1;
     460        timeout = std::min(remaining, (bigtime_t)AS_USECS(MAX_TIMEOUT));
     461    }
     462
     463    syslog(LOG_DEBUG, "%s: Timeout shift: %lu secs (try %lu)\n",
     464        device, timeout, tries);
     465
     466    UpdateSocket(socket);
     467    return true;
     468}
     469
     470
    420471//  #pragma mark -
    421472
    422473
    DHCPClient::_StateTransition(int socket, dhcp_state& state)  
    652703    BNetworkAddress broadcast;
    653704    broadcast.SetToBroadcast(AF_INET, DHCP_SERVER_PORT);
    654705
    655     time_t timeout;
    656     uint32 tries;
    657     _ResetTimeout(socket, state, timeout, tries);
     706    socket_timeout timeout(socket);
    658707
    659708    dhcp_message discover(DHCP_DISCOVER);
    660709    _PrepareMessage(discover, state);
    DHCPClient::_StateTransition(int socket, dhcp_state& state)  
    684733            0, (struct sockaddr*)&from, &fromLength);
    685734        if (bytesReceived < 0 && errno == B_TIMED_OUT) {
    686735            // depending on the state, we'll just try again
    687             if (!_TimeoutShift(socket, state, timeout, tries))
     736            if (!_TimeoutShift(socket, state, timeout))
    688737                return B_TIMED_OUT;
    689738            skipRequest = false;
    690739            continue;
    DHCPClient::_PrepareMessage(dhcp_message& message, dhcp_state state)  
    893942}
    894943
    895944
    896 void
    897 DHCPClient::_ResetTimeout(int socket, dhcp_state& state, time_t& timeout,
    898     uint32& tries)
    899 {
    900     timeout = DEFAULT_TIMEOUT;
    901     tries = 0;
    902 
    903     struct timeval value;
    904     value.tv_sec = timeout;
    905     value.tv_usec = rand() % 1000000;
    906     setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
    907 }
    908 
    909 
    910945bool
    911 DHCPClient::_TimeoutShift(int socket, dhcp_state& state, time_t& timeout,
    912     uint32& tries)
     946DHCPClient::_TimeoutShift(int socket, dhcp_state& state,
     947    socket_timeout& timeout)
    913948{
    914     if (state == RENEWING && system_time() > fRebindingTime) {
    915         state = REBINDING;
     949    bigtime_t stateMaxTime = -1;
     950    if (state == RENEWING)
     951        stateMaxTime = fRebindingTime;
     952    else if (state == REBINDING)
     953        stateMaxTime = fLeaseTime;
     954
     955    if (system_time() > stateMaxTime) {
     956        state = state == REBINDING ? INIT : REBINDING;
    916957        return false;
    917958    }
    918959
    919     if (state == REBINDING && system_time() > fLeaseTime) {
    920         state = INIT;
    921         return false;
    922     }
    923 
    924     tries++;
    925     timeout += timeout;
    926     if (timeout > MAX_TIMEOUT)
    927         timeout = MAX_TIMEOUT;
    928 
    929     if (tries > MAX_RETRIES) {
    930         bigtime_t remaining = 0;
    931         if (state == RENEWING)
    932             remaining = (fRebindingTime - system_time()) / 2 + 1;
    933         else if (state == REBINDING)
    934             remaining = (fLeaseTime - system_time()) / 2 + 1;
    935         else
    936             return false;
    937 
    938         timeout = std::max(remaining / 1000000, bigtime_t(60));
    939     }
    940 
    941     syslog(LOG_DEBUG, "%s: Timeout shift: %lu secs (try %lu)\n",
    942         Device(), timeout, tries);
    943 
    944     struct timeval value;
    945     value.tv_sec = timeout;
    946     value.tv_usec = rand() % 1000000;
    947     setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
    948 
    949     return true;
     960    return timeout.Shift(socket, stateMaxTime, Device());
    950961}
    951962
    952963
  • src/servers/net/DHCPClient.h

    diff --git a/src/servers/net/DHCPClient.h b/src/servers/net/DHCPClient.h
    index b0a02d4..63b3bf0 100644
    a b  
    1818
    1919class BMessageRunner;
    2020class dhcp_message;
     21class socket_timeout;
    2122
    2223
    2324enum dhcp_state {
    private:  
    5556            status_t            _SendMessage(int socket, dhcp_message& message,
    5657                                    const BNetworkAddress& address) const;
    5758            dhcp_state          _CurrentState() const;
    58             void                _ResetTimeout(int socket, dhcp_state& state,
    59                                     time_t& timeout, uint32& tries);
    6059            bool                _TimeoutShift(int socket, dhcp_state& state,
    61                                     time_t& timeout, uint32& tries);
     60                                    socket_timeout& timeout);
    6261            void                _RestartLease(bigtime_t lease);
    6362
    6463    static  BString             _AddressToString(const uint8* data);