From: Iain Lea (iain.lea@anl433.erlm.siemens.de)
Date: 04/28/93


From: iain.lea@anl433.erlm.siemens.de (Iain Lea)
Subject: Re: rlogin problems: Sun<->Linux
Date: 28 Apr 1993 07:07:38 GMT

John Paul Morrison (jmorriso@rflab.ee.ubc.ca) wrote:
:

: I'm having really annoying rlogin problems between SunOS 4.1.3 and Linux 99pl9

: the rlogind in Linux takes forever to respond to the Sun. From SunOS I can
: sit typing: rlogin linux.host & until I have around 15 rlogin attempts
: in the background, and eventually one of the *latest* rlogin attempts gets
: through

The following context diff has been working well on SLS 1.00 with a 0.99p[678].

Iain

--cut here--

o Kernel modifications:
     - /usr/src/linux/net/tcp/sock.c at line 1826 in get_sock() added:
        if (s->dead && (s->state == TCP_CLOSE))
            continue;

o TCP/IP net-src:
     - /usr/src/net-src/rlogind/rlogind.c
       Just remove all the "ifndef linux" bits from rlogind.c so the OOB
       handling code is re-inserted.
     - /usr/src/net-src/rlogin/rlogin.c
--PATCH BEGIN--
*** rlogin.c.original Sat Mar 13 12:06:19 1993
--- rlogin.c Tue Mar 16 15:44:05 1993
***************
*** 82,89 ****
--- 82,100 ----
  char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
  extern char *krb_realmofhost();
  #endif
  
+ /*
+ * rlogin has problems with urgent data when logging into suns which
+ * results in the connection being closed with an IO error. SUN_KLUDGE
+ * is a work around - the actual bug is probably in tcp.c in the kernel, but
+ * I haven't managed to find it yet.
+ * Andrew.Tridgell@anu.edu.au (12th March 1993)
+ */
+ #ifdef linux
+ #define SUN_KLUDGE
+ #endif
+
  #ifndef TIOCPKT_WINDOW
  #define TIOCPKT_WINDOW 0x80
  #endif
  
***************
*** 556,563 ****
--- 567,577 ----
            bcmp(&ws, &winsize, sizeof(ws))) {
                winsize = ws;
                sendwindow();
        }
+ #ifdef SUN_KLUDGE
+ signal(SIGWINCH,sigwinch);
+ #endif
  }
  
  /*
   * Send the window size to the server via the magic escape
***************
*** 596,605 ****
  jmp_buf rcvtop;
  int ppid, rcvcnt, rcvstate;
  char rcvbuf[8 * 1024];
  
  void
! oob()
  {
        struct sgttyb sb;
        int atmark, n, out, rcvd;
        char waste[BUFSIZ], mark;
--- 610,629 ----
  jmp_buf rcvtop;
  int ppid, rcvcnt, rcvstate;
  char rcvbuf[8 * 1024];
  
+ void oob()
+ {
+ void oob_real();
+ oob_real();
+ #ifdef SUN_KLUDGE
+ signal(SIGURG,oob);
+ #endif
+ }
+
+
  void
! oob_real()
  {
        struct sgttyb sb;
        int atmark, n, out, rcvd;
        char waste[BUFSIZ], mark;
***************
*** 636,644 ****
--- 660,670 ----
        if (!eight && (mark & TIOCPKT_NOSTOP)) {
                (void)ioctl(0, TIOCGETP, (char *)&sb);
                sb.sg_flags &= ~CBREAK;
                sb.sg_flags |= RAW;
+ #ifndef SUN_KLUDGE
                (void)ioctl(0, TIOCSETN, (char *)&sb);
+ #endif
                notc.t_stopc = -1;
                notc.t_startc = -1;
                (void)ioctl(0, TIOCSETC, (char *)&notc);
        }
***************
*** 728,735 ****
--- 754,778 ----
                else
  #endif
  #endif
                        rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
+
+ /*
+ * If we get a EIO from a read then it may mean that we have unread ungent data
+ * waiting that is getting in the way. We probably have got more then one lot of
+ * urgent data but we only got one SIGURG due to a problem in the kernel tcp.
+ * We can try and fix this by sending ourself a SIGURG and pretending the error
+ * never occurred. This might be a problem if we really _should_ be getting
+ * a EIO for some unrelated reason. (AJT 3/93)
+ */
+ #ifdef SUN_KLUDGE
+ if (rcvcnt < 0 && errno == EIO)
+ {
+ errno = 0;
+ kill(getpid(),SIGURG);
+ continue;
+ }
+ #endif
                if (rcvcnt == 0)
                        return (0);
                if (rcvcnt < 0) {
                        if (errno == EINTR)
***************
*** 793,800 ****
--- 836,846 ----
  void
  copytochild()
  {
        (void)kill(child, SIGURG);
+ #ifdef SUN_KLUDGE
+ signal(SIGCHLD,copytochild);
+ #endif
  }
  
  msg(str)
        char *str;