Changeset 736 for branches/samba-3.5.x/source3/libsmb/namequery.c
- Timestamp:
- Nov 12, 2012, 5:38:52 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.5.x/source3/libsmb/namequery.c
r414 r736 572 572 "looking for duplicate address/port pairs\n")); 573 573 574 /* one loop to remove duplicates*/574 /* One loop to set duplicates to a zero addr. */ 575 575 for ( i=0; i<count; i++ ) { 576 576 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) { … … 586 586 } 587 587 588 /* one loop to clean up any holes we left */ 589 /* first ip should never be a zero_ip() */ 590 for (i = 0; i<count; ) { 591 if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) { 592 if (i != count-1) { 593 memmove(&iplist[i], &iplist[i+1], 594 (count - i - 1)*sizeof(iplist[i])); 588 /* Now remove any addresses set to zero above. */ 589 for (i = 0; i < count; i++) { 590 while (i < count && 591 is_zero_addr((struct sockaddr *)&iplist[i].ss)) { 592 if (count-i-1>0) { 593 memmove(&iplist[i], 594 &iplist[i+1], 595 (count-i-1)*sizeof(struct ip_service)); 595 596 } 596 597 count--; 597 continue; 598 } 599 i++; 598 } 600 599 } 601 600 … … 850 849 851 850 /******************************************************** 852 convert an array if struct sockaddr_storage to struct ip_service851 Convert an array if struct sockaddr_storage to struct ip_service 853 852 return false on failure. Port is set to PORT_NONE; 853 pcount is [in/out] - it is the length of ss_list on input, 854 and the length of return_iplist on output as we remove any 855 zero addresses from ss_list. 854 856 *********************************************************/ 855 857 856 858 static bool convert_ss2service(struct ip_service **return_iplist, 857 859 const struct sockaddr_storage *ss_list, 858 int count)860 int *pcount) 859 861 { 860 862 int i; 861 862 if ( count==0 || !ss_list ) 863 int orig_count = *pcount; 864 int real_count = 0; 865 866 if (orig_count==0 || !ss_list ) 863 867 return False; 864 868 869 /* Filter out zero addrs. */ 870 for ( i=0; i<orig_count; i++ ) { 871 if (is_zero_addr((struct sockaddr *)&ss_list[i])) { 872 continue; 873 } 874 real_count++; 875 } 876 if (real_count==0) { 877 return false; 878 } 879 865 880 /* copy the ip address; port will be PORT_NONE */ 866 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==881 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, real_count)) == 867 882 NULL) { 868 883 DEBUG(0,("convert_ip2service: malloc failed " 869 "for %d enetries!\n", count ));884 "for %d enetries!\n", real_count )); 870 885 return False; 871 886 } 872 887 873 for ( i=0; i<count; i++ ) { 874 (*return_iplist)[i].ss = ss_list[i]; 875 (*return_iplist)[i].port = PORT_NONE; 876 } 877 888 for ( i=0, real_count = 0; i<orig_count; i++ ) { 889 if (is_zero_addr((struct sockaddr *)&ss_list[i])) { 890 continue; 891 } 892 (*return_iplist)[real_count].ss = ss_list[i]; 893 (*return_iplist)[real_count].port = PORT_NONE; 894 real_count++; 895 } 896 897 *pcount = real_count; 878 898 return true; 879 899 } … … 948 968 949 969 status = NT_STATUS_OK; 950 if (!convert_ss2service(return_iplist, ss_list, *return_count) )970 if (!convert_ss2service(return_iplist, ss_list, return_count) ) 951 971 status = NT_STATUS_INVALID_PARAMETER; 952 972 … … 1083 1103 1084 1104 status = NT_STATUS_OK; 1085 if (!convert_ss2service(return_iplist, ss_list, *return_count))1105 if (!convert_ss2service(return_iplist, ss_list, return_count)) 1086 1106 status = NT_STATUS_INVALID_PARAMETER; 1087 1107 … … 1231 1251 memcpy(&ss, res->ai_addr, res->ai_addrlen); 1232 1252 1253 if (is_zero_addr((struct sockaddr *)&ss)) { 1254 continue; 1255 } 1256 1233 1257 *return_count += 1; 1234 1258 … … 1264 1288 int *return_count) 1265 1289 { 1266 int i , j;1290 int i; 1267 1291 NTSTATUS status; 1268 1292 TALLOC_CTX *ctx; … … 1313 1337 1314 1338 for (i=0;i<numdcs;i++) { 1315 numaddrs += MAX(dcs[i].num_ips,1); 1339 if (!dcs[i].ss_s) { 1340 numaddrs += 1; 1341 } else { 1342 numaddrs += dcs[i].num_ips; 1343 } 1316 1344 } 1317 1345 … … 1327 1355 1328 1356 *return_count = 0; 1329 i = 0; 1330 j = 0; 1331 while ( i < numdcs && (*return_count<numaddrs) ) { 1332 struct ip_service *r = &(*return_iplist)[*return_count]; 1333 1334 r->port = dcs[i].port; 1335 1336 /* If we don't have an IP list for a name, lookup it up */ 1337 1357 1358 for (i = 0; i < numdcs; i++) { 1359 /* If we don't have an IP list for a name, look it up */ 1338 1360 if (!dcs[i].ss_s) { 1339 interpret_string_addr(&r->ss, dcs[i].hostname, 0); 1340 i++; 1341 j = 0; 1361 /* We need to get all IP addresses here. */ 1362 struct addrinfo *res = NULL; 1363 struct addrinfo *p; 1364 int extra_addrs = 0; 1365 1366 if (!interpret_string_addr_internal(&res, 1367 dcs[i].hostname, 1368 0)) { 1369 continue; 1370 } 1371 /* Add in every IP from the lookup. How 1372 many is that ? */ 1373 for (p = res; p; p = p->ai_next) { 1374 if (is_zero_addr((struct sockaddr *)p->ai_addr)) { 1375 continue; 1376 } 1377 extra_addrs++; 1378 } 1379 if (extra_addrs > 1) { 1380 /* We need to expand the return_iplist array 1381 as we only budgeted for one address. */ 1382 numaddrs += (extra_addrs-1); 1383 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist, 1384 struct ip_service, 1385 numaddrs); 1386 if (*return_iplist == NULL) { 1387 if (res) { 1388 freeaddrinfo(res); 1389 } 1390 talloc_destroy(ctx); 1391 return NT_STATUS_NO_MEMORY; 1392 } 1393 } 1394 for (p = res; p; p = p->ai_next) { 1395 (*return_iplist)[*return_count].port = dcs[i].port; 1396 memcpy(&(*return_iplist)[*return_count].ss, 1397 p->ai_addr, 1398 p->ai_addrlen); 1399 if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) { 1400 continue; 1401 } 1402 (*return_count)++; 1403 /* Should never happen, but still... */ 1404 if (*return_count>=numaddrs) { 1405 break; 1406 } 1407 } 1408 if (res) { 1409 freeaddrinfo(res); 1410 } 1342 1411 } else { 1343 /* use the IP addresses from the SRV sresponse */ 1344 1345 if ( j >= dcs[i].num_ips ) { 1346 i++; 1347 j = 0; 1348 continue; 1349 } 1350 1351 r->ss = dcs[i].ss_s[j]; 1352 j++; 1353 } 1354 1355 /* make sure it is a valid IP. I considered checking the 1356 * negative connection cache, but this is the wrong place 1357 * for it. Maybe only as a hack. After think about it, if 1358 * all of the IP addresses returned from DNS are dead, what 1359 * hope does a netbios name lookup have ? The standard reason 1360 * for falling back to netbios lookups is that our DNS server 1361 * doesn't know anything about the DC's -- jerry */ 1362 1363 if (!is_zero_addr((struct sockaddr *)&r->ss)) { 1364 (*return_count)++; 1412 /* use all the IP addresses from the SRV sresponse */ 1413 int j; 1414 for (j = 0; j < dcs[i].num_ips; j++) { 1415 (*return_iplist)[*return_count].port = dcs[i].port; 1416 (*return_iplist)[*return_count].ss = dcs[i].ss_s[j]; 1417 if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) { 1418 continue; 1419 } 1420 (*return_count)++; 1421 /* Should never happen, but still... */ 1422 if (*return_count>=numaddrs) { 1423 break; 1424 } 1425 } 1365 1426 } 1366 1427 } … … 1419 1480 return NT_STATUS_INVALID_PARAMETER; 1420 1481 } 1482 if (is_zero_addr((struct sockaddr *)&(*return_iplist)->ss)) { 1483 SAFE_FREE(*return_iplist); 1484 return NT_STATUS_UNSUCCESSFUL; 1485 } 1421 1486 *return_count = 1; 1422 1487 return NT_STATUS_OK; … … 1426 1491 1427 1492 if (namecache_fetch(name, name_type, return_iplist, return_count)) { 1493 *return_count = remove_duplicate_addrs2(*return_iplist, 1494 *return_count ); 1428 1495 /* This could be a negative response */ 1429 1496 if (*return_count > 0) { … … 1520 1587 the iplist when the PDC is down will cause two sets of timeouts. */ 1521 1588 1522 if ( *return_count ) { 1523 *return_count = remove_duplicate_addrs2(*return_iplist, 1524 *return_count ); 1525 } 1589 *return_count = remove_duplicate_addrs2(*return_iplist, *return_count ); 1526 1590 1527 1591 /* Save in name cache */ … … 1539 1603 } 1540 1604 1541 namecache_store(name, name_type, *return_count, *return_iplist); 1605 if (*return_count) { 1606 namecache_store(name, name_type, *return_count, *return_iplist); 1607 } 1542 1608 1543 1609 /* Display some debugging info */ … … 2002 2068 explicit password servers */ 2003 2069 2004 if (local_count) { 2005 local_count = remove_duplicate_addrs2(return_iplist, 2006 local_count ); 2007 } 2070 local_count = remove_duplicate_addrs2(return_iplist, local_count ); 2008 2071 2009 2072 /* For DC's we always prioritize IPv4 due to W2K3 not
Note:
See TracChangeset
for help on using the changeset viewer.