Changeset 745 for trunk/server/source3/nmbd/nmbd_winsserver.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/nmbd/nmbd_winsserver.c
r454 r745 22 22 23 23 #include "includes.h" 24 #include "system/filesys.h" 25 #include "nmbd/nmbd.h" 26 #include "util_tdb.h" 24 27 25 28 #define WINS_LIST "wins.dat" … … 49 52 SAFE_FREE(nr->data.ip); 50 53 SAFE_FREE(nr); 54 } 55 } 56 57 /**************************************************************************** 58 Delete all the temporary 1b name records on the in-memory linked list. 59 *****************************************************************************/ 60 61 static void wins_delete_all_1b_in_memory_records(void) 62 { 63 struct name_record *nr = NULL; 64 struct name_record *nrnext = NULL; 65 66 /* Delete all temporary 1b name records on the wins subnet linked list. */ 67 for( nr = wins_server_subnet->namelist; nr; nr = nrnext) { 68 nrnext = nr->next; 69 if (nr->name.name_type == 0x1b) { 70 DLIST_REMOVE(wins_server_subnet->namelist, nr); 71 SAFE_FREE(nr->data.ip); 72 SAFE_FREE(nr); 73 } 51 74 } 52 75 } … … 405 428 namerec->data.wins_flags|=flags; 406 429 407 DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",430 DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: %d, flags: 0x%x, winsflags: 0x%x\n", 408 431 namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags)); 409 432 } … … 584 607 585 608 /* Open the wins.tdb. */ 586 wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600); 609 wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, 610 O_CREAT|O_RDWR, 0600); 587 611 if (!wins_tdb) { 588 612 DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n", … … 1251 1275 1252 1276 if(!find_ip_in_name_record(namerec, from_ip)) { 1277 /* 1278 * Need to emulate the behaviour of Windows, as 1279 * described in: 1280 * http://lists.samba.org/archive/samba-technical/2001-October/016236.html 1281 * (is there an MS reference for this 1282 * somewhere?) because if the 1c list gets over 1283 * 86 entries, the reply packet is too big 1284 * (rdata>576 bytes) so no reply is sent. 1285 * 1286 * Keep only the "latest" 25 records, while 1287 * ensuring that the PDC (0x1b) is never removed 1288 * We do this by removing the first entry that 1289 * isn't the 1b entry for the same name, 1290 * on the grounds that insertion is at the end 1291 * of the list, so the oldest entries are at 1292 * the start. 1293 * 1294 */ 1295 while(namerec->data.num_ips>=25) { 1296 struct name_record *name1brec = NULL; 1297 1298 /* We only do this for 1c types. */ 1299 if (namerec->name.name_type != 0x1c) { 1300 break; 1301 } 1302 DEBUG(3,("wins_process_name_registration_request: " 1303 "More than 25 IPs already in " 1304 "the list. Looking for a 1b " 1305 "record\n")); 1306 1307 /* Ensure we have all the active 1b 1308 * names on the list. */ 1309 wins_delete_all_1b_in_memory_records(); 1310 fetch_all_active_wins_1b_names(); 1311 1312 /* Per the above, find the 1b record, 1313 and then remove the first IP that isn't the same */ 1314 for(name1brec = subrec->namelist; 1315 name1brec; 1316 name1brec = name1brec->next ) { 1317 if( WINS_STATE_ACTIVE(name1brec) && 1318 name1brec->name.name_type == 0x1b) { 1319 DEBUG(3,("wins_process_name_registration_request: " 1320 "Found the #1b record " 1321 "with ip %s\n", 1322 inet_ntoa(name1brec->data.ip[0]))); 1323 break; 1324 } 1325 } 1326 if(!name1brec) { 1327 DEBUG(3,("wins_process_name_registration_request: " 1328 "Didn't find a #1b name record. " 1329 "Removing the first available " 1330 "entry %s\n", 1331 inet_ntoa(namerec->data.ip[0]))); 1332 remove_ip_from_name_record(namerec, namerec->data.ip[0]); 1333 wins_hook("delete", namerec, 0); 1334 } else { 1335 int i; 1336 for(i=0; i<namerec->data.num_ips; i++) { 1337 /* The name1brec should only have 1338 * the single IP address in it, 1339 * so we only check against the first one*/ 1340 if(!ip_equal_v4( namerec->data.ip[i], name1brec->data.ip[0])) { 1341 /* The i'th entry isn't the 1b address; delete it */ 1342 DEBUG(3,("wins_process_name_registration_request: " 1343 "Entry at %d is not the #1b address. " 1344 "About to remove it\n", 1345 i)); 1346 remove_ip_from_name_record(namerec, namerec->data.ip[i]); 1347 wins_hook("delete", namerec, 0); 1348 break; 1349 } 1350 } 1351 } 1352 } 1353 /* The list is guaranteed to be < 25 entries now 1354 * - safe to add a new one */ 1253 1355 add_ip_to_name_record(namerec, from_ip); 1254 1356 /* we need to update the record for replication */ … … 1867 1969 1868 1970 if(rcode == 0) { 1971 1972 int ip_count; 1973 1869 1974 ttl = (namerec->data.death_time != PERMANENT_TTL) ? namerec->data.death_time - p->timestamp : lp_max_wins_ttl(); 1975 1976 /* The netbios reply packet data section is limited to 576 bytes. In theory 1977 * this should give us space for 96 addresses, but in practice, 86 appears 1978 * to be the max (don't know why). If we send any more than that, 1979 * reply_netbios_packet will fail to send a reply to avoid a memcpy buffer 1980 * overflow. Keep the count to 85 and it will be ok */ 1981 ip_count=namerec->data.num_ips; 1982 if(ip_count>85) { 1983 ip_count=85; 1984 } 1870 1985 1871 1986 /* Copy all known ip addresses into the return data. */ 1872 1987 /* Optimise for the common case of one IP address so we don't need a malloc. */ 1873 1988 1874 if( namerec->data.num_ips== 1 ) {1989 if( ip_count == 1 ) { 1875 1990 prdata = rdata; 1876 1991 } else { 1877 if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips* 6 )) == NULL) {1992 if((prdata = (char *)SMB_MALLOC( ip_count * 6 )) == NULL) { 1878 1993 DEBUG(0,("send_wins_name_query_response: malloc fail !\n")); 1879 1994 return; … … 1881 1996 } 1882 1997 1883 for(i = 0; i < namerec->data.num_ips; i++) {1998 for(i = 0; i < ip_count; i++) { 1884 1999 set_nb_flags(&prdata[i*6],namerec->data.nb_flags); 1885 2000 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]); … … 1887 2002 1888 2003 sort_query_replies(prdata, i, p->ip); 1889 reply_data_len = namerec->data.num_ips* 6;2004 reply_data_len = ip_count * 6; 1890 2005 } 1891 2006 … … 2026 2141 struct name_record *namerec = NULL; 2027 2142 struct in_addr from_ip; 2028 bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False; ;2143 bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False; 2029 2144 2030 2145 putip((char *)&from_ip,&nmb->additional->rdata[2]);
Note:
See TracChangeset
for help on using the changeset viewer.