Problem with 4.2BSD talk

Chuck Privitera crp at ccivax.UUCP
Wed Nov 14 06:33:05 AEST 1984


Index:	src/ucb/talk/get_addrs.c 4.2BSD/(2.9BSD?)

Description:
	This is actually a follow up to article <1311 at dalcs.UUCP>.
	The subject was "TCP/IP Communications Problem" and was
	posted to net.unix-wizards. I wanted to change the subject
	(to be more informative) and post this reply to a more
	appropriate news group. Anyways, here goes. When using
	the software loopback network interface as your primary
	network, talk can't communicate with foreign hosts.
Repeat-by:
	Make the loopback interface your primary network,
	then try to talk to a user on another machine.
	(via ethernet, harvard's itt interface, rick
	 adam's serial line interface, or whatever).
	 Talk will (appear to) hang with the message:

	 "Checking for invitation on caller's machine."
Fix:
	Talk isn't really hung. It is actually waiting for
	a response from the foreign host. Well, the foreign
	host will never be able to respond. The problem is
	that talk sends a "control" packet to the remote
	talk daemon which contains (among other things) the
	address of the remote talk's socket (who is on the
	loopback network). So, the foreign host receives
	the control packets correctly, but when it tries
	to respond (by writing to the address supplied in
	the packet it just received), the response gets
	swallowed by the loopback driver on the foreign host!!
	What I did to fix it was to have talk find out the
	name of the network it will be using, and if the
	user being "talked to" is on another machine,
	make sure the network name doesn't start with "loop".
	Sort of kludgy I know, but the loopback interface is
	the only one that doesn't allow inter-machine communication,
	and 4.2 is distributed with "loopback-net" in /etc/networks,
	so ....
		To fix talk, apply the changes in this context diff
	to get_addrs.c, and add the local host name to the alias list
	for the network you really want talk to use.

rcsdiff -c3 -r1.1 get_addrs.c
RCS file: RCS/get_addrs.c,v
retrieving revision 1.1
diff -c3 -r1.1 get_addrs.c
*** /tmp/,RCSt1008987	Tue Nov 13 15:28:38 1984
--- get_addrs.c	Tue Nov 13 15:23:06 1984
***************
*** 1,4
! /* $Header: get_addrs.c,v 1.1 84/04/06 15:16:21 root Rel $ */
  
  #include "talk_ctl.h"
  

--- 1,4 -----
! /* $Header: get_addrs.c,v 1.3 84/11/13 15:22:12 root Exp $ */
  
  #include "talk_ctl.h"
  
***************
*** 9,15
  char *my_machine_name;
  char *his_machine_name;
  {
!     struct hostent *hp;
      struct servent *sp;
  
      msg.pid = getpid();

--- 9,15 -----
  char *my_machine_name;
  char *his_machine_name;
  {
!     struct hostent *hp, *p; 
      struct servent *sp;
      struct netent  *np;
      char **cp;
***************
*** 11,16
  {
      struct hostent *hp;
      struct servent *sp;
  
      msg.pid = getpid();
  

--- 11,18 -----
  {
      struct hostent *hp, *p; 
      struct servent *sp;
+     struct netent  *np;
+     char **cp;
  
      msg.pid = getpid();
  
***************
*** 16,23
  
  	/* look up the address of the local host */
  
!     hp = gethostbyname(my_machine_name);
! 
      if (hp == (struct hostent *) 0) {
  	printf("This machine doesn't exist. Boy, am I confused!\n");
  	exit(-1);

--- 18,39 -----
  
  	/* look up the address of the local host */
  
!     sethostent(1);	/* Don't rewind hosts file */
! again:
!     while(p = gethostent()) {
! 	if (strcmp(p->h_name, my_machine_name) == 0)
! 		break;
! 	for(cp = p->h_aliases; *cp != 0; cp++)
! 		if (strcmp(*cp, my_machine_name) == 0)
! 			goto found;
!     }
! found:
!     if (hp && !p) {
! 	printf("No suitable network for %s to talk to %s on.\n",
! 		my_machine_name, his_machine_name);
! 	exit(-1);
!     }
!     hp = p;
      if (hp == (struct hostent *) 0) {
  	printf("This machine doesn't exist. Boy, am I confused!\n");
  	exit(-1);
***************
*** 29,34
      }
  
      bcopy(hp->h_addr, (char *)&my_machine_addr, hp->h_length);
  
  	/* if he is on the same machine, then simply copy */
  

--- 45,51 -----
      }
  
      bcopy(hp->h_addr, (char *)&my_machine_addr, hp->h_length);
+     np = getnetbyaddr(inet_netof(my_machine_addr), AF_INET);
  
  	/* if he is on the same machine, then simply copy */
  
***************
*** 37,42
  	bcopy((char *)&my_machine_addr, (char *)&his_machine_addr,
  		sizeof(his_machine_name));
      } else {
  
  	/* look up the address of the recipient's machine */
  

--- 54,69 -----
  	bcopy((char *)&my_machine_addr, (char *)&his_machine_addr,
  		sizeof(his_machine_name));
      } else {
+ 
+ 	/*
+ 	 * Don't try to talk to a remote machine on
+ 	 * the loopback network.
+ 	 */
+ 
+ #define min(a, b)	(a < b ? a : b)
+ 
+ 	if (np && !bcmp(np->n_name, "loop", min(strlen(np->name), 4)))
+ 		goto again;
  
  	/* look up the address of the recipient's machine */



More information about the Comp.bugs.2bsd mailing list