*** net.cc.orig	Thu Mar 21 06:49:18 1996
--- net.cc	Thu Jul 15 16:43:56 1999
***************
*** 163,208 ****
  {
  	int cc = ::send(fd, (char*)buf, len, 0);
  	if (cc < 0) {
! 		switch (errno) {
  		case ECONNREFUSED:
  			/* no one listening at some site - ignore */
- #if defined(__osf__) || defined(_AIX)
- 			/*
- 			 * Due to a bug in kern/uipc_socket.c, on several
- 			 * systems, datagram sockets incorrectly persist
- 			 * in an error state on receipt of an ICMP
- 			 * port-unreachable.  This causes unicast connection
- 			 * rendezvous problems, and worse, multicast
- 			 * transmission problems because several systems
- 			 * incorrectly send port unreachables for 
- 			 * multicast destinations.  Our work around
- 			 * is to simply close and reopen the socket
- 			 * (by calling reset() below).
- 			 *
- 			 * This bug originated at CSRG in Berkeley
- 			 * and was present in the BSD Reno networking
- 			 * code release.  It has since been fixed
- 			 * in 4.4BSD and OSF-3.x.  It is know to remain
- 			 * in AIX-4.1.3.
- 			 *
- 			 * A fix is to change the following lines from
- 			 * kern/uipc_socket.c:
- 			 *
- 			 *	if (so_serror)
- 			 *		snderr(so->so_error);
- 			 *
- 			 * to:
- 			 *
- 			 *	if (so->so_error) {
- 			 * 		error = so->so_error;
- 			 *		so->so_error = 0;
- 			 *		splx(s);
- 			 *		goto release;
- 			 *	}
- 			 *
- 			 */
- 			reset();
- #endif
  			break;
  
  		case ENETUNREACH:
--- 163,210 ----
  {
  	int cc = ::send(fd, (char*)buf, len, 0);
  	if (cc < 0) {
! 		/*
! 		 * Due to a bug in kern/uipc_socket.c, on several
! 		 * systems, datagram sockets incorrectly persist
! 		 * in an error state on receipt of any ICMP
! 		 * error.  This causes unicast connection
! 		 * rendezvous problems, and worse, multicast
! 		 * transmission problems because several systems
! 		 * incorrectly send port unreachables for 
! 		 * multicast destinations.  Our work around
! 		 * is to call getsockopt(..., SO_ERROR, ...)
! 		 * which resets so->so_error.
! 		 *
! 		 * This bug originated at CSRG in Berkeley
! 		 * and was present in the BSD Reno networking
! 		 * code release.  It has since been fixed
! 		 * in OSF-3.x.  It is know to remain
! 		 * in 4.4BSD and AIX-4.1.3.
! 		 *
! 		 * A fix is to change the following lines from
! 		 * kern/uipc_socket.c:
! 		 *
! 		 *	if (so_serror)
! 		 *		snderr(so->so_error);
! 		 *
! 		 * to:
! 		 *
! 		 *	if (so->so_error) {
! 		 * 		error = so->so_error;
! 		 *		so->so_error = 0;
! 		 *		splx(s);
! 		 *		goto release;
! 		 *	}
! 		 *
! 		 */
! 		int err, errlen = sizeof(err), savederrno;
! 
! 		savederrno = errno;
! 		getsockopt(fd, SOL_SOCKET, SO_ERROR, &err,
! 			(socklen_t *) &errlen);
! 		switch (savederrno) {
  		case ECONNREFUSED:
  			/* no one listening at some site - ignore */
  			break;
  
  		case ENETUNREACH:
***************
*** 217,223 ****
  			 * icmp unreachable, so we should be able to
  			 * send now.
  			 */
! 			(void)::send(ssock_, (char*)buf, len, 0);
  			break;
  
  		default:
--- 219,225 ----
  			 * icmp unreachable, so we should be able to
  			 * send now.
  			 */
! 			(void)::send(fd, (char*)buf, len, 0);
  			break;
  
  		default:
***************
*** 264,275 ****
  	}
  	int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0);
  	if (cc < 0) {
! 		switch (errno) {
  		case ECONNREFUSED:
  			/* no one listening at some site - ignore */
- #if defined(__osf__) || defined(_AIX)
- 			reset();
- #endif
  			break;
  
  		case ENETUNREACH:
--- 266,279 ----
  	}
  	int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0);
  	if (cc < 0) {
! 		int err, errlen = sizeof(err), savederrno;
! 
! 		savederrno = errno;
! 		getsockopt(ssock_, SOL_SOCKET, SO_ERROR, &err,
! 			(socklen_t *) &errlen);
! 		switch (savederrno) {
  		case ECONNREFUSED:
  			/* no one listening at some site - ignore */
  			break;
  
  		case ENETUNREACH:
***************
*** 299,305 ****
  	sockaddr_in sfrom;
  	int fromlen = sizeof(sfrom);
  	int cc = ::recvfrom(fd, (char*)buf, len, 0,
! 			    (sockaddr*)&sfrom, &fromlen);
  	if (cc < 0) {
  		if (errno != EWOULDBLOCK)
  			perror("recvfrom");
--- 303,309 ----
  	sockaddr_in sfrom;
  	int fromlen = sizeof(sfrom);
  	int cc = ::recvfrom(fd, (char*)buf, len, 0,
! 			    (sockaddr*)&sfrom, (socklen_t *) &fromlen);
  	if (cc < 0) {
  		if (errno != EWOULDBLOCK)
  			perror("recvfrom");
