Cross thread shutdown of connected UDP socket, unexpected recvfrom behavior

2013-11-09 Thread mpb
Hi LKML,

I have a C/pthreads program with two threads ("main" and "thread").
"thread" calls recvfrom on a connected UDP socket and blocks, waiting
for input.  "main" then calls shutdown SHUT_RD on the socket.  In
"thread", recvfrom returns, apparently successfully, returning a zero
length string, and setting src_addr to a bogus(?) address family,
port, and source address.

Is the above the correct behavior for recvfrom?

Here is output from my program.  "main" sends "hello\0", then "" (the
empty string), then calls shutdown.  "thread" receives "hello\0", "",
and then finally receives an empty string that was never sent!

thread  recvfrom: Success
  rv 6  addrlen 16  fam 2  port 8000  addr 17f

thread  recvfrom: Success
  rv 0  addrlen 16  fam 2  port 8000  addr 17f

mainshutdown: Success
  rv 0

thread  recvfrom: Success
  rv 0  addrlen 16  fam 59060  port 44237  addr deaadef0

The source code (2k) for the porgram is attached.  I'm running Ubuntu
13.04, kernel 3.8.0-19-generic #30-Ubuntu, on 32-bit i686.

For reference, this June 2000 LKML thread discusses calling close in a
similar situation.
http://www.gossamer-threads.com/lists/linux/kernel/144379

Please CC me if you have questions, otherwise I'll try to watch for
answers in the list archives.

Thanks!

-mpb


#include 
#include 
#include 
#include 
#include 


struct sockaddr_in  addr_0, addr_1, addr_2 ;
int fd0, fd1, rv0, rv1, addrlen;
charbuf_0[1024], buf_1[1024];
pthread_t   thread;
void*   thread_rv;


void* thread_main (void* arg) {

  int i;  for ( i=0;  i<3;  i++ ) {

addr_2.sin_family   =  0;
addr_2.sin_port =  0;
addr_2.sin_addr.s_addr  =  0;

addrlen = sizeof addr_2;
rv1 = recvfrom ( fd1, buf_0, sizeof buf_0, 0,
		 (struct sockaddr*) _2,  );

int fam   =  addr_2.sin_family;
int port  =  addr_2.sin_port;
int addr  =  addr_2.sin_addr.s_addr;

printf ("\n");
perror ("thread  recvfrom");
printf ( "  rv %d  addrlen %d  fam %d  port %d  addr %x\n",
	 rv1, addrlen, fam, ntohs (port), addr );
;;; }

  return NULL; }


void main_main () {

  send ( fd0, "hello", 6, 0);
  send ( fd0, "",  0, 0);
  usleep (10);

  rv0 = shutdown ( fd1, SHUT_RD );
  printf ("\n");
  perror ("mainshutdown");
  printf ("  %d\n", rv0)

  ;;; }


int main () {

  addr_0.sin_family = AF_INET;
  addr_0.sin_port = htons (8000);
  inet_pton ( AF_INET, "127.0.0.1", _0.sin_addr );

  addr_1.sin_family = AF_INET;
  addr_1.sin_port = htons (8001);
  inet_pton ( AF_INET, "127.0.0.1", _1.sin_addr );

  fd0 = socket ( AF_INET, SOCK_DGRAM, 0 );
  bind( fd0, (struct sockaddr*) _0, sizeof addr_0 );
  connect ( fd0, (struct sockaddr*) _1, sizeof addr_1 );

  fd1 = socket ( AF_INET, SOCK_DGRAM, 0 );
  bind( fd1, (struct sockaddr*) _1, sizeof addr_1 );
  connect ( fd1, (struct sockaddr*) _0, sizeof addr_0 );

  pthread_create ( , NULL, thread_main, NULL );
  main_main ();
  pthread_join ( thread, _rv );

  return 0; }


Cross thread shutdown of connected UDP socket, unexpected recvfrom behavior

2013-11-09 Thread mpb
Hi LKML,

I have a C/pthreads program with two threads (main and thread).
thread calls recvfrom on a connected UDP socket and blocks, waiting
for input.  main then calls shutdown SHUT_RD on the socket.  In
thread, recvfrom returns, apparently successfully, returning a zero
length string, and setting src_addr to a bogus(?) address family,
port, and source address.

Is the above the correct behavior for recvfrom?

Here is output from my program.  main sends hello\0, then  (the
empty string), then calls shutdown.  thread receives hello\0, ,
and then finally receives an empty string that was never sent!

thread  recvfrom: Success
  rv 6  addrlen 16  fam 2  port 8000  addr 17f

thread  recvfrom: Success
  rv 0  addrlen 16  fam 2  port 8000  addr 17f

mainshutdown: Success
  rv 0

thread  recvfrom: Success
  rv 0  addrlen 16  fam 59060  port 44237  addr deaadef0

The source code (2k) for the porgram is attached.  I'm running Ubuntu
13.04, kernel 3.8.0-19-generic #30-Ubuntu, on 32-bit i686.

For reference, this June 2000 LKML thread discusses calling close in a
similar situation.
http://www.gossamer-threads.com/lists/linux/kernel/144379

Please CC me if you have questions, otherwise I'll try to watch for
answers in the list archives.

Thanks!

-mpb


#include netinet/in.h
#include pthread.h
#include stdio.h
#include sys/socket.h
#include sys/types.h


struct sockaddr_in  addr_0, addr_1, addr_2 ;
int fd0, fd1, rv0, rv1, addrlen;
charbuf_0[1024], buf_1[1024];
pthread_t   thread;
void*   thread_rv;


void* thread_main (void* arg) {

  int i;  for ( i=0;  i3;  i++ ) {

addr_2.sin_family   =  0;
addr_2.sin_port =  0;
addr_2.sin_addr.s_addr  =  0;

addrlen = sizeof addr_2;
rv1 = recvfrom ( fd1, buf_0, sizeof buf_0, 0,
		 (struct sockaddr*) addr_2, addrlen );

int fam   =  addr_2.sin_family;
int port  =  addr_2.sin_port;
int addr  =  addr_2.sin_addr.s_addr;

printf (\n);
perror (thread  recvfrom);
printf (   rv %d  addrlen %d  fam %d  port %d  addr %x\n,
	 rv1, addrlen, fam, ntohs (port), addr );
;;; }

  return NULL; }


void main_main () {

  send ( fd0, hello, 6, 0);
  send ( fd0, ,  0, 0);
  usleep (10);

  rv0 = shutdown ( fd1, SHUT_RD );
  printf (\n);
  perror (mainshutdown);
  printf (  %d\n, rv0)

  ;;; }


int main () {

  addr_0.sin_family = AF_INET;
  addr_0.sin_port = htons (8000);
  inet_pton ( AF_INET, 127.0.0.1, addr_0.sin_addr );

  addr_1.sin_family = AF_INET;
  addr_1.sin_port = htons (8001);
  inet_pton ( AF_INET, 127.0.0.1, addr_1.sin_addr );

  fd0 = socket ( AF_INET, SOCK_DGRAM, 0 );
  bind( fd0, (struct sockaddr*) addr_0, sizeof addr_0 );
  connect ( fd0, (struct sockaddr*) addr_1, sizeof addr_1 );

  fd1 = socket ( AF_INET, SOCK_DGRAM, 0 );
  bind( fd1, (struct sockaddr*) addr_1, sizeof addr_1 );
  connect ( fd1, (struct sockaddr*) addr_0, sizeof addr_0 );

  pthread_create ( thread, NULL, thread_main, NULL );
  main_main ();
  pthread_join ( thread, thread_rv );

  return 0; }