Ignore:
Timestamp:
Nov 12, 2012, 5:38:52 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server 3.5: update branche to 3.5.16

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.5.x/source3/libsmb/namequery.c

    r414 r736  
    572572                        "looking for duplicate address/port pairs\n"));
    573573
    574         /* one loop to remove duplicates */
     574        /* One loop to set duplicates to a zero addr. */
    575575        for ( i=0; i<count; i++ ) {
    576576                if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
     
    586586        }
    587587
    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));
    595596                        }
    596597                        count--;
    597                         continue;
    598                 }
    599                 i++;
     598                }
    600599        }
    601600
     
    850849
    851850/********************************************************
    852  convert an array if struct sockaddr_storage to struct ip_service
     851 Convert an array if struct sockaddr_storage to struct ip_service
    853852 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.
    854856*********************************************************/
    855857
    856858static bool convert_ss2service(struct ip_service **return_iplist,
    857859                const struct sockaddr_storage *ss_list,
    858                 int count)
     860                int *pcount)
    859861{
    860862        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 )
    863867                return False;
    864868
     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
    865880        /* 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)) ==
    867882                        NULL) {
    868883                DEBUG(0,("convert_ip2service: malloc failed "
    869                         "for %d enetries!\n", count ));
     884                        "for %d enetries!\n", real_count ));
    870885                return False;
    871886        }
    872887
    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;
    878898        return true;
    879899}
     
    948968
    949969        status = NT_STATUS_OK;
    950         if (!convert_ss2service(return_iplist, ss_list, *return_count) )
     970        if (!convert_ss2service(return_iplist, ss_list, return_count) )
    951971                status = NT_STATUS_INVALID_PARAMETER;
    952972
     
    10831103
    10841104        status = NT_STATUS_OK;
    1085         if (!convert_ss2service(return_iplist, ss_list, *return_count))
     1105        if (!convert_ss2service(return_iplist, ss_list, return_count))
    10861106                status = NT_STATUS_INVALID_PARAMETER;
    10871107
     
    12311251                memcpy(&ss, res->ai_addr, res->ai_addrlen);
    12321252
     1253                if (is_zero_addr((struct sockaddr *)&ss)) {
     1254                        continue;
     1255                }
     1256
    12331257                *return_count += 1;
    12341258
     
    12641288                            int *return_count)
    12651289{
    1266         int                     i, j;
     1290        int                     i;
    12671291        NTSTATUS                status;
    12681292        TALLOC_CTX              *ctx;
     
    13131337
    13141338        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                }
    13161344        }
    13171345
     
    13271355
    13281356        *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 */
    13381360                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                        }
    13421411                } 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                        }
    13651426                }
    13661427        }
     
    14191480                        return NT_STATUS_INVALID_PARAMETER;
    14201481                }
     1482                if (is_zero_addr((struct sockaddr *)&(*return_iplist)->ss)) {
     1483                        SAFE_FREE(*return_iplist);
     1484                        return NT_STATUS_UNSUCCESSFUL;
     1485                }
    14211486                *return_count = 1;
    14221487                return NT_STATUS_OK;
     
    14261491
    14271492        if (namecache_fetch(name, name_type, return_iplist, return_count)) {
     1493                *return_count = remove_duplicate_addrs2(*return_iplist,
     1494                                        *return_count );
    14281495                /* This could be a negative response */
    14291496                if (*return_count > 0) {
     
    15201587        the iplist when the PDC is down will cause two sets of timeouts. */
    15211588
    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 );
    15261590
    15271591        /* Save in name cache */
     
    15391603        }
    15401604
    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        }
    15421608
    15431609        /* Display some debugging info */
     
    20022068           explicit password servers */
    20032069
    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 );
    20082071
    20092072        /* For DC's we always prioritize IPv4 due to W2K3 not
Note: See TracChangeset for help on using the changeset viewer.