/* find the interface to use for sending a outgoing request */ struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server, const char *address, bool allow_bcast_iface) { struct nbtd_interface *cur; /* try to find a exact match */ for (cur=nbtd_server->interfaces;cur;cur=cur->next) { if (iface_same_net(address, cur->ip_address, cur->netmask)) { DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n", address, cur->ip_address, cur->netmask, cur)); return cur; } } /* no exact match, if we have the broadcast interface, use that */ if (allow_bcast_iface && nbtd_server->bcast_interface) { cur = nbtd_server->bcast_interface; DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n", address, cur->ip_address, cur->netmask, cur)); return cur; } /* fallback to first interface */ cur = nbtd_server->interfaces; DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n", address, cur->ip_address, cur->netmask, cur)); return cur; }
static void nbtd_wins_randomize1Clist(struct loadparm_context *lp_ctx, const char **addresses, struct socket_address *src) { const char *mask; const char *tmp; uint32_t num_addrs; uint32_t idx, sidx; int r; for (num_addrs=0; addresses[num_addrs]; num_addrs++) { /* noop */ } if (num_addrs <= 1) return; /* nothing to do */ /* first sort the addresses depending on the matching to the client */ ldb_qsort(addresses, num_addrs , sizeof(addresses[0]), src, (ldb_qsort_cmp_fn_t)nbtd_wins_randomize1Clist_sort); mask = lp_parm_string(lp_ctx, NULL, "nbtd", "wins_randomize1Clist_mask"); if (!mask) { mask = "255.255.255.0"; } /* * choose a random address to be the first in the response to the client, * preferr the addresses inside the nbtd:wins_randomize1Clist_mask netmask */ r = random(); idx = sidx = r % num_addrs; while (1) { bool same; /* if the current one is in the same subnet, use it */ same = iface_same_net(addresses[idx], src->addr, mask); if (same) { sidx = idx; break; } /* we need to check for idx == 0, after checking for the same net */ if (idx == 0) break; /* * if we haven't found an address in the same subnet, search in ones * which match the client more * * some notes: * * it's not "idx = idx % r" but "idx = r % idx" * because in "a % b" b is the allowed range * and b-1 is the maximum possible result, so it must be decreasing * and the above idx == 0 check breaks the while(1) loop. */ idx = r % idx; } /* note sidx == 0 is also valid here ... */ tmp = addresses[0]; addresses[0] = addresses[sidx]; addresses[sidx] = tmp; }