関数 | |
static void | send_election_dgram (struct subnet_record *subrec, const char *workgroup_name, uint32 criterion, int timeup, const char *server_name) |
static void | check_for_master_browser_success (struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *answer_name, struct in_addr answer_ip, struct res_rec *rrec) |
static void | check_for_master_browser_fail (struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int fail_code) |
void | check_master_browser_exists (time_t t) |
void | run_elections (time_t t) |
static BOOL | win_election (struct work_record *work, int version, uint32 criterion, int timeup, const char *server_name) |
void | process_election (struct subnet_record *subrec, struct packet_struct *p, char *buf) |
BOOL | check_elections (void) |
void | nmbd_message_election (int msg_type, struct process_id src, void *buf, size_t len, void *private_data) |
変数 | |
time_t | StartupTime |
static void send_election_dgram | ( | struct subnet_record * | subrec, | |
const char * | workgroup_name, | |||
uint32 | criterion, | |||
int | timeup, | |||
const char * | server_name | |||
) | [static] |
nmbd_elections.c の 33 行で定義されています。
参照先 subnet_record::bcast_ip・global_myname・subnet_record::myip・send_mailslot()・skip_string()・strupper_m()・subnet_record::subnet_name.
参照元 check_for_master_browser_fail()・run_elections().
00035 { 00036 pstring outbuf; 00037 unstring srv_name; 00038 char *p; 00039 00040 DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n", 00041 workgroup_name, subrec->subnet_name )); 00042 00043 memset(outbuf,'\0',sizeof(outbuf)); 00044 p = outbuf; 00045 SCVAL(p,0,ANN_Election); /* Election opcode. */ 00046 p++; 00047 00048 SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION)); 00049 SIVAL(p,1,criterion); 00050 SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */ 00051 p += 13; 00052 unstrcpy(srv_name, server_name); 00053 strupper_m(srv_name); 00054 /* The following call does UNIX -> DOS charset conversion. */ 00055 pstrcpy_base(p, srv_name, outbuf); 00056 p = skip_string(outbuf,sizeof(outbuf),p); 00057 00058 send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf), 00059 global_myname(), 0, 00060 workgroup_name, 0x1e, 00061 subrec->bcast_ip, subrec->myip, DGRAM_PORT); 00062 }
static void check_for_master_browser_success | ( | struct subnet_record * | subrec, | |
struct userdata_struct * | userdata, | |||
struct nmb_name * | answer_name, | |||
struct in_addr | answer_ip, | |||
struct res_rec * | rrec | |||
) | [static] |
nmbd_elections.c の 68 行で定義されています。
参照先 nmb_name::name・pull_ascii_nstring().
参照元 check_master_browser_exists().
00072 { 00073 unstring aname; 00074 pull_ascii_nstring(aname, sizeof(aname), answer_name->name); 00075 DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \ 00076 IP %s (just checking).\n", aname, inet_ntoa(answer_ip) )); 00077 }
static void check_for_master_browser_fail | ( | struct subnet_record * | subrec, | |
struct response_record * | rrec, | |||
struct nmb_name * | question_name, | |||
int | fail_code | |||
) | [static] |
nmbd_elections.c の 83 行で定義されています。
参照先 find_workgroup_on_subnet()・lp_workgroup()・nmb_name::name・work_record::needelection・pull_ascii_nstring()・send_election_dgram()・strequal()・subnet_record::subnet_name・work_record::work_group.
参照元 check_master_browser_exists().
00087 { 00088 unstring workgroup_name; 00089 struct work_record *work; 00090 00091 pull_ascii_nstring(workgroup_name,sizeof(workgroup_name),question_name->name); 00092 00093 work = find_workgroup_on_subnet(subrec, workgroup_name); 00094 if(work == NULL) { 00095 DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n", 00096 workgroup_name, subrec->subnet_name )); 00097 return; 00098 } 00099 00100 if (strequal(work->work_group, lp_workgroup())) { 00101 00102 if (lp_local_master()) { 00103 /* We have discovered that there is no local master 00104 browser, and we are configured to initiate 00105 an election that we will participate in. 00106 */ 00107 DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n", 00108 work->work_group, subrec->subnet_name )); 00109 00110 /* Setting this means we will participate when the 00111 election is run in run_elections(). */ 00112 work->needelection = True; 00113 } else { 00114 /* We need to force an election, because we are configured 00115 not to become the local master, but we still need one, 00116 having detected that one doesn't exist. 00117 */ 00118 send_election_dgram(subrec, work->work_group, 0, 0, ""); 00119 } 00120 } 00121 }
void check_master_browser_exists | ( | time_t | t | ) |
nmbd_elections.c の 128 行で定義されています。
参照先 check_for_master_browser_fail()・check_for_master_browser_success()・dump_workgroups()・lp_workgroup()・work_record::next・query_name()・strequal()・subnet_record::workgrouplist.
参照元 process().
00129 { 00130 static time_t lastrun=0; 00131 struct subnet_record *subrec; 00132 const char *workgroup_name = lp_workgroup(); 00133 00134 if (!lastrun) 00135 lastrun = t; 00136 00137 if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60))) 00138 return; 00139 00140 lastrun = t; 00141 00142 dump_workgroups(False); 00143 00144 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 00145 struct work_record *work; 00146 00147 for (work = subrec->workgrouplist; work; work = work->next) { 00148 if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) { 00149 /* Do a name query for the local master browser on this net. */ 00150 query_name( subrec, work->work_group, 0x1d, 00151 check_for_master_browser_success, 00152 check_for_master_browser_fail, 00153 NULL); 00154 } 00155 } 00156 } 00157 }
void run_elections | ( | time_t | t | ) |
nmbd_elections.c の 163 行で定義されています。
参照先 become_local_master_browser()・find_name_on_subnet()・global_myname・make_nmb_name()・work_record::next・nmb_namestr()・send_election_dgram()・StartupTime・subnet_record::subnet_name・subnet_record::workgrouplist.
参照元 process().
00164 { 00165 static time_t lastime = 0; 00166 00167 struct subnet_record *subrec; 00168 00169 START_PROFILE(run_elections); 00170 00171 /* Send election packets once every 2 seconds - note */ 00172 if (lastime && (t - lastime < 2)) { 00173 END_PROFILE(run_elections); 00174 return; 00175 } 00176 00177 lastime = t; 00178 00179 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 00180 struct work_record *work; 00181 00182 for (work = subrec->workgrouplist; work; work = work->next) { 00183 if (work->RunningElection) { 00184 /* 00185 * We can only run an election for a workgroup if we have 00186 * registered the WORKGROUP<1e> name, as that's the name 00187 * we must listen to. 00188 */ 00189 struct nmb_name nmbname; 00190 00191 make_nmb_name(&nmbname, work->work_group, 0x1e); 00192 if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) { 00193 DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \ 00194 yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name )); 00195 continue; 00196 } 00197 00198 send_election_dgram(subrec, work->work_group, work->ElectionCriterion, 00199 t - StartupTime, global_myname()); 00200 00201 if (work->ElectionCount++ >= 4) { 00202 /* Won election (4 packets were sent out uncontested. */ 00203 DEBUG(2,("run_elections: >>> Won election for workgroup %s on subnet %s <<<\n", 00204 work->work_group, subrec->subnet_name )); 00205 00206 work->RunningElection = False; 00207 00208 become_local_master_browser(subrec, work); 00209 } 00210 } 00211 } 00212 } 00213 END_PROFILE(run_elections); 00214 }
static BOOL win_election | ( | struct work_record * | work, | |
int | version, | |||
uint32 | criterion, | |||
int | timeup, | |||
const char * | server_name | |||
) | [static] |
nmbd_elections.c の 220 行で定義されています。
参照先 work_record::ElectionCriterion・global_myname・StartupTime・StrCaseCmp().
参照元 process_election().
00222 { 00223 int mytimeup = time(NULL) - StartupTime; 00224 uint32 mycriterion = work->ElectionCriterion; 00225 00226 /* If local master is false then never win in election broadcasts. */ 00227 if(!lp_local_master()) { 00228 DEBUG(3,("win_election: Losing election as local master == False\n")); 00229 return False; 00230 } 00231 00232 DEBUG(4,("win_election: election comparison: %x:%x %x:%x %d:%d %s:%s\n", 00233 version, ELECTION_VERSION, 00234 criterion, mycriterion, 00235 timeup, mytimeup, 00236 server_name, global_myname())); 00237 00238 if (version > ELECTION_VERSION) 00239 return(False); 00240 if (version < ELECTION_VERSION) 00241 return(True); 00242 00243 if (criterion > mycriterion) 00244 return(False); 00245 if (criterion < mycriterion) 00246 return(True); 00247 00248 if (timeup > mytimeup) 00249 return(False); 00250 if (timeup < mytimeup) 00251 return(True); 00252 00253 if (StrCaseCmp(global_myname(), server_name) > 0) 00254 return(False); 00255 00256 return(True); 00257 }
void process_election | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p, | |||
char * | buf | |||
) |
nmbd_elections.c の 263 行で定義されています。
参照先 dgram_packet::dest_name・packet_struct::dgram・work_record::ElectionCount・find_workgroup_on_subnet()・packet_struct::ip・lp_workgroup()・nmb_name::name・work_record::needelection・packet_struct::packet・pull_ascii_nstring()・work_record::RunningElection・strequal()・subnet_record::subnet_name・unbecome_local_master_browser()・win_election()・work_record::work_group.
00264 { 00265 struct dgram_packet *dgram = &p->packet.dgram; 00266 int version = CVAL(buf,0); 00267 uint32 criterion = IVAL(buf,1); 00268 int timeup = IVAL(buf,5)/1000; 00269 unstring server_name; 00270 struct work_record *work; 00271 unstring workgroup_name; 00272 00273 START_PROFILE(election); 00274 00275 pull_ascii_nstring(server_name, sizeof(server_name), buf+13); 00276 pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); 00277 00278 server_name[15] = 0; 00279 00280 DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n", 00281 server_name,inet_ntoa(p->ip), subrec->subnet_name, workgroup_name )); 00282 00283 DEBUG(5,("process_election: vers=%d criterion=%08x timeup=%d\n", version,criterion,timeup)); 00284 00285 if(( work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) { 00286 DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n", 00287 workgroup_name, subrec->subnet_name )); 00288 goto done; 00289 } 00290 00291 if (!strequal(work->work_group, lp_workgroup())) { 00292 DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \ 00293 is not my workgroup.\n", work->work_group, subrec->subnet_name )); 00294 goto done; 00295 } 00296 00297 if (win_election(work, version,criterion,timeup,server_name)) { 00298 /* We take precedence over the requesting server. */ 00299 if (!work->RunningElection) { 00300 /* We weren't running an election - start running one. */ 00301 00302 work->needelection = True; 00303 work->ElectionCount=0; 00304 } 00305 00306 /* Note that if we were running an election for this workgroup on this 00307 subnet already, we just ignore the server we take precedence over. */ 00308 } else { 00309 /* We lost. Stop participating. */ 00310 work->needelection = False; 00311 00312 if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) { 00313 work->RunningElection = False; 00314 DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n", 00315 work->work_group, subrec->subnet_name )); 00316 if (AM_LOCAL_MASTER_BROWSER(work)) 00317 unbecome_local_master_browser(subrec, work, False); 00318 } 00319 } 00320 done: 00321 00322 END_PROFILE(election); 00323 }
BOOL check_elections | ( | void | ) |
nmbd_elections.c の 332 行で定義されています。
参照先 find_name_on_subnet()・make_nmb_name()・work_record::next・nmb_namestr()・subnet_record::subnet_name・subnet_record::workgrouplist.
参照元 process().
00333 { 00334 struct subnet_record *subrec; 00335 BOOL run_any_election = False; 00336 00337 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 00338 struct work_record *work; 00339 for (work = subrec->workgrouplist; work; work = work->next) { 00340 run_any_election |= work->RunningElection; 00341 00342 /* 00343 * Start an election if we have any chance of winning. 00344 * Note this is a change to the previous code, that would 00345 * only run an election if nmbd was in the potential browser 00346 * state. We need to run elections in any state if we're told 00347 * to. JRA. 00348 */ 00349 00350 if (work->needelection && !work->RunningElection && lp_local_master()) { 00351 /* 00352 * We can only run an election for a workgroup if we have 00353 * registered the WORKGROUP<1e> name, as that's the name 00354 * we must listen to. 00355 */ 00356 struct nmb_name nmbname; 00357 00358 make_nmb_name(&nmbname, work->work_group, 0x1e); 00359 if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) { 00360 DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \ 00361 yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name )); 00362 continue; 00363 } 00364 00365 DEBUG(3,("check_elections: >>> Starting election for workgroup %s on subnet %s <<<\n", 00366 work->work_group, subrec->subnet_name )); 00367 00368 work->ElectionCount = 0; 00369 work->RunningElection = True; 00370 work->needelection = False; 00371 } 00372 } 00373 } 00374 return run_any_election; 00375 }
void nmbd_message_election | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) |
nmbd_elections.c の 381 行で定義されています。
参照先 lp_workgroup()・MST_NONE・MST_POTENTIAL・work_record::next・strequal()・subnet_record::workgrouplist.
参照元 main().
00383 { 00384 struct subnet_record *subrec; 00385 00386 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 00387 struct work_record *work; 00388 for (work = subrec->workgrouplist; work; work = work->next) { 00389 if (strequal(work->work_group, lp_workgroup())) { 00390 work->needelection = True; 00391 work->ElectionCount=0; 00392 work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE; 00393 } 00394 } 00395 } 00396 }
time_t StartupTime |