[haiku-commits] haiku: hrev51039 - src/servers/net

  • From: fredrik.holmqvist@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 25 Mar 2017 13:42:26 +0100 (CET)

hrev51039 adds 1 changeset to branch 'master'
old head: be9a70562e3c6552efb0caa53bd26965e7e1bed7
new head: 3bbff30d9e5aa58c6f128300c2372db42c840191
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=3bbff30d9e5a+%5Ebe9a70562e3c

----------------------------------------------------------------------------

3bbff30d9e5a: DHCP initial timeout 0.25s from 4s
  
  Connecting to wifi is very slow, there are several issues.
  Easiest to find and fis is that on my wifi DHCP always took
  4s, as first request fails. Still investigating why..
  Reducing timeout to 0.25s makes DHCP process fast.
  
  Moved timout handling into its own struct, and changed state
  timeout from max(remaing, 60s) to min(remaining, MAX_TIMEOUT)
  Not sure about that change, but why would you want a max value
  that is at least 60s?

                         [ Fredrik Holmqvist <fredrik.holmqvist@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev51039
Commit:      3bbff30d9e5aa58c6f128300c2372db42c840191
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3bbff30d9e5a
Author:      Fredrik Holmqvist <fredrik.holmqvist@xxxxxxxxx>
Date:        Sat Mar 25 12:33:40 2017 UTC

----------------------------------------------------------------------------

2 files changed, 68 insertions(+), 59 deletions(-)
src/servers/net/DHCPClient.cpp | 122 ++++++++++++++++++++-----------------
src/servers/net/DHCPClient.h   |   5 +-

----------------------------------------------------------------------------

diff --git a/src/servers/net/DHCPClient.cpp b/src/servers/net/DHCPClient.cpp
index d5ffd0e..c3815fb 100644
--- a/src/servers/net/DHCPClient.cpp
+++ b/src/servers/net/DHCPClient.cpp
@@ -39,8 +39,10 @@
 #define DHCP_CLIENT_PORT       68
 #define DHCP_SERVER_PORT       67
 
-#define DEFAULT_TIMEOUT                4       // secs
-#define MAX_TIMEOUT                    64      // secs
+#define DEFAULT_TIMEOUT                0.25    // secs
+#define MAX_TIMEOUT                    64              // secs
+
+#define AS_USECS(t) (1000000 * t)
 
 #define MAX_RETRIES                    5
 
@@ -152,6 +154,22 @@ struct dhcp_message {
        static const char* TypeToString(message_type type);
 } _PACKED;
 
+struct socket_timeout {
+       socket_timeout(int socket)
+               :
+               timeout((time_t)AS_USECS(DEFAULT_TIMEOUT)),
+               tries(0)
+       {
+               UpdateSocket(socket);
+       }
+
+       time_t timeout; // in micro secs
+       uint8 tries;
+
+       bool Shift(int socket, bigtime_t stateMaxTime, const char* device);
+       void UpdateSocket(int socket) const;
+};
+
 #define DHCP_FLAG_BROADCAST            0x8000
 
 #define ARP_HARDWARE_TYPE_ETHER        1
@@ -417,6 +435,39 @@ dhcp_message::TypeToString(message_type type)
 }
 
 
+void
+socket_timeout::UpdateSocket(int socket) const
+{
+       struct timeval value;
+       value.tv_sec = timeout / 1000000;
+       value.tv_usec = timeout % 1000000;
+       setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
+}
+
+
+bool
+socket_timeout::Shift(int socket, bigtime_t stateMaxTime, const char* device)
+{
+       tries++;
+       timeout += timeout;
+       if (timeout > AS_USECS(MAX_TIMEOUT))
+               timeout = AS_USECS(MAX_TIMEOUT);
+
+       if (tries > MAX_RETRIES) {
+               if (stateMaxTime == -1)
+                       return false;
+               bigtime_t remaining = (stateMaxTime - system_time()) / 2 + 1;
+               timeout = std::min(remaining, (bigtime_t)AS_USECS(MAX_TIMEOUT));
+       }
+
+       syslog(LOG_DEBUG, "%s: Timeout shift: %lu secs (try %lu)\n",
+               device, timeout, tries);
+
+       UpdateSocket(socket);
+       return true;
+}
+
+
 //     #pragma mark -
 
 
@@ -652,9 +703,7 @@ DHCPClient::_StateTransition(int socket, dhcp_state& state)
        BNetworkAddress broadcast;
        broadcast.SetToBroadcast(AF_INET, DHCP_SERVER_PORT);
 
-       time_t timeout;
-       uint32 tries;
-       _ResetTimeout(socket, state, timeout, tries);
+       socket_timeout timeout(socket);
 
        dhcp_message discover(DHCP_DISCOVER);
        _PrepareMessage(discover, state);
@@ -679,12 +728,11 @@ DHCPClient::_StateTransition(int socket, dhcp_state& 
state)
                char buffer[2048];
                struct sockaddr_in from;
                socklen_t fromLength = sizeof(from);
-
                ssize_t bytesReceived = recvfrom(socket, buffer, sizeof(buffer),
                        0, (struct sockaddr*)&from, &fromLength);
                if (bytesReceived < 0 && errno == B_TIMED_OUT) {
                        // depending on the state, we'll just try again
-                       if (!_TimeoutShift(socket, state, timeout, tries))
+                       if (!_TimeoutShift(socket, state, timeout))
                                return B_TIMED_OUT;
                        skipRequest = false;
                        continue;
@@ -893,60 +941,22 @@ DHCPClient::_PrepareMessage(dhcp_message& message, 
dhcp_state state)
 }
 
 
-void
-DHCPClient::_ResetTimeout(int socket, dhcp_state& state, time_t& timeout,
-       uint32& tries)
-{
-       timeout = DEFAULT_TIMEOUT;
-       tries = 0;
-
-       struct timeval value;
-       value.tv_sec = timeout;
-       value.tv_usec = rand() % 1000000;
-       setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
-}
-
-
 bool
-DHCPClient::_TimeoutShift(int socket, dhcp_state& state, time_t& timeout,
-       uint32& tries)
+DHCPClient::_TimeoutShift(int socket, dhcp_state& state,
+       socket_timeout& timeout)
 {
-       if (state == RENEWING && system_time() > fRebindingTime) {
-               state = REBINDING;
-               return false;
-       }
-
-       if (state == REBINDING && system_time() > fLeaseTime) {
-               state = INIT;
+       bigtime_t stateMaxTime = -1;
+       if (state == RENEWING)
+               stateMaxTime = fRebindingTime;
+       else if (state == REBINDING)
+               stateMaxTime = fLeaseTime;
+
+       if (system_time() > stateMaxTime) {
+               state = state == REBINDING ? INIT : REBINDING;
                return false;
        }
 
-       tries++;
-       timeout += timeout;
-       if (timeout > MAX_TIMEOUT)
-               timeout = MAX_TIMEOUT;
-
-       if (tries > MAX_RETRIES) {
-               bigtime_t remaining = 0;
-               if (state == RENEWING)
-                       remaining = (fRebindingTime - system_time()) / 2 + 1;
-               else if (state == REBINDING)
-                       remaining = (fLeaseTime - system_time()) / 2 + 1;
-               else
-                       return false;
-
-               timeout = std::max(remaining / 1000000, bigtime_t(60));
-       }
-
-       syslog(LOG_DEBUG, "%s: Timeout shift: %lu secs (try %lu)\n",
-               Device(), timeout, tries);
-
-       struct timeval value;
-       value.tv_sec = timeout;
-       value.tv_usec = rand() % 1000000;
-       setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
-
-       return true;
+       return timeout.Shift(socket, stateMaxTime, Device());
 }
 
 
diff --git a/src/servers/net/DHCPClient.h b/src/servers/net/DHCPClient.h
index b0a02d4..63b3bf0 100644
--- a/src/servers/net/DHCPClient.h
+++ b/src/servers/net/DHCPClient.h
@@ -18,6 +18,7 @@
 
 class BMessageRunner;
 class dhcp_message;
+class socket_timeout;
 
 
 enum dhcp_state {
@@ -55,10 +56,8 @@ private:
                        status_t                        _SendMessage(int 
socket, dhcp_message& message,
                                                                        const 
BNetworkAddress& address) const;
                        dhcp_state                      _CurrentState() const;
-                       void                            _ResetTimeout(int 
socket, dhcp_state& state,
-                                                                       time_t& 
timeout, uint32& tries);
                        bool                            _TimeoutShift(int 
socket, dhcp_state& state,
-                                                                       time_t& 
timeout, uint32& tries);
+                                                                       
socket_timeout& timeout);
                        void                            _RestartLease(bigtime_t 
lease);
 
        static  BString                         _AddressToString(const uint8* 
data);


Other related posts: