$OpenBSD: patch-net_cc,v 1.1 2001/07/30 15:33:22 espie Exp $
--- net.cc.orig	Thu Mar 21 12:49:18 1996
+++ net.cc	Mon Jul 30 17:25:38 2001
@@ -163,46 +163,48 @@ void Network::dosend(u_char* buf, int le
 {
 	int cc = ::send(fd, (char*)buf, len, 0);
 	if (cc < 0) {
-		switch (errno) {
+		/*
+		 * 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 */
-#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:
@@ -217,7 +219,7 @@ void Network::dosend(u_char* buf, int le
 			 * icmp unreachable, so we should be able to
 			 * send now.
 			 */
-			(void)::send(ssock_, (char*)buf, len, 0);
+			(void)::send(fd, (char*)buf, len, 0);
 			break;
 
 		default:
@@ -264,12 +266,14 @@ void Network::sendmsg(const msghdr& mh)
 	}
 	int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0);
 	if (cc < 0) {
-		switch (errno) {
+		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 */
-#if defined(__osf__) || defined(_AIX)
-			reset();
-#endif
 			break;
 
 		case ENETUNREACH:
@@ -299,7 +303,7 @@ int Network::dorecv(u_char* buf, int len
 	sockaddr_in sfrom;
 	int fromlen = sizeof(sfrom);
 	int cc = ::recvfrom(fd, (char*)buf, len, 0,
-			    (sockaddr*)&sfrom, &fromlen);
+			    (sockaddr*)&sfrom, (socklen_t *) &fromlen);
 	if (cc < 0) {
 		if (errno != EWOULDBLOCK)
 			perror("recvfrom");
