aboutsummaryrefslogtreecommitdiff
path: root/audio/vat/files/patch-af
blob: 85e74ea804471625e4331b48fe59b57ae06e581e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
--- net.cc.orig	Thu Mar 21 03:49:18 1996
+++ net.cc	Sun Dec  3 19:04:01 2006
@@ -163,46 +163,49 @@
 {
 	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, savederrno;
+		socklen_t errlen = sizeof(err);
+
+		savederrno = errno;
+		getsockopt(fd, SOL_SOCKET, SO_ERROR, &err,
+			&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 +220,7 @@
 			 * 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 +267,15 @@
 	}
 	int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0);
 	if (cc < 0) {
-		switch (errno) {
+		int err, savederrno;
+		socklen_t errlen = sizeof(err);
+
+		savederrno = errno;
+		getsockopt(ssock_, SOL_SOCKET, SO_ERROR, &err,
+			&errlen);
+		switch (savederrno) {
 		case ECONNREFUSED:
 			/* no one listening at some site - ignore */
-#if defined(__osf__) || defined(_AIX)
-			reset();
-#endif
 			break;
 
 		case ENETUNREACH:
@@ -297,7 +303,7 @@
 int Network::dorecv(u_char* buf, int len, u_int32_t& from, int fd)
 {
 	sockaddr_in sfrom;
-	int fromlen = sizeof(sfrom);
+	socklen_t fromlen = sizeof(sfrom);
 	int cc = ::recvfrom(fd, (char*)buf, len, 0,
 			    (sockaddr*)&sfrom, &fromlen);
 	if (cc < 0) {