;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*- ;;; Patch file for System version 123.74 ;;; Reason: ;;; Attempt to solve the Chaosnet "File Input" and "Host Down" hangs. ;;; When the remote end sends a STS that indicates that all outstanding packets have ;;; been received, but that not all are acknowledged, we clear out the send-pkt list. ;;; If the acknowledgement is lost, we don't retransmit, as there are no packets to ;;; retransmit. In this case, we should send a SNS to elicit a STS with updated ;;; acknowledgment info. Fix to chaos:retransmission to do exactly that... ;;; Along same lines: chaos:retransmission should count the firrst packet still on ;;; the send list as the lowest packet number -- not last packet acknowledged. ;;; Written 25-Oct-87 14:56:43 by pld at site LMI Cambridge ;;; while running on Jack Flanders from band 2 ;;; with Experimental System 123.73, Experimental Local-File 73.0, Experimental FILE-Server 22.0, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.0, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, microcode 1754, SDU Boot Tape 3.12, SDU ROM 8. ; From modified file DJ: L.NETWORK.CHAOS; CHSNCP.LISP#393 at 25-Oct-87 15:16:09 #10R CHAOS#: (COMPILER-LET ((*PACKAGE* (PKG-FIND-PACKAGE "CHAOS"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; CHAOS; CHSNCP  " (DEFUN RETRANSMISSION (CONN &AUX TIME (INHIBIT-SCHEDULING-FLAG T)) (when (MEMQ (STATE CONN) '(OPEN-STATE RFC-SENT-STATE)) ;;Only if it is open or awaiting a response from RFC (when (null (send-pkts conn)) (when (pktnum-< (send-pkt-acked conn) (pkt-num-sent conn)) ;;No packets to transmit but none on send-list. Remote end has received all of ;;our packets but has not acknowledged them all. Send a SNS to elicit a STS (setq inhibit-scheduling-flag nil) (let ((pkt (net:allocate-packet))) (setf (pkt-opcode pkt) sns-op) (setf (pkt-nbytes-on-write pkt) 0) (transmit-int-pkt-for-conn conn pkt)) (setq more-retransmission-needed t)) ;Indicate that pkts remain unacknowledged (return-from retransmission t)) ;And return from this function ;; Doing this outside the loop can lose ;; because then TIME can be less than (PKT-TIME-TRANSMITTED PKT). (SETQ TIME (zl:TIME)) ;On the other hand, doing it inside the loop loses ;;because if there are enough PKTs pending for a particular CONN, it can ;;hang because every time it sends one it has to restart from the beginning ;;of the list. So now we deal with the case mentioned above explicitly. (DO-NAMED CONN-DONE () (NIL) (LET ((INHIBIT-SCHEDULING-FLAG T)) (DO* ((PKT (SEND-PKTS CONN) (PKT-LINK PKT)) (first-pkt-num (and pkt (pkt-num pkt)))) ((NULL PKT) (RETURN-FROM CONN-DONE NIL)) (COND ((NOT (EQ CONN (PKT-SOURCE-CONN PKT))) (FERROR "~S in SEND-PKTS list for incorrect CONN: CONN ~S, (PKT-SOURCE-CONN PKT) ~S." PKT CONN (PKT-SOURCE-CONN PKT)))) (SETQ MORE-RETRANSMISSION-NEEDED T) (COND ((TIME-LESSP TIME (PKT-TIME-TRANSMITTED PKT))) ;Dont do this one again. (( (TIME-DIFFERENCE TIME (PKT-TIME-TRANSMITTED PKT)) (LSH (CONN-RETRANSMISSION-INTERVAL CONN) ;; Retransmit the lowest numbered packet most often (MAX 0 (MIN 5 (1- (pktnum-- (PKT-NUM PKT) first-pkt-num)))))) (SETF (PKT-BEING-RETRANSMITTED PKT) T) (SETQ INHIBIT-SCHEDULING-FLAG NIL) (TRANSMIT-PKT PKT T) (INCF PKTS-RETRANSMITTED) (SETQ INHIBIT-SCHEDULING-FLAG T) (COND ((EQ (PKT-BEING-RETRANSMITTED PKT) 'FREE) (SETF (PKT-BEING-RETRANSMITTED PKT) NIL) (FREE-PKT PKT)) (T (SETF (PKT-BEING-RETRANSMITTED PKT) NIL))) (RETURN NIL))))) ;Must always start from beginning of chain if ; turned on scheduling, since chain could be invalid (PROCESS-ALLOW-SCHEDULE)))) ))