Exemple #1
0
/*
  return the IP of the currently active wins server for the given tag,
  or the zero IP otherwise
*/
struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
{
	const char **list;
	int i;
	struct tagged_ip t_ip;

	/* if we are a wins server then we always just talk to ourselves */
	if (lp_we_are_a_wins_server()) {
		struct in_addr loopback_ip;
		loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
		return loopback_ip;
	}

	list = lp_wins_server_list();
	if (!list || !list[0]) {
		struct in_addr ip;
		zero_ip_v4(&ip);
		return ip;
	}

	/* find the first live one for this tag */
	for (i=0; list[i]; i++) {
		parse_ip(&t_ip, list[i]);
		if (strcmp(tag, t_ip.tag) != 0) {
			/* not for the right tag. Move along */
			continue;
		}
		if (!wins_srv_is_dead(t_ip.ip, src_ip)) {
			fstring src_name;
			fstrcpy(src_name, inet_ntoa(src_ip));
			DEBUG(6,("Current wins server for tag '%s' with source %s is %s\n", 
				 tag, 
				 src_name,
				 inet_ntoa(t_ip.ip)));
			return t_ip.ip;
		}
	}

	/* they're all dead - try the first one until they revive */
	for (i=0; list[i]; i++) {
		parse_ip(&t_ip, list[i]);
		if (strcmp(tag, t_ip.tag) != 0) {
			continue;
		}
		return t_ip.ip;
	}

	/* this can't happen?? */
	zero_ip_v4(&t_ip.ip);
	return t_ip.ip;
}
Exemple #2
0
/*
  mark a wins server as temporarily dead
*/
void wins_srv_died(struct in_addr wins_ip, struct in_addr src_ip)
{
	char *keystr;

	if (is_zero_ip_v4(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
		return;

	keystr = wins_srv_keystr(wins_ip, src_ip);

	gencache_set(keystr, "DOWN", time(NULL) + DEATH_TIME);

	SAFE_FREE(keystr);

	DEBUG(4,("Marking wins server %s dead for %u seconds from source %s\n",
		 inet_ntoa(wins_ip), DEATH_TIME, inet_ntoa(src_ip)));
}
static void wins_registration_timeout(struct subnet_record *subrec,
				      struct response_record *rrec)
{
	struct userdata_struct *userdata = rrec->userdata;
	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
	struct nmb_name *nmbname = &sent_nmb->question.question_name;
	struct in_addr register_ip;
	fstring src_addr;

	putip(&register_ip,&sent_nmb->additional->rdata[2]);

	fstrcpy(src_addr, inet_ntoa(register_ip));

	DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n", 
		 inet_ntoa(rrec->packet->ip), src_addr));

	/* mark it temporarily dead for this source address */
	wins_srv_died(rrec->packet->ip, register_ip);

	/* if we have some userdata then use that to work out what
	   wins server to try next */
	if (userdata) {
		const char *tag = (const char *)userdata->data;

		/* try the next wins server in our failover list for
		   this tag */
		rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
	}

	/* if we have run out of wins servers for this tag then they
	   must all have timed out. We treat this as *success*, not
	   failure, and go into our standard name refresh mode. This
	   copes with all the wins servers being down */
	if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
		uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
		int ttl = sent_nmb->additional->ttl;

		standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
		if(rrec->success_fn) {
			(*(register_name_success_function)rrec->success_fn)(subrec, 
									    rrec->userdata, 
									    nmbname, 
									    nb_flags, 
									    ttl, 
									    register_ip);
		}

		/* send off a registration for the next IP, if any */
		wins_next_registration(rrec);

		/* don't need to send this packet any more */
		remove_response_record(subrec, rrec);
		return;
	}
	
	/* we will be moving to the next WINS server for this group,
	   send it immediately */
	rrec->repeat_count = 2;
	rrec->repeat_time = time(NULL) + 1;
	rrec->in_expiration_processing = False;

	DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
		 nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));

	/* notice that we don't remove the response record. This keeps
	   us trying to register with each of our failover wins servers */
}