;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*-
;;; Patch file for System version 123.58
;;; Reason:
;;;  Nasty bug in TCP: If a FIN arrived in a segment by itself, but some prior segment
;;;  had been lost, a read buffer could be marked as full -- causing it to be returned
;;;  with whatever garbage it had in it.
;;; Written 19-Oct-87 10:53:23 by pld at site LMI Cambridge
;;; while running on Jack Flanders from band 2
;;; with Experimental System 123.56, 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.IP-TCP.KERNEL; TCP.LISP#280 at 19-Oct-87 10:53:26
#10R TCP#: 
(COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP")))
  (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  "

(defun copy-packet-data-to-receive-data (socket buffer-seq packet packet-bytes packet-offset packet-seq
					 push-offset keyword)
  "Copy data from a received packet into user receive buffers.  Return amount of uncopied data"
  (declare (values bytes-not-copied new-offset new-sequence new-push-offset new-buffer-seq))
  (do ((list (fifo-as-list (tcp-user-receive-data socket)) (cdr list))
       (packet-edge (32-bit-plus packet-seq packet-bytes)))	;sequence number of end of packet
      ((null list))				;Quit when we've run out of buffers
    (let* ((elt (car list))
	   (length (array-length (rcv-buffer elt)))
	   (buffer-edge (32-bit-plus buffer-seq length))
	   (buffer-offset 0)
	   (copy-bytes 0))
      ;;Sequence numbers of buffer: [buffer-seq,buffer-edge)
      (cond ((32-bit-< buffer-seq packet-seq)
	     ;;Packet starts after left edge of buffer
	     (unless (32-bit-<= buffer-edge packet-seq)
	       ;;Packet's left edge is in this buffer
	       (setq buffer-offset (32-bit-minus packet-seq buffer-seq))
	       (setq copy-bytes (min (- length buffer-offset) packet-bytes))))
	    ((32-bit->= packet-edge buffer-seq)
	     ;;Packet's right edge is in this buffer
	     (setq buffer-offset 0)
	     (setq copy-bytes (min length packet-bytes)))
	    (t
	     (setq buffer-offset 0)
	     (setq copy-bytes 0)))
      (when (plusp copy-bytes)
	(copy-tcp-data packet packet-offset elt buffer-offset copy-bytes socket keyword)
	(incf packet-offset copy-bytes)
	(setq packet-seq (32-bit-plus packet-seq copy-bytes))
	(decf packet-bytes copy-bytes))
      (setq buffer-seq buffer-edge)
      (when push-offset
	(decf push-offset copy-bytes))
      (cond ((plusp packet-bytes)		;Entire packet doesn't fit in this buffer
	     (when push-offset
	       (setf (rcv-push-offset elt) (array-length (rcv-buffer elt)))))
	    ((zerop packet-bytes)
	     (unless (32-bit-<= buffer-edge packet-seq)
	       (adjust-push-offset elt (and push-offset (+ buffer-offset push-offset copy-bytes)))
	       (reset-holes socket)
	       (return)))
	    (t
	     (error "packet-bytes < 0")))))
  (values packet-bytes packet-offset packet-seq push-offset buffer-seq))

))
