@@ -83,6 +83,7 @@ extern StatBag S;
83
83
#define GEN_IP_PKTINFO IP_RECVDSTADDR
84
84
#endif
85
85
86
+ vector<ComboAddress> g_localaddresses;
86
87
87
88
void UDPNameserver::bindIPv4 ()
88
89
{
@@ -95,7 +96,7 @@ void UDPNameserver::bindIPv4()
95
96
int s;
96
97
for (vector<string>::const_iterator i=locals.begin ();i!=locals.end ();++i) {
97
98
string localname (*i);
98
- struct sockaddr_in locala;
99
+ ComboAddress locala;
99
100
100
101
s=socket (AF_INET,SOCK_DGRAM,0 );
101
102
@@ -108,12 +109,12 @@ void UDPNameserver::bindIPv4()
108
109
throw AhuException (" Unable to set UDP socket to non-blocking: " +stringerror ());
109
110
110
111
memset (&locala,0 ,sizeof (locala));
111
- locala.sin_family =AF_INET;
112
+ locala.sin4 . sin_family =AF_INET;
112
113
113
114
if (localname==" 0.0.0.0" ) {
114
115
int val=1 ;
115
116
setsockopt (s, IPPROTO_IP, GEN_IP_PKTINFO, &val, sizeof (val));
116
- locala.sin_addr .s_addr = INADDR_ANY;
117
+ locala.sin4 . sin_addr .s_addr = INADDR_ANY;
117
118
}
118
119
else
119
120
{
@@ -122,17 +123,17 @@ void UDPNameserver::bindIPv4()
122
123
if (!h)
123
124
throw AhuException (" Unable to resolve local address" );
124
125
125
- locala.sin_addr .s_addr =*(int *)h->h_addr ;
126
+ locala.sin4 . sin_addr .s_addr =*(int *)h->h_addr ;
126
127
}
127
128
128
- locala.sin_port =htons (::arg ().asNum (" local-port" ));
129
-
130
- if (::bind (s, (sockaddr*)&locala,sizeof ( locala))< 0 ) {
131
- L<<Logger::Error<<" binding UDP socket to '" +localname+" ' port " +lexical_cast<string>(ntohs (locala.sin_port ))+" : " <<strerror (errno)<<endl;
129
+ locala.sin4 . sin_port =htons (::arg ().asNum (" local-port" ));
130
+ g_localaddresses. push_back (locala);
131
+ if (::bind (s, (sockaddr*)&locala, locala. getSocklen ()) < 0 ) {
132
+ L<<Logger::Error<<" binding UDP socket to '" +localname+" ' port " +lexical_cast<string>(ntohs (locala.sin4 . sin_port ))+" : " <<strerror (errno)<<endl;
132
133
throw AhuException (" Unable to bind to UDP socket" );
133
134
}
134
135
d_sockets.push_back (s);
135
- L<<Logger::Error<<" UDP server bound to " <<inet_ntoa (locala.sin_addr )<<" :" <<::arg ().asNum (" local-port" )<<endl;
136
+ L<<Logger::Error<<" UDP server bound to " <<inet_ntoa (locala.sin4 . sin_addr )<<" :" <<::arg ().asNum (" local-port" )<<endl;
136
137
struct pollfd pfd;
137
138
pfd.fd = s;
138
139
pfd.events = POLLIN;
@@ -151,6 +152,40 @@ static bool IsAnyAddress(const ComboAddress& addr)
151
152
return false ;
152
153
}
153
154
155
+
156
+ bool AddressIsUs (const ComboAddress& remote)
157
+ {
158
+ BOOST_FOREACH (const ComboAddress& us, g_localaddresses) {
159
+ if (remote == us)
160
+ return true ;
161
+ if (IsAnyAddress (us)) {
162
+ int s = socket (AF_INET, SOCK_DGRAM, 0 );
163
+ if (s < 0 )
164
+ continue ;
165
+
166
+ if (connect (s, (struct sockaddr *)&remote, remote.getSocklen ()) < 0 ) {
167
+ close (s);
168
+ continue ;
169
+ }
170
+
171
+ ComboAddress actualLocal;
172
+ actualLocal.sin4 .sin_family = remote.sin4 .sin_family ;
173
+ socklen_t socklen = actualLocal.getSocklen ();
174
+
175
+ if (getsockname (s, (struct sockaddr *) &actualLocal, &socklen) < 0 ) {
176
+ close (s);
177
+ continue ;
178
+ }
179
+ close (s);
180
+ actualLocal.sin4 .sin_port = us.sin4 .sin_port ;
181
+ if (actualLocal == remote)
182
+ return true ;
183
+ }
184
+ }
185
+ return false ;
186
+ }
187
+
188
+
154
189
void UDPNameserver::bindIPv6 ()
155
190
{
156
191
#if !WIN32 && HAVE_IPV6
@@ -178,7 +213,7 @@ void UDPNameserver::bindIPv6()
178
213
setsockopt (s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof (val));
179
214
setsockopt (s, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof (val)); // if this fails, we report an error in tcpreceiver too
180
215
}
181
-
216
+ g_localaddresses. push_back (locala);
182
217
if (::bind (s, (sockaddr*)&locala, sizeof (locala))<0 ) {
183
218
L<<Logger::Error<<" binding to UDP ipv6 socket: " <<strerror (errno)<<endl;
184
219
throw AhuException (" Unable to bind to UDP ipv6 socket" );
0 commit comments