... | ... |
@@ -44,6 +44,7 @@ |
44 | 44 |
* 2003-08-21 check_self properly handles ipv6 addresses & refs (andrei) |
45 | 45 |
* 2003-10-21 check_self updated to handle proto (andrei) |
46 | 46 |
* 2003-10-24 converted to the new socket_info lists (andrei) |
47 |
+ * 2004-10-10 modified check_self to use grep_sock_info (andrei) |
|
47 | 48 |
*/ |
48 | 49 |
|
49 | 50 |
|
... | ... |
@@ -230,93 +231,9 @@ struct socket_info* get_send_socket(union sockaddr_union* to, int proto) |
230 | 231 |
*/ |
231 | 232 |
int check_self(str* host, unsigned short port, unsigned short proto) |
232 | 233 |
{ |
233 |
- char* hname; |
|
234 |
- int h_len; |
|
235 |
- struct socket_info* si; |
|
236 |
- unsigned short c_proto; |
|
237 |
-#ifdef USE_IPV6 |
|
238 |
- struct ip_addr* ip6; |
|
239 |
-#endif |
|
240 |
- |
|
241 |
- h_len=host->len; |
|
242 |
- hname=host->s; |
|
243 |
-#ifdef USE_IPV6 |
|
244 |
- if ((h_len>2)&&((*hname)=='[')&&(hname[h_len-1]==']')){ |
|
245 |
- /* ipv6 reference, skip [] */ |
|
246 |
- hname++; |
|
247 |
- h_len-=2; |
|
248 |
- } |
|
249 |
-#endif |
|
250 |
- c_proto=proto?proto:PROTO_UDP; |
|
251 |
- do{ |
|
252 |
- /* get the proper sock list */ |
|
253 |
- switch(c_proto){ |
|
254 |
- case PROTO_NONE: /* we'll use udp and not all the lists FIXME: */ |
|
255 |
- case PROTO_UDP: |
|
256 |
- si=udp_listen; |
|
257 |
- break; |
|
258 |
-#ifdef USE_TCP |
|
259 |
- case PROTO_TCP: |
|
260 |
- si=tcp_listen; |
|
261 |
- break; |
|
262 |
-#endif |
|
263 |
-#ifdef USE_TLS |
|
264 |
- case PROTO_TLS: |
|
265 |
- si=tls_listen; |
|
266 |
- break; |
|
267 |
-#endif |
|
268 |
- default: |
|
269 |
- /* unknown proto */ |
|
270 |
- LOG(L_WARN, "WARNING: check_self: " |
|
271 |
- "unknown proto %d\n", c_proto); |
|
272 |
- return 0; /* false */ |
|
273 |
- } |
|
274 |
- for (; si; si=si->next){ |
|
275 |
- DBG("check_self - checking if host==us: %d==%d && " |
|
276 |
- " [%.*s] == [%.*s]\n", |
|
277 |
- h_len, |
|
278 |
- si->name.len, |
|
279 |
- h_len, hname, |
|
280 |
- si->name.len, si->name.s |
|
281 |
- ); |
|
282 |
- if (port) { |
|
283 |
- DBG("check_self - checking if port %d matches port %d\n", |
|
284 |
- si->port_no, port); |
|
285 |
- if (si->port_no!=port) { |
|
286 |
- continue; |
|
287 |
- } |
|
288 |
- } |
|
289 |
- if ( (h_len==si->name.len) && |
|
290 |
- (strncasecmp(hname, si->name.s, |
|
291 |
- si->name.len)==0) /*slower*/) |
|
292 |
- /* comp. must be case insensitive, host names |
|
293 |
- * can be written in mixed case, it will also match |
|
294 |
- * ipv6 addresses if we are lucky*/ |
|
295 |
- goto found; |
|
296 |
- /* check if host == ip address */ |
|
297 |
-#ifdef USE_IPV6 |
|
298 |
- /* ipv6 case is uglier, host can be [3ffe::1] */ |
|
299 |
- ip6=str2ip6(host); |
|
300 |
- if (ip6){ |
|
301 |
- if (ip_addr_cmp(ip6, &si->address)) |
|
302 |
- goto found; /* match */ |
|
303 |
- else |
|
304 |
- continue; /* no match, but this is an ipv6 address |
|
305 |
- so no point in trying ipv4 */ |
|
306 |
- } |
|
307 |
-#endif |
|
308 |
- /* ipv4 */ |
|
309 |
- if ( (!(si->flags&SI_IS_IP)) && |
|
310 |
- (h_len==si->address_str.len) && |
|
311 |
- (memcmp(hname, si->address_str.s, |
|
312 |
- si->address_str.len)==0) |
|
313 |
- ) |
|
314 |
- goto found; |
|
315 |
- } |
|
316 |
- }while( (proto==0) && (c_proto=next_proto(c_proto)) ); |
|
317 |
- |
|
234 |
+ if (grep_sock_info(host, port, proto)) goto found; |
|
318 | 235 |
/* try to look into the aliases*/ |
319 |
- if (grep_aliases(hname, h_len, port, proto)==0){ |
|
236 |
+ if (grep_aliases(host->s, host->len, port, proto)==0){ |
|
320 | 237 |
DBG("check_self: host != me\n"); |
321 | 238 |
return 0; |
322 | 239 |
} |
... | ... |
@@ -59,6 +59,13 @@ static inline int grep_aliases(char* name, int len, unsigned short port, |
59 | 59 |
{ |
60 | 60 |
struct host_alias* a; |
61 | 61 |
|
62 |
+#ifdef USE_IPV6 |
|
63 |
+ if ((len>2)&&((*name)=='[')&&(name[len-1]==']')){ |
|
64 |
+ /* ipv6 reference, skip [] */ |
|
65 |
+ name++; |
|
66 |
+ len-=2; |
|
67 |
+ } |
|
68 |
+#endif |
|
62 | 69 |
for(a=aliases;a;a=a->next) |
63 | 70 |
if ((a->alias.len==len) && ((a->port==0) || (port==0) || |
64 | 71 |
(a->port==port)) && ((a->proto==0) || (proto==0) || |
... | ... |
@@ -32,6 +32,7 @@ |
32 | 32 |
* History: |
33 | 33 |
* -------- |
34 | 34 |
* 2003-10-22 created by andrei |
35 |
+ * 2004-10-10 added grep_sock_info (andrei) |
|
35 | 36 |
*/ |
36 | 37 |
|
37 | 38 |
|
... | ... |
@@ -185,6 +186,99 @@ static struct socket_info** get_sock_info_list(unsigned short proto) |
185 | 186 |
|
186 | 187 |
|
187 | 188 |
|
189 |
+/* checks if the proto: host:port is one of the address we listen on |
|
190 |
+ * and returns the corresponding socket_info structure. |
|
191 |
+ * if port==0, the port number is ignored |
|
192 |
+ * if proto==0 (PROTO_NONE) the protocol is ignored |
|
193 |
+ * returns 0 if not found |
|
194 |
+ * WARNING: uses str2ip6 so it will overwrite any previous |
|
195 |
+ * unsaved result of this function (static buffer) |
|
196 |
+ */ |
|
197 |
+struct socket_info* grep_sock_info(str* host, unsigned short port, |
|
198 |
+ unsigned short proto) |
|
199 |
+{ |
|
200 |
+ char* hname; |
|
201 |
+ int h_len; |
|
202 |
+ struct socket_info* si; |
|
203 |
+ struct socket_info** list; |
|
204 |
+ unsigned short c_proto; |
|
205 |
+#ifdef USE_IPV6 |
|
206 |
+ struct ip_addr* ip6; |
|
207 |
+#endif |
|
208 |
+ |
|
209 |
+ h_len=host->len; |
|
210 |
+ hname=host->s; |
|
211 |
+#ifdef USE_IPV6 |
|
212 |
+ if ((h_len>2)&&((*hname)=='[')&&(hname[h_len-1]==']')){ |
|
213 |
+ /* ipv6 reference, skip [] */ |
|
214 |
+ hname++; |
|
215 |
+ h_len-=2; |
|
216 |
+ } |
|
217 |
+#endif |
|
218 |
+ c_proto=proto?proto:PROTO_UDP; |
|
219 |
+ do{ |
|
220 |
+ /* get the proper sock_list */ |
|
221 |
+ if (c_proto==PROTO_NONE) |
|
222 |
+ list=&udp_listen; |
|
223 |
+ else |
|
224 |
+ list=get_sock_info_list(c_proto); |
|
225 |
+ |
|
226 |
+ if (list==0){ |
|
227 |
+ LOG(L_WARN, "WARNING: grep_sock_info: " |
|
228 |
+ "unknown proto %d\n", c_proto); |
|
229 |
+ goto not_found; /* false */ |
|
230 |
+ } |
|
231 |
+ for (si=*list; si; si=si->next){ |
|
232 |
+ DBG("grep_sock_info - checking if host==us: %d==%d && " |
|
233 |
+ " [%.*s] == [%.*s]\n", |
|
234 |
+ h_len, |
|
235 |
+ si->name.len, |
|
236 |
+ h_len, hname, |
|
237 |
+ si->name.len, si->name.s |
|
238 |
+ ); |
|
239 |
+ if (port) { |
|
240 |
+ DBG("grep_sock_info - checking if port %d matches port %d\n", |
|
241 |
+ si->port_no, port); |
|
242 |
+ if (si->port_no!=port) { |
|
243 |
+ continue; |
|
244 |
+ } |
|
245 |
+ } |
|
246 |
+ if ( (h_len==si->name.len) && |
|
247 |
+ (strncasecmp(hname, si->name.s, |
|
248 |
+ si->name.len)==0) /*slower*/) |
|
249 |
+ /* comp. must be case insensitive, host names |
|
250 |
+ * can be written in mixed case, it will also match |
|
251 |
+ * ipv6 addresses if we are lucky*/ |
|
252 |
+ goto found; |
|
253 |
+ /* check if host == ip address */ |
|
254 |
+#ifdef USE_IPV6 |
|
255 |
+ /* ipv6 case is uglier, host can be [3ffe::1] */ |
|
256 |
+ ip6=str2ip6(host); |
|
257 |
+ if (ip6){ |
|
258 |
+ if (ip_addr_cmp(ip6, &si->address)) |
|
259 |
+ goto found; /* match */ |
|
260 |
+ else |
|
261 |
+ continue; /* no match, but this is an ipv6 address |
|
262 |
+ so no point in trying ipv4 */ |
|
263 |
+ } |
|
264 |
+#endif |
|
265 |
+ /* ipv4 */ |
|
266 |
+ if ( (!(si->flags&SI_IS_IP)) && |
|
267 |
+ (h_len==si->address_str.len) && |
|
268 |
+ (memcmp(hname, si->address_str.s, |
|
269 |
+ si->address_str.len)==0) |
|
270 |
+ ) |
|
271 |
+ goto found; |
|
272 |
+ } |
|
273 |
+ }while( (proto==0) && (c_proto=next_proto(c_proto)) ); |
|
274 |
+not_found: |
|
275 |
+ return 0; |
|
276 |
+found: |
|
277 |
+ return si; |
|
278 |
+} |
|
279 |
+ |
|
280 |
+ |
|
281 |
+ |
|
188 | 282 |
/* adds a new sock_info structure to the corresponding list |
189 | 283 |
* return 0 on success, -1 on error */ |
190 | 284 |
int new_sock2list(char* name, unsigned short port, unsigned short proto, |
... | ... |
@@ -57,6 +57,8 @@ int fix_all_socket_lists(); |
57 | 57 |
void print_all_socket_lists(); |
58 | 58 |
void print_aliases(); |
59 | 59 |
|
60 |
+struct socket_info* grep_sock_info(str* host, unsigned short port, |
|
61 |
+ unsigned short proto); |
|
60 | 62 |
|
61 | 63 |
/* helper function: |
62 | 64 |
* returns next protocol, if the last one is reached return 0 |
... | ... |
@@ -108,5 +110,4 @@ inline static struct socket_info* get_first_socket() |
108 | 110 |
} |
109 | 111 |
|
110 | 112 |
|
111 |
- |
|
112 | 113 |
#endif |