On Mon, 8 Apr 2002, Cajus Pollmeier wrote: >Date: Mon, 8 Apr 2002 08:28:40 +0200 >From: Cajus Pollmeier <[EMAIL PROTECTED]> >To: [EMAIL PROTECTED] >Cc: [EMAIL PROTECTED] >Content-Type: text/plain; > charset="iso-8859-15" >List-Id: General X Discussion <xpert.XFree86.Org> >Subject: Fixed: Xdm dying at Feb 13th EST 9:58 > >Hi Xperts. > >Some days ago I posted a phenomen about "too many keepalive retransmissions, >declaring session dead" >problems when using X via xdmcp. I investigated some time to solve the problem. >That's what what I got: > >Using ethereal to view what happens, I saw that i.e. at 4 April, 08:00:47 the client >is sending many keepalive >packets in a very short distance of time, before claiming that the session is dead. > >Looking at the sources (xdmcp.c), I found that closing sessions happens every 48-49 >days, depending on the size of >the variable "keepaliveDormancy". Using CARD32 as variable type for "timeOutTime" >while depending on >the system time (see GetTimeInMillis()) will overflow each 2^32 ms (about 49 days). > >The function "XdmcpWakeupHandler" in xdmcp.c is not working in a correct way when the >overflow happens. >As a workaround I added an if clause to wait for GetTimeInMillis to overflow, too.
Chris Blizzard and Keith Packard recently worked on this problem and created a fix, which is now in XFree86 head CVS I believe. I've attached Keith's patch which applies to older releases as well. -- Mike A. Harris Shipping/mailing address: OS Systems Engineer 190 Pittsburgh Ave., Sault Ste. Marie, XFree86 maintainer Ontario, Canada, P6C 5B3 Red Hat Inc. http://www.redhat.com ftp://people.redhat.com/mharris
Index: xdmcp.c =================================================================== RCS file: /home/x-cvs/xc/programs/Xserver/os/xdmcp.c,v retrieving revision 3.20 diff -u -r3.20 xdmcp.c --- xc/programs/Xserver/os/xdmcp.c 19 Nov 2001 20:44:18 -0000 3.20 +++ xc/programs/Xserver/os/xdmcp.c 10 Mar 2002 22:52:46 -0000 @@ -660,34 +660,17 @@ pointer pReadmask) { fd_set *LastSelectMask = (fd_set*)pReadmask; - CARD32 millisToGo, wtMillis; - static struct timeval waittime; + CARD32 millisToGo; if (state == XDM_OFF) return; FD_SET(xdmcpSocket, LastSelectMask); if (timeOutTime == 0) return; - millisToGo = GetTimeInMillis(); - if (millisToGo < timeOutTime) - millisToGo = timeOutTime - millisToGo; - else + millisToGo = timeOutTime - GetTimeInMillis(); + if ((int) millisToGo < 0) millisToGo = 0; - if (*wt == NULL) - { - waittime.tv_sec = (millisToGo) / 1000; - waittime.tv_usec = 1000 * (millisToGo % 1000); - *wt = &waittime; - } - else - { - wtMillis = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000; - if (millisToGo < wtMillis) - { - (*wt)->tv_sec = (millisToGo) / 1000; - (*wt)->tv_usec = 1000 * (millisToGo % 1000); - } - } + AdjustWaitForDelay (wt, millisToGo); } /* @@ -726,7 +709,7 @@ if (XFD_ANYSET(&AllClients) && state == XDM_RUN_SESSION) timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000; } - else if (timeOutTime && GetTimeInMillis() >= timeOutTime) + else if (timeOutTime && (int) (GetTimeInMillis() - timeOutTime) >= 0) { if (state == XDM_RUN_SESSION) {