🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.linux.networking
Article #813

socket programming problem

#813
From: John Selbie
Date: Tue, 20 Dec 1994 20:14
189 lines
5948 bytes
I am working on a large networking project that involves socket
communicatons using UDP channels on a variety of platforms. 

It appears that the Linux recvfrom() call is not behaving properly,
because extracting the the IP address from the "from" sockaddr structure
has different results depending on where and how the program is run.

As an example, I've written two simple programs.  "send" and "recv".
"send" transmits a datagram every second to a defined port on the computer
running "receive".  "receive" prints the IP address of any datagram that
comes in on that port.

Everything was compiled using gcc.  (Sun - 2.5.8 ; Linux - 2.6.0)


The programs exhibits the following behavior on a Sun:
(this is the expected results)

/net/hc22/selbie/bug => recv&
[1] 20532

/net/hc22/selbie/bug => send
ip: 130.207.9.20
ip: 130.207.9.20
----------------------------------------------------------

Yet on a Linux box I get the following behavior:
/home/selbie/bug => gcc recv.c -o recv

/home/selbie/bug => gcc send.c -o send

/home/selbie/bug => recv&
[1690]

/home/selbie/bug => send
ip: 0.0.0.0
ip: 0.0.0.0

An IP address of 0, is not the expected result.
----------------------------------------------------------

Even more strange, is that when the program is compiled with
debugging turned on, the correct results come through.

/home/selbie/bug => gcc recv.c -o recv -g

/home/selbie/bug => recv

/home/selbie/bug => recv&
[1] 1751

/home/selbie/bug => send
ip: 130.207.37.101
ip: 130.207.37.101
 
The expected IP address comes through.
-----------------------------------------------------------

The problem was discovered when the real system was compiled
without debugging, the sockaddr extracted from the recvfrom()
call was passed into a sendto() for a response back to the client.
"sendto" errors started appearing as soon as the first client
sent a datagram.  So, it does not appear to be a inet_ntoa() problem.
I am inclined to think this is a gcc/linux problem.  However, it could
be something glaringly obvious. 

It seems that socket experts are few and far between, and posting
to a newsgroup is my last resort.  I think someone out there
can give me some advice.  Anyone who can explain this problem will
receive lots of praise and some beer to boot.

Below is the code for bug.h, send.c, and recv.c.  It will can
also be compiled on other C compilers using the socket and nsl
libraries.

John Selbie
selbie@cc.gatech.edu

/* --------------------------------------------------------- */
/* bug.h */
#define RECEIVE_PORT 40000

/* place the hostname of the machine that runs recv here!    */
#define RECEIVE_IP "hostname"

/* --------------------------------------------------------- */

/* --------------------------------------------------------- */
/* recv.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h> 
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include "bug.h"

void main(int argc, char *argv[])
{
  struct sockaddr_in sin;  /* socket address structure to send on */
  struct sockaddr_in sin2; /* receive address structure */
  int s, n, len;
  char hn[65];
  struct hostent *hp;
  char msg[1300];

  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
    fprintf(stderr,"error: socket(): %d\n", errno);
    exit(1);
  }
 

  sin.sin_family = AF_INET;
  sin.sin_port = htons(RECEIVE_PORT);

  gethostname(hn, 65);
  hp = gethostbyname(hn);
  if (hp == NULL)
  {
    fprintf(stderr, "error with gethostbyname: %d\n");
    exit(1);
  }
  memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);

  bind(s, (struct sockaddr *)&sin, sizeof(sin));

  while (1)
  {
    n = recvfrom(s, msg, 1300, 0, (struct sockaddr *)&sin2, &len);
    if (n < 0)
      fprintf(stderr, "recvfrom error: %d\n", errno);
    else
      printf("ip: %s\n", inet_ntoa(sin2.sin_addr));
  }
}

/* --------------------------------------------------------- */
/* send.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include "bug.h"


void main(void)
{
  struct sockaddr_in sin;
  struct hostent *hp;
  int s;
  char buf[1300];


  sin.sin_family = AF_INET;
  sin.sin_port = htons(RECEIVE_PORT);
  hp = gethostbyname(RECEIVE_IP);

  if (!hp)
  {
      fprintf(stderr, "can't figure out host ip address\n");
      exit(1);
  }

  memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
 
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
    fprintf(stderr,"error: socket(): %d\n", errno);
    exit(1);
  }

  while (1)
  {
    sleep(1);
    if (sendto(s, buf, 1300, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
      fprintf(stderr, "error: unable to sendto(): %d\n", errno);
  }
}
Technical Details
Message-ID: <3d7dvb$lcl@lennon.cc.gatech.edu>
Path: arc1-ca.pugleaf.net!nntp.gmd.de!newsserver.jvnc.net!nntpserver.pppl.gov!princeton!rutgers!gatech!gt-news!cc.gatech.edu!selbie

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,e67558230f76e1ad,start
X-Google-Attributes: gid11318c,public
X-Google-Thread: 10c696,e67558230f76e1ad,start
X-Google-Attributes: gid10c696,public
X-Google-Thread: 10669a,e67558230f76e1ad,start
X-Google-Attributes: gid10669a,public
X-Google-Thread: 100b1f,e67558230f76e1ad,start
X-Google-Attributes: gid100b1f,public
X-Google-ArrivalTime: 1994-12-20 12:14:35 PST
Path: arc1-ca.pugleaf.net!nntp.gmd.de!newsserver.jvnc.net!nntpserver.pppl.gov!princeton!rutgers!gatech!gt-news!cc.gatech.edu!selbie
From: selbie@cc.gatech.edu (John Selbie)
Newsgroups: comp.os.linux.networking,comp.os.linux.help,comp.os.linux.development.apps,gnu.gcc.help
Subject: socket programming problem
Date: 20 Dec 1994 15:14:35 -0500
Organization: Georgia Tech: College of Computing
Lines: 190
Message-ID: <3d7dvb$lcl@lennon.cc.gatech.edu>
NNTP-Posting-Host: lennon-cc.cc.gatech.edu
NNTP-Posting-User: selbie