;;; -*- Mode:Lisp; Readtable:CL; Package:USER; Base:10; Patch-File:T -*- ;;; Patch file for System version 123.180 ;;; Reason: ;;; Patch 123.169 doesn't quite do the job -- it can cause TCP not to hand up ;;; PUSHED data immediately and to acknowledge data that hasn't been received. ;;; Also create (tcp:print-tcp-receive-log) and make that function and ;;; (tcp:print-tcp-log) go to *standard-output* instead of *terminal-io*. ;;; Written 8-Jan-88 14:30:22 by pld at site Gigamos Cambridge ;;; while running on James Brown from band 1 ;;; with Experimental System 123.179, Experimental Local-File 73.3, Experimental FILE-Server 22.1, Experimental Unix-Interface 11.0, Experimental Tape 18.0, Experimental KERMIT 34.3, Experimental ZMail 71.0, Experimental Lambda-Diag 15.0, microcode 1754, SDU Boot Tape 3.13, SDU ROM 102. ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#285 at 8-Jan-88 14:42:17 #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)))) (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) (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) ;;Unless this buffer precedes the packet.... (when (32-bit-> packet-seq buffer-seq) ;;If part of packet went into this buffer... (adjust-push-offset elt (and push-offset (+ buffer-offset push-offset copy-bytes)))) (reset-holes socket) (return))) (t (error "packet-bytes < 0"))) (setq buffer-seq buffer-edge))) (values packet-bytes packet-offset packet-seq push-offset buffer-seq)) )) ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#285 at 8-Jan-88 14:42:36 #10R TCP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  " (defun send-immediate-ack (tp) "Builds and sends a ACK packet for a specific TCP connection" (with-lock ((tcp-user-lock tp)) (unless (eq (tcp-user-state tp) :closed) (tcp-stat-incf tp ack-packets-sent) (tcp-log :send-ack tp (RCV.NXT tp)) (setf (tcp-user-ack-needed-p tp) nil) (cancel-timeout tp 'ack-delay-timeout) (multiple-value-bind (header ip-header) (build-ack-packet tp) (send-control-packet header ip-header tp))))) )) ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#285 at 8-Jan-88 14:42:40 #10R TCP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  " (defun tcp-receive-logging (enable) "Turns on TCP logging for data reception" (setq *tcp-logging* nil) (setq *tcp-log-keywords* nil) (initialize-tcp-log) (when enable (setq *tcp-log-keywords* '(:open :close :read :receive :copy :save :retrieve :drop :read-reply :send-ack)) (setq *tcp-logging* t))) )) ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#285 at 8-Jan-88 14:42:43 #10R TCP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  " (defun print-tcp-log (&optional (stream *standard-output*)) (unless (fifo-empty-p *tcp-log*) (format stream "~&S/R sport dport SEQ ACK flags WND UP data") (dolist (elt (fifo-as-list *tcp-log*)) (let ((keyword (case (car elt) (:copy :CPY) (:save :SAV) (:retrieve :RET) (:drop :DRP) (:delay :DLY) (:wait :WAI) (:skip :SKP) (:send-ack :ACK) (:timeout :TMO) (:user-timeout :UTM) (:cancel :CAN) (:open :OP) (:open-reply :OPR) (:close :CL) (:close-reply :CLR) (:abort :ABO) (:read :RD) (:read-reply :RDR) (:write :WR) (:write-reply :WRR) (:reset-received :RSR) (:reset-packet :RSP) (:reset-sent :RSS) (:receive :RCV) (:send :SND) (:failed-send :FAI) (:failed-send-timeout :FST) (:block :BLK) (:unblock :UBL) (:initial-rtt :IRT) (:rtt :RTT))) (args (cdr elt))) (case (car elt) ((:copy :save :retrieve :drop) (format stream "~&~A ~5D ~5D ~5D bytes from ~D -> ~D" keyword (first args) (second args) (third args) (fourth args) (fifth args))) (:user-timeout (format stream "~&~3A ~5D ~5D cum = ~D tmo = ~D" keyword (first args) (second args) (third args) (fourth args))) (:initial-rtt (format stream "~&~3A ~5D ~5D ~,4F" keyword (first args) (second args) (third args))) (:rtt (format stream "~&~3A ~5D ~5D ~,4F -> ~,4F" keyword (first args) (second args) (third args) (fourth args))) (:send-ack (format stream "~&~3A ~5D ~5D ~16,8,'0R" keyword (first args) (second args) (third args))) ((:delay :wait :skip :timeout :cancel :open :open-reply :close :close-reply :abort :failed-send :failed-send-timeout :block :unblock) (format stream "~&~3A ~5D ~5D" keyword (first args) (second args))) (:read-reply (format stream "~&~3A ~5D ~5D ~5D bytes~@[ ~D~]~@[ URG = ~D~]" keyword (first args) (second args) (third args) (fourth args) (fifth args))) ((:read :write :write-reply) (format stream "~&~3A ~5D ~5D ~5D bytes" keyword (first args) (second args) (third args))) (:state (format stream "~&STC ~5D ~5D ~A -> ~A" (first args) (second args) (third args) (fourth args))) (:reset-received (format stream "~&~3A ~5D ~5D ~S" keyword (first args) (second args) (third args))) (:reset-sent (format stream "~&~3A ~5D ~5D ~S" keyword (first args) (second args) (fourth args))) (:reset-packet (let* ((pkt (first args)) (source (tcp-source-port pkt)) (dest (tcp-destination-port pkt))) (format stream "~&~3A (~D[~A]->~D) ~S" keyword source (canonical-ip (third args)) dest (second args)))) ((:send :receive) (let ((pkt (first args)) (data-bytes (second args)) (source (third args)) (destination (fourth args))) (format stream "~&~3A ~5D ~5D ~16,8,'0R ~16,8,'0R ~:[ ~;U~]~:[ ~;A~]~:[ ~;P~]~:[ ~;R~]~:[ ~;S~]~:[ ~;F~] ~5D ~5D ~5D ~A -> ~A" keyword (tcp-source-port pkt) (tcp-destination-port pkt) (tcp-sequence-number pkt) (tcp-ack-number pkt) (tcp-urg-bit-p pkt) (tcp-ack-bit-p pkt) (tcp-psh-bit-p pkt) (tcp-rst-bit-p pkt) (tcp-syn-bit-p pkt) (tcp-fin-bit-p pkt) (tcp-window pkt) (tcp-urgent-pointer pkt) data-bytes (canonical-ip source) (canonical-ip destination)) (when (fifth args) (format stream "~&~S" (fifth args)))))))))) )) ; From modified file DJ: L.NETWORK.IP-TCP.KERNEL; TCP.LISP#285 at 8-Jan-88 14:42:44 #10R TCP#: (COMPILER-LET ((*PACKAGE* (GLOBAL:PKG-FIND-PACKAGE "TCP"))) (COMPILER::PATCH-SOURCE-FILE "SYS: NETWORK; IP-TCP; KERNEL; TCP  " (defun print-tcp-receive-log (&optional (stream *standard-output*)) (unless (fifo-empty-p *tcp-log*) (format stream "~&S/R sport dport SEQ flags WND UP data") (dolist (elt (fifo-as-list *tcp-log*)) (let ((keyword (case (car elt) (:copy :CPY) (:save :SAV) (:retrieve :RET) (:drop :DRP) (:send-ack :ACK) (:open :OP) (:close :CL) (:read :RD) (:read-reply :RDR) (:receive :RCV))) (args (cdr elt))) (case (car elt) ((:copy :save :retrieve :drop) (format stream "~&~A ~5D ~5D ~5D bytes from ~D -> ~D" keyword (first args) (second args) (third args) (fourth args) (fifth args))) (:send-ack (format stream "~&~3A ~5D ~5D ~D" keyword (first args) (second args) (third args))) ((:open :close) (format stream "~&~3A ~5D ~5D" keyword (first args) (second args))) (:read (format stream "~&~3A ~5D ~5D ~5D bytes" keyword (first args) (second args) (third args))) (:read-reply (format stream "~&~3A ~5D ~5D ~5D bytes~@[ ~D~]~@[ URG = ~D~]" keyword (first args) (second args) (third args) (fourth args) (fifth args))) ((:read :write :write-reply) (format stream "~&~3A ~5D ~5D ~5D bytes" keyword (first args) (second args) (third args))) (:receive (let ((pkt (first args)) (data-bytes (second args))) (format stream "~&~3A ~5D ~5D ~D ~:[ ~;U~]~:[ ~;A~]~:[ ~;P~]~:[ ~;R~]~:[ ~;S~]~:[ ~;F~] ~5D ~5D ~5D" keyword (tcp-source-port pkt) (tcp-destination-port pkt) (tcp-sequence-number pkt) (tcp-urg-bit-p pkt) (tcp-ack-bit-p pkt) (tcp-psh-bit-p pkt) (tcp-rst-bit-p pkt) (tcp-syn-bit-p pkt) (tcp-fin-bit-p pkt) (tcp-window pkt) (tcp-urgent-pointer pkt) data-bytes) (when (fifth args) (format stream "~&~S" (fifth args)))))))))) ))