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)
{