Ejemplo n.º 1
0
static void
dmsg_parse_host_id(uint8_t *start, uint32_t len,
		struct string *dc, struct string *rack, struct dyn_token *token)
{
	uint8_t *p, *q;
	uint8_t *dc_p, *rack_p, *token_p;
	uint32_t k, delimlen, dc_len, rack_len, token_len;
	char delim[] = "$$";
	delimlen = 2;

	/* parse "dc$rack$token : don't support vnode for now */
	//log_hexdump(LOG_VERB, start, len, "host_addr testing: ");
	p = start + len - 1;
	dc_p = NULL;
	rack_p = NULL;
	token_p = NULL;

	dc_len = rack_len = token_len = 0;

	for (k = 0; k < sizeof(delim)-1; k++) {
		q = dn_strrchr(p, start, delim[k]);

		switch (k) {
		case 0:
			//no support for vnode at this time
			token_p = q + 1;
			token_len = (uint32_t)(p - token_p + 1);
			parse_dyn_token(token_p, token_len, token);
			break;
		case 1:
			rack_p = q + 1;
			rack_len = (uint32_t)(p - rack_p + 1);

			string_copy(rack, rack_p, rack_len);
			break;

		default:
			NOT_REACHED();
		}
		p = q - 1;
	}

	if (k != delimlen) {
		loga("Error: this should not happen");
		return;// DN_ERROR;
	}

	dc_p = start;
	dc_len = len - (token_len + rack_len + 2);
	string_copy(dc, dc_p, dc_len);

}
Ejemplo n.º 2
0
static rstatus_t
dnode_peer_add_local(struct server_pool *pool, struct server *peer)
{
	ASSERT(peer != NULL);
	peer->idx = 0; /* this might be psychotic, trying it for now */

	peer->pname = pool->d_addrstr;

	uint8_t *p = pool->d_addrstr.data + pool->d_addrstr.len - 1;
	uint8_t *start = pool->d_addrstr.data;
	string_copy(&peer->name, start, dn_strrchr(p, start, ':') - start);

	//peer->name = pool->d_addrstr;
	peer->port = pool->d_port;

	peer->weight = 0;  /* hacking this out of the way for now */
	peer->rack = pool->rack;
	peer->is_local = true;
	//TODO-jeb might need to copy over tokens, not sure if this is good enough
	peer->tokens = pool->tokens;

	peer->family = pool->d_family;
	peer->addrlen = pool->d_addrlen;
	peer->addr = pool->d_addr;

	peer->ns_conn_q = 0;
	TAILQ_INIT(&peer->s_conn_q);

	peer->next_retry = 0LL;
	peer->failure_count = 0;
	peer->is_seed = 1;
	string_copy(&peer->dc, pool->dc.data, pool->dc.len);
	peer->owner = pool;

	log_debug(LOG_VERB, "dyn: transform to local node to peer %"PRIu32" '%.*s'",
			peer->idx, pool->name.len, pool->name.data);

	return DN_OK;
}
Ejemplo n.º 3
0
static struct ring_msg *
dmsg_parse(struct dmsg *dmsg)
{
   //rstatus_t status;
   uint8_t *p, *q, *start, *end, *pipe_p;
   uint8_t *host_id, *host_addr, *ts, *node_state;
   uint32_t k, delimlen, host_id_len, host_addr_len, ts_len, node_state_len;
   char delim[] = ",,,";
   delimlen = 3;


   /* parse "host_id1,generation_ts1,host_state1,host_broadcast_address1|host_id2,generation_ts2,host_state2,host_broadcast_address2" */
   /* host_id = dc-rack-token */
   //p = dmsg->data + dmsg->mlen - 1;
   //p = dmsg->owner->pos + dmsg->owner->mlen - 1;
   p = dmsg->payload + dmsg->plen - 1;
   end = p;

   //start = dmsg->data;
   //start = dmsg->owner->pos;
   start = dmsg->payload;

   host_id = NULL;
   host_addr = NULL;
   ts = NULL;
   node_state = NULL;

   host_id_len = 0;
   host_addr_len = 0;
   ts_len = 0;
   node_state_len = 0;
   pipe_p = start;
   int count = 0;

   do {
      q = dn_strrchr(p, start, '|');
      count++;
      p = q - 1;
   } while (q != NULL);

   struct ring_msg *ring_msg = create_ring_msg_with_size(count, true);
   if (ring_msg == NULL) {
      log_debug(LOG_ERR, "Error: unable to create a new ring msg!");
      //we just drop this msg
      return NULL;
   }

   struct server_pool *sp = (struct server_pool *) dmsg->owner->owner->owner;
   ring_msg->sp = sp;
   ring_msg->cb = gossip_msg_peer_update;

   count = 0;
   //p = dmsg->data + dmsg->mlen - 1;
    p = dmsg->payload + dmsg->plen - 1;

   do {

      for (k = 0; k < sizeof(delim)-1; k++) {
         q = dn_strrchr(p, start, delim[k]);

         switch (k) {
         case 0:
            host_addr = q + 1;
            host_addr_len = (uint32_t)(p - host_addr + 1);
            break;
         case 1:
            node_state = q + 1;
            node_state_len = (uint32_t)(p - node_state + 1);

            break;
         case 2:
            ts = q + 1;
            ts_len = (uint32_t)(p - ts + 1);

            break;

         default:
            NOT_REACHED();
         }
         p = q - 1;

      }

      if (k != delimlen) {
         loga("Error: this is insanely bad");
         return NULL;// DN_ERROR;
      }

      pipe_p = dn_strrchr(p, start, '|');

      if (pipe_p == NULL) {
         pipe_p = start;
      } else {
         pipe_p = pipe_p + 1;
         p = pipe_p - 2;
      }

      //host_id = dmsg->data;
      //host_id_len = dmsg->mlen - (host_addr_len + node_state_len + ts_len + 3);
      host_id = pipe_p;
      host_id_len = end - pipe_p - (host_addr_len + node_state_len + ts_len + 3) + 1;

      end = p;


      struct node *rnode = (struct node *) array_get(&ring_msg->nodes, count);
      dmsg_parse_host_id(host_id, host_id_len, &rnode->dc, &rnode->rack, &rnode->token);


      string_copy(&rnode->name, host_addr, host_addr_len);
      string_copy(&rnode->pname, host_addr, host_addr_len); //need to add port

      rnode->port = sp->d_port;
      rnode->is_local = false;
      rnode->is_seed = false;

      ts[ts_len] = '\0';
      rnode->ts = atol(ts);

      node_state[node_state_len] = '\0';
      rnode->state = (uint8_t) atoi(node_state);

      count++;
   } while (pipe_p != start);

   //TODOs: should move this outside
   dmsg_to_gossip(ring_msg);

   return ring_msg;
}
Ejemplo n.º 4
0
static rstatus_t
gossip_update_seeds(struct server_pool *sp, struct mbuf *seeds)
{
	struct string rack_name;
	struct string dc_name;
	struct string port_str;
	struct string address;
	struct string ip;
	//struct array tokens;
	struct dyn_token token;

	struct string temp;

	string_init(&rack_name);
	string_init(&dc_name);
	string_init(&port_str);
	string_init(&address);
	string_init(&ip);
	init_dyn_token(&token);

	uint8_t *p, *q, *start;
	start = seeds->start;
	p = seeds->last - 1;
	q = dn_strrchr(p, start, '|');

	uint8_t *seed_node;
	uint32_t seed_node_len;

	while (q > start) {
		seed_node = q + 1;
		seed_node_len = (uint32_t)(p - seed_node + 1);
		string_copy(&temp, seed_node, seed_node_len);
		//array_init(&tokens, 1, sizeof(struct dyn_token));
		init_dyn_token(&token);
		parse_seeds(&temp, &dc_name, &rack_name, &port_str, &address, &ip,  &token);
		log_debug(LOG_VERB, "address          : '%.*s'", address.len, address.data);
		log_debug(LOG_VERB, "rack_name         : '%.*s'", rack_name.len, rack_name.data);
		log_debug(LOG_VERB, "dc_name        : '%.*s'", dc_name.len, dc_name.data);
		log_debug(LOG_VERB, "ip         : '%.*s'", ip.len, ip.data);

		//struct dyn_token *token = array_get(&tokens, 0);
		gossip_add_node_if_absent(sp, &dc_name, &rack_name, &address, &ip, &port_str, &token, NORMAL, (uint64_t) time(NULL));

		p = q - 1;
		q = dn_strrchr(p, start, '|');
		string_deinit(&temp);
		//array_deinit(&tokens);
		deinit_dyn_token(&token);
		string_deinit(&rack_name);
		string_deinit(&dc_name);
		string_deinit(&port_str);
		string_deinit(&address);
		string_deinit(&ip);
	}

	if (q == NULL) {
		seed_node_len = (uint32_t)(p - start + 1);
		seed_node = start;

		string_copy(&temp, seed_node, seed_node_len);
		//array_init(&tokens, 1, sizeof(struct dyn_token));
		init_dyn_token(&token);
		parse_seeds(&temp, &dc_name, &rack_name, &port_str, &address, &ip, &token);

		//struct dyn_token *token = array_get(&tokens, 0);
		gossip_add_node_if_absent(sp, &dc_name, &rack_name, &address, &ip, &port_str, &token, NORMAL, (uint64_t) time(NULL));
	}

	string_deinit(&temp);
	//array_deinit(&tokens);
	deinit_dyn_token(&token);
	string_deinit(&rack_name);
	string_deinit(&dc_name);
	string_deinit(&port_str);
	string_deinit(&address);
	string_deinit(&ip);

	gossip_debug();
	return DN_OK;
}
Ejemplo n.º 5
0
static rstatus_t
parse_seeds(struct string *seeds, struct string *dc_name, struct string *rack_name,
		struct string *port_str, struct string *address, struct string *name,
		struct dyn_token *ptoken)
{
	rstatus_t status;
	uint8_t *p, *q, *start;
	uint8_t *pname, *port, *rack, *dc, *token, *addr;
	uint32_t k, delimlen, pnamelen, portlen, racklen, dclen, tokenlen, addrlen;
	char delim[] = "::::";

	/* parse "hostname:port:rack:dc:tokens" */
	p = seeds->data + seeds->len - 1;
	start = seeds->data;
	rack = NULL;
	dc = NULL;
	racklen = 0;
	dclen = 0;
	token = NULL;
	tokenlen = 0;
	port = NULL;
	portlen = 0;
	delimlen = 4;

	for (k = 0; k < sizeof(delim)-1; k++) {
		q = dn_strrchr(p, start, delim[k]);

		switch (k) {
		case 0:
			token = q + 1;
			tokenlen = (uint32_t)(p - token + 1);
			break;
		case 1:
			dc = q + 1;
			dclen = (uint32_t)(p - dc + 1);
			string_copy(dc_name, dc, dclen);
			break;
		case 2:
			rack = q + 1;
			racklen = (uint32_t)(p - rack + 1);
			string_copy(rack_name, rack, racklen);
			break;

		case 3:
			port = q + 1;
			portlen = (uint32_t)(p - port + 1);
			string_copy(port_str, port, portlen);
			break;

		default:
			NOT_REACHED();
		}

		p = q - 1;
	}

	if (k != delimlen) {
		return GOS_ERROR;
	}

	//pname = hostname:port
	pname = seeds->data;
	pnamelen = seeds->len - (tokenlen + racklen + dclen + 3);
	status = string_copy(address, pname, pnamelen);


	//addr = hostname or ip only
	addr = start;
	addrlen = (uint32_t)(p - start + 1);
	//if it is a dns name, convert to IP or otherwise keep that IP
	if (!isdigit( (char) addr[0])) {
		addr[addrlen] = '\0';
		char *local_ip4 = hostname_to_private_ip4( (char *) addr);
		if (local_ip4 != NULL) {
		    status = string_copy_c(name, local_ip4);
		} else
			status = string_copy(name, addr, addrlen);
	} else {
	    status = string_copy(name, addr, addrlen);
	}
	if (status != DN_OK) {
		return GOS_ERROR;
	}

	uint8_t *t_end = token + tokenlen;
	status = derive_token(ptoken, token, t_end);
	if (status != DN_OK) {
		return GOS_ERROR;
	}

	//status = dn_resolve(&address, field->port, &field->info);
	//if (status != DN_OK) {
	//    string_deinit(&address);
	//    return CONF_ERROR;
	//}

	return GOS_OK;
}