delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2018/06/13/09:49:26

X-Recipient: archive-cygwin AT delorie DOT com
DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:date:from:to:subject:message-id:mime-version
:content-type; q=dns; s=default; b=etsFVif/hjKyje0sVO55XqnlDfYDn
EhRJLX6eof+Ac90w+G+pnNySgEwWVs0grHJXMGm+xH0sLzwLhDGyfqNzikoqfxuE
OS0KMc3LU8GmPuD6w1UeTci3MmnMyw+YqI+JqMrc4Ng6EO05LrY+YqU1dbugCAnk
A0d3mkW6CI4m50=
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:date:from:to:subject:message-id:mime-version
:content-type; s=default; bh=/uUT13qGudtq9nA+DUIwfDM+BLg=; b=XiV
/WXjKABBBlNQEYd88hOZRtyLLjd9i8SyYPLE0QxiYG4GY3nAnYl3hwRmQdoz+HKr
hDAYzYcHaomgmSeLFFdP3wfIinOre38POG3qPOpOqUemTJVh9NFNdR6JBUV1sH3p
Cxr0kT6SIL/PQklPKwNyIBzjXXFiLuTWD3rXVM1I=
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=H*F:D*ne.jp, UD:jp, listen, 100000
X-HELO: conssluserg-01.nifty.com
DKIM-Filter: OpenDKIM Filter v2.10.3 conssluserg-01.nifty.com w5DDms6K010117
X-Nifty-SrcIP: [125.3.30.127]
Date: Wed, 13 Jun 2018 22:48:58 +0900
From: Takashi Yano <takashi DOT yano AT nifty DOT ne DOT jp>
To: cygwin AT cygwin DOT com
Subject: Problems of AF_INET domain socket regarding out-of-band data.
Message-Id: <20180613224858.7822b08abb75d76b72920095@nifty.ne.jp>
Mime-Version: 1.0
X-IsSubscribed: yes

--Multipart=_Wed__13_Jun_2018_22_48_58_+0900_VUITj9uMjPPjbkfq
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Hello,

I have found a few problems of AF_INET domain socket regarding
out-of-band data.

1. recv() with MSG_OOB flag eats normal data if no OOB data
  is sent yet.

2. Calling recv() with MSG_OOB flag is blocked if no OOB data
  is sent yet.

3. Calling recv() without MSG_OOB flag after receiving OOB data
  is blocked even if received data exist in buffer. 

Regarding problem 1 and 2, POSIX states as follows about recv().
[EINVAL]
The MSG_OOB flag is set and no out-of-band data is available.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html

Attached is a sample program to reproduce these problems.
Argument to this program specifies the test mode.
0: cause problem 1
2: cause problem 2
3: cause problem 3

Expected results:
debian:~/OOB> ./server_client 0
recv(OOB): Invalid argument
OOB   :  (-1)
NORMAL: 1234567890 (10)
debian:~/OOB> ./server_client 1
OOB   : A (1)
NORMAL: 1234567890 (10)
debian:~/OOB> ./server_client 2
recv(OOB): Invalid argument
OOB   :  (-1)
NORMAL: 1234567890 (10)
debian:~/OOB> ./server_client 3
OOB   : A (1)
NORMAL: 1234567890 (10)
debian:~/OOB>

Result on cygwin:
[yano AT Express5800-S70 ~/OOB]$ ./server_client 0
OOB   : 1234567890 (10)
NORMAL:  (0)
[yano AT Express5800-S70 ~/OOB]$ ./server_client 1
OOB   : A (1)
NORMAL: 1234567890 (10)
[yano AT Express5800-S70 ~/OOB]$ ./server_client 2
[yano AT Express5800-S70 ~/OOB]$ ./server_client 3
OOB   : A (1)
[yano AT Express5800-S70 ~/OOB]$

Only the result of test mode 1 is as expected.

I have confirmed this occurs in both latest 32bit and 64 bit
cygwin.

-- 
Takashi Yano <takashi DOT yano AT nifty DOT ne DOT jp>

--Multipart=_Wed__13_Jun_2018_22_48_58_+0900_VUITj9uMjPPjbkfq
Content-Type: text/x-csrc;
 name="server_client.c"
Content-Disposition: attachment;
 filename="server_client.c"
Content-Transfer-Encoding: 7bit

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>

#define PORT	12345
#define HOST	"127.0.0.1"

int server(int mode)
{
	int sock0, sock1;
	struct sockaddr_in addr;
	struct sockaddr_in client;
	socklen_t len;

	/* Create a socket */
	sock0 = socket(AF_INET, SOCK_STREAM, 0);
	if (sock0 < 0) {
		perror("socket");
		return -1;
	}

	/* Bind */
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = INADDR_ANY;
	if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("bind");
		return -1;
	}

	/* Wait for connection from client */
	if (listen(sock0, 1) < 0) {
		perror("listen");
		return -1;
	}

	/* Accept connection */
	len = sizeof(client);
	sock1 = accept(sock0, (struct sockaddr *)&client, &len);
	if (sock1 < 0) {
		perror("accept");
		return -1;
	}

	/* Send normal data */
	if (send(sock1, "1234567890", 10, 0) < 0) {
		perror("send");
		return -1;
	}
	if (mode & 1) {
		/* Send out-of-band data */
		if (send(sock1, "A", 1, MSG_OOB) < 0) {
			perror("send(OOB)");
			return -1;
		}
	}

	/* Wait for receiving all data at client side */
	usleep(200000);

	if (mode & 2) {
		return -1; /* return -1 to kill client */
	}

	/* Close client socket */
	close(sock1);

	/* Close socket for listen */
	close(sock0);

	return 0;
}

int client()
{
	struct sockaddr_in server;
	int sock;
	char buf[256];
	int n;

	/* Create a socket */
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		perror("sock");
		return -1;
	}

	/* Setting for connection */
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = inet_addr(HOST);

	/* Connect to server */
	if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
		perror("connect");
		return -1;
	}

	/* Wait for sending all data at server side */
	usleep(100000);

	/* Receive out-of-band data from server */
	memset(buf, 0, sizeof(buf));
	n = recv(sock, buf, sizeof(buf), MSG_OOB);
	if (n<0) {
		perror("recv(OOB)");
	}
	printf("OOB   : %s (%d)\n", buf, n);
	/* Receive normal data from server */
	memset(buf, 0, sizeof(buf));
	n = recv(sock, buf, sizeof(buf), 0);
	if (n<0) {
		perror("recv");
	}
	printf("NORMAL: %s (%d)\n", buf, n);

	/* Close socket */
	close(sock);

	return 0;
}

int main(int argc, char *argv[])
{
	int mode = 0;
	pid_t pid;

	if (argc >= 2) {
		mode = atoi(argv[1]);
	}

	pid = fork();
	if (pid) {
		if (server(mode) < 0) kill(pid, SIGTERM);
		wait(NULL);
	} else {
		return client();
	}
	return 0;
}


--Multipart=_Wed__13_Jun_2018_22_48_58_+0900_VUITj9uMjPPjbkfq
Content-Type: text/plain; charset=us-ascii


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
--Multipart=_Wed__13_Jun_2018_22_48_58_+0900_VUITj9uMjPPjbkfq--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019