[comp.protocols.tcp-ip] Problems with heterogeneous networks

goldstn@evax.arl.utexas.edu (David Goldstein) (02/08/91)

For quite some time I've been unable to debug TCP/IP code that behaves
as follows:

sockets are used to communicate at port #2700. the same code is used on
each machine.

sun4 -> sun4 fine
sun4 -> sun3 fine
sun3 -> sun4 connects properly, but sending gets bad address on the Unix
		"write"..
		seems as if the socket # is correct though
sun3 -> sun3      "
VAX (Ultrix) and Sun4 -> does not connect

Can anyone give me some insight  on this problem?  Enclosed is some of
the relevent source code, loaded with print statements for debugging.
Thanks very much for even reading!
David


/**********************************************************************
   Name:  Setup sockets

 Abstract:  This routine sets up sockets for the interactive
     workstations.  The white workstation connects at a reserved
     port.  A server port is set up for the other workstations.
     The ports are set to be non-blocking so that an "accept"
     can be done in a loop without hanging.

 
  Revision History:
    06/06/90    D. Goldstein	 
***********************************************************************/
#include <sys/types.h> 
/* #include <sys/socket.h>  */
#include <stdio.h>
#include <netinet/in.h> 
/* #include <netdb.h> */
#include <errno.h>
#define SETUP_SOCKETS
#include <ctype.h>
#include "my_sockets.h"
#include "tcmipc.h"
#include "icm.h"
#include "stats.h"
#define TRUE 1
#define FALSE 0
/*
extern int have_told_tcm_quitting;
*/
extern long int timer[20];



/* Make a socket and listen for connections */
int make_server_socket(serv_port)
int serv_port;              /*  server port  */
{
extern struct hostent *gethostbyname();
struct hostent *rhp;
int s, on =0;
struct sockaddr_in raddress;

    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0) give_error("socket in make_server_socket");

    /* look up address of the destination machine */
    if ((rhp = gethostbyname(my_host_name)) == NULL) 
	give_error("gethostbyname make_server_socket");
    bzero((char *)&raddress, sizeof(raddress));
    bcopy(rhp->h_addr,(char *)&raddress.sin_addr,rhp->h_length);
 
    raddress.sin_family =  AF_INET;
/*    raddress.sin_addr.s_addr =  INADDR_ANY; */
    raddress.sin_port = serv_port;         /* server port */
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
	give_error("setsocketopt in make_server_socket");

    if (bind(s, (struct sockaddr *) &raddress, sizeof(struct sockaddr_in)))
	give_error("bind_socket");
    if (listen(s, 10) < 0) 
 	give_error("listen make_server_socket");
   return(s);
}


look_for_host(i,count)
int i,count;
{
struct hostent *hp;
extern struct sockaddr_in Host_addr;
extern struct hostent *gethostbyname();
int sock;

   printf("Establishing connection to workstation on host |%s|\n",ws[i].name);
   hp = gethostbyname(ws[i].name);
   if (hp == (struct hostent *) 0) give_error("gethostbyname");
   /* Get local host address */
   bzero((char *)&Host_addr, sizeof(Host_addr));
   bcopy(hp->h_addr, (char *)&Host_addr.sin_addr, hp->h_length);
   Host_addr.sin_family = AF_INET;
   Host_addr.sin_port = ws[i].adrs;
   printf("will accept %s at #%d\n",ws[i].name,ws[i].adrs);
   if ((sock=socket(AF_INET,SOCK_STREAM,0))<0) give_error("socket");
   while (connect(sock,(struct sockaddr *)&Host_addr,sizeof(Host_addr))<0);
   printf("%s connected %d = TRUE at socket %d\n",ws[i].name,i,sock);
   connected[i] = TRUE;
   who_head = insert(ws[i].name,who_head,sock,TCP);
   return(sock);
}



b4accepting(i,count)
int i,count;
{
    sock[i] = make_server_socket(ws[i].adrs);
    if (dont_block(sock[i]) < 0) perror("Creating non-blocking pilot socket");
    fprintf(stderr,"%s: B4listening, listening for %s at socket# %d.\n", 
               my_host_name,ws[i].name,ws[i].adrs);
}

accepting(i)
int i;
{
int g;
    g = accept(sock[i],0,0);  /* modifies a copied socket */
    if (g > 0) {
       sock[i] = g;
       fprintf(stderr,"%s: Connected at socket # %d: %s\n",
              progname,g,my_host_name);
       if (dont_block(sock[i])< 0) perror("Resetting non-blocking attributes");
       connected[i] = TRUE;
       who_head = insert(ws[i].name,who_head,sock[i],TCP);
       printf("connected  to proc %d= TRUE, %s uses socket %d\n",
                    i,ws[i].name,sock[i]);
       }
    else if ( g < 0 && errno != EWOULDBLOCK) {
            fprintf(stderr,"%s: Error connecting %s\n", progname,my_host_name);
            perror("accepting connection");
            }
	 else { sleep(1);
              printf("in never-never land?\n"); /*  Terminate(1);  */
              }
}


setup_sockets(count,vars)
int count;
char *vars[];
{
int length,msgsock, connecting=0;
struct sockaddr_in server;
int g,i,j,c, iterat = 0;
struct hostent *hp;
extern struct sockaddr_in Host_addr;
extern struct hostent *gethostbyname();
extern give_error();

    /* NOTE: all 'C' arrays are 0-based, but command-line args 1-based,
       hence arrays are indices are compensated for */

    last_ws = count;
    gethostname(my_host_name,HOST_NAME_LENGTH);
    printf("Hostname is %s of %d workstations\n",my_host_name, last_ws);

    for (i=0; i<last_ws; i++) 
        if (strcmp(ws[i].name,my_host_name)<0)
           b4accepting(i,count);
/*
    printf("\nHit 'C' to continue.\n");  while ('C' != getchar());
*/ 
    printf("Will start in 10 seconds....hurry up other machines!\n");
    sleep(10);
    /* Handle case of all < self, create and accept socks */
    while (connecting<last_ws) {
          iterat++;
          for (i=0; i<last_ws; i++) 
              if (!connected[i])
                 if ((strcmp(ws[i].name,my_host_name)<0)) {
		    /* printf("going to accepting\n"); */
                    accepting(i); 
                    if (connected[i]) connecting++;
	            }
                 else if (strcmp(ws[i].name,my_host_name)>0) {
			 /* printf("look for host\n"); */
                         sock[i]=look_for_host(i,count);
                         if (connected[i]) connecting++; else sleep(1);
			 }
          if (!(iterat%10000)) printf("can't form a connection\n"); 
          }
    printf("exiting setup sockets");
    fact_message.type = FACTS;
    fact_message.num_facts = 0;
}