Date: Sun, 17 Jun 2001 13:25:16 +0900 (JST) From: tak@st.rim.or.jp (NAKAMURA Takayuki) To: FreeBSD-gnats-submit@freebsd.org Cc: tak@st.rim.or.jp Subject: kern/28218: A peer of TCP socket cannot detect termination of another peer Message-ID: <200106170425.NAA11988@reverse.takn.yi.org>
next in thread | raw e-mail | index | archive | help
>Number: 28218 >Category: kern >Synopsis: A peer of TCP socket cannot detect termination of another peer >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jun 16 21:30:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: NAKAMURA Takayuki >Release: FreeBSD 4.3-RELEASE i386 >Organization: (none) >Environment: System: FreeBSD parsley 4.3-RELEASE FreeBSD 4.3-RELEASE #0: Mon May 21 20:46:55 JST 2001 takayuki@parsley.ma.onlab.ntt.co.jp:/usr/src/sys/compile/TAKA i386 >Description: The following sequence shows the problem of the socket implementation. [server side] |takayuki@parsley:~/sample>uname -a |FreeBSD parsley 4.3-RELEASE FreeBSD 4.3-RELEASE #0: Mon May 21 20:46:55 JST 2001 takayuki@parsley.ma.onlab.ntt.co.jp:/usr/src/sys/compile/TAKA i386 |takayuki@parsley:~/sample>ls -l |total 5 |-rw-r--r-- 1 takayuki staff 2945 Jun 17 12:56 client.el |-rw-r--r-- 1 takayuki staff 1819 Jun 17 12:56 server.c |takayuki@parsley:~/sample>gcc server.c |takayuki@parsley:~/sample>./a.out [client side] |takayuki@parsley:~/sample>emacs -q -nw M-x load-file[ret] Load file: ~/sample/client.el M-x client-start[ret] hello[ret] ^Z |Suspended |takayuki@parsley:~/sample>kill %1 |takayuki@parsley:~/sample> |[1] Terminated emacs -q -nw ***** Now, the server side cannot detect termination of the client process. |takayuki@parsley:~/sample>ps uxg | grep a.out |takayuki 61304 0.0 0.1 332 200 p1 R+ 1:00PM 0:00.00 grep a.out |takayuki 61297 0.0 0.1 848 308 p2 I+ 12:56PM 0:00.00 ./a.out |takayuki 61302 0.0 0.1 860 384 p2 I+ 12:58PM 0:00.00 ./a.out ***** "M-x telnet" is not affected. [client side] |takayuki@parsley:~/sample>emacs -q -nw M-x telnet[ret] Open connection to host: localhost 12345 hello[ret] ^Z |Suspended |takayuki@parsley:~/sample>kill %1 |takayuki@parsley:~/sample> |[1] Terminated emacs -q -nw ***** In this time the server side detects termination. |takayuki@parsley:~/sample>./a.out |received: hoge | |child process: end. |takayuki@parsley:~/sample>ps uxg | grep a.out |takayuki 61342 0.0 0.0 300 172 p1 R+ 1:06PM 0:00.00 grep a.out |takayuki 61334 0.0 0.1 848 332 p2 I+ 1:04PM 0:00.00 ./a.out ***** This problem can be reproduced on any 4.3-RELEASE system, but 4.1-RELEASE does not perform the problem. 4.2-RELASE is not tested. In the above operation sequence, the problem appears on both localhost and other Ethernet connected server hosts where any OSs run. Tcpdump says that TCP FIN packet is not sent. Client side must be FreeBSD 4.3-RELEASE. In the above operation sequence, "emacs" is introduced from packages-4.3. Both emacs 20.x and ja-mule-19.x reproduce the problem. This problem can be reproduced on client side. I don't know whether server side has the same problem. >How-To-Repeat: [server.c] #include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> /* Sample Port */ #define serverPortNum 12345 static void sigchld_handler(int sig) { int pid; int status; for (;;) { pid = waitpid(-1, &status, WNOHANG); if (pid <= 0) break; } } int main(void) { int server_skt, newskt; struct sockaddr_in socketAddress, rsocketAddress; socklen_t length; int count; char buf[256]; struct sigaction sa; int optval; server_skt = socket(PF_INET, SOCK_STREAM, 0); socketAddress.sin_family = AF_INET; socketAddress.sin_addr.s_addr = INADDR_ANY; socketAddress.sin_port = htons(serverPortNum); optval = 1; setsockopt(server_skt, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(int)); if (bind(server_skt, (struct sockaddr *)&socketAddress, sizeof(socketAddress) ) < 0) { perror("bind failed"); return 1; } listen(server_skt, 4); sigaction(SIGCHLD, NULL, &sa); sa.sa_handler = sigchld_handler; sigaction(SIGCHLD, &sa, NULL); for (;;) { length = sizeof(rsocketAddress); newskt = accept(server_skt, (struct sockaddr *)&rsocketAddress, &length); if (fork() == 0) { /* child proess */ close(server_skt); /* processing... */ for (;;) { count = read(newskt, buf, sizeof(buf)-1); if (count <= 0) { if (count < 0) perror("read on child process"); break; } buf[count] = 0; printf("received: %s\n", buf); write(newskt, buf, count); } printf("child process: end.\n"); return 0; } close(newskt); } /* NOTREACHED */ return 0; } [client.el] ;;; client sample (setq server-name "localhost") (setq server-port 12345) (defvar client-input-map nil) (defvar client-process nil) (defconst client-log-buffer "*client LOG*") (defconst client-input-buffer "*client INPUT*") ;; functions (defun client-reconfigure-windows () (switch-to-buffer (get-buffer-create client-input-buffer)) (client-mode) (delete-other-windows) (split-window-vertically -4) (switch-to-buffer (get-buffer-create client-log-buffer)) (goto-char (point-max)) (other-window 1) (goto-char (point-max)) (redraw-frame (selected-frame))) (defun client-mode () "Major mode for the Client" (interactive) (if client-input-map nil (setq client-input-map (make-sparse-keymap)) (define-key client-input-map "\C-m" 'client-send-message-full)) (use-local-map client-input-map)) (defun client-get-string () (save-excursion (let ((p (point))) (beginning-of-line) (buffer-substring (point) p)))) (defun client-send-message () (let ((str (client-get-string))) (process-send-string client-process (concat str "\n")))) (defun client-send-message-full () (interactive) (end-of-line) (client-send-message) (newline)) (defun client-start () "Start client" (interactive) (client-reconfigure-windows) (message "trying to connect host %s:%d ..." server-name server-port) (setq client-process (open-network-stream "client" client-log-buffer server-name server-port)) (set-buffer (get-buffer client-log-buffer)) (set-marker (process-mark client-process) (point)) (goto-char (point-max)) (set-buffer (get-buffer client-input-buffer)) (goto-char (point-min)) (set-process-sentinel client-process 'client-sentinel) (set-process-buffer client-process (get-buffer client-log-buffer)) (set-process-filter client-process 'client-display-filter) (message "client: Connection established. [%s:%d]" server-name server-port)) (defun client-sentinel (process event) (let ((stat (process-status process)) mf) (save-excursion (set-buffer (process-buffer process)) (goto-char (point-min))) (if (or (eq stat 'closed) (eq stat 'exit)) (progn (message "client: Connection closed.") (delete-process client-process) (force-mode-line-update t) (save-excursion (set-buffer (process-buffer process)) (goto-char (point-max)) (insert "*** Connection closed. ***\n"))) (error "client: %s" event)))) (defun client-display-filter (proc string) (let ((old-buffer (current-buffer)) excess-string p len) (unwind-protect (let (eqp) (set-buffer (process-buffer proc)) (get-buffer-window (current-buffer) 'visible) (setq eqp (= (point) (process-mark proc))) (save-window-excursion (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (set-buffer old-buffer))))) ;;; end of file >Fix: no fix is known. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106170425.NAA11988>