Browse code

core/forward.c Fixed mhomed behavior.

As connect() dones't re-bound a UDP sock if the socket is already
bound to an interface, first unbind the socket by connecting to AF_UNSPEC

Marius Zbihlei authored on 04/11/2010 14:11:41
Showing 1 changed files
... ...
@@ -131,6 +131,10 @@ struct socket_info* get_out_socket(union sockaddr_union* to, int proto)
131 131
 	union sockaddr_union from; 
132 132
 	struct socket_info* si;
133 133
 	struct ip_addr ip;
134
+	union sockaddr_union uncon;
135
+
136
+	memset(&uncon, 0, sizeof(union sockaddr_union));
137
+	uncon.sin.sin_family = AF_UNSPEC;
134 138
 
135 139
 	if (unlikely(proto!=PROTO_UDP)) {
136 140
 		LOG(L_CRIT, "BUG: get_out_socket can only be called for UDP\n");
... ...
@@ -167,6 +171,14 @@ retry:
167 167
 		return 0;
168 168
 	}
169 169
 	}
170
+
171
+	if( !mhomed_sock_cache_disabled ){
172
+		/* some Linux kernel versions (all?) along with other UNIXes don't re-bound the sock if already bound */
173
+		/* to un-bound a socket set sin_family to AF_UNSPEC and zero out the rest*/
174
+		if (unlikely(connect(*temp_sock, &uncon.s, sockaddru_len(uncon))) < 0)
175
+				mhomed_sock_cache_disabled = 1;
176
+	}
177
+
170 178
 	if (unlikely(connect(*temp_sock, &to->s, sockaddru_len(*to))==-1)) {
171 179
 		if (unlikely(errno==EISCONN && !mhomed_sock_cache_disabled)){
172 180
 			/*  no multiple connects support on the same socket */