Пример #1
0
/**
 * Initializes the Peer Manager. 
 * The initial list of peers is taken from the configuration provided
 * @param config - configuration for initial peers
 * @returns 1
 */
int peer_manager_init(dp_config *config)
{
	int i;
	peer *p;
	LOG(L_DBG,"DBG:peer_manager_init(): Peer Manager initialization...\n");
	peer_list = shm_malloc(sizeof(peer_list_t));
	peer_list->head = 0; 
	peer_list->tail = 0;
	peer_list_lock = lock_alloc();
	peer_list_lock = lock_init(peer_list_lock);
	
	hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier));
	endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier));
	msg_id_lock = lock_alloc();
	msg_id_lock = lock_init(msg_id_lock);
	
	srand((unsigned int)time(0));
	*hopbyhop_id = rand();
	*endtoend_id = (time(0)&0xFFF)<<20;
	*endtoend_id |= rand() & 0xFFFFF;	

	for(i=0;i<config->peers_cnt;i++){
		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
		if (!p) continue;
		p->is_dynamic = 0;
		add_peer(p);
	}
	
	add_timer(PEER_MANAGER_TIMER,0,&peer_timer,0);
	
	return 1;
}
Пример #2
0
void udp_readable_cb(EV_P_ ev_io *w, int revents)
{
  char b;
  struct sockaddr src;
  socklen_t len;
  struct Peer *p;
  (void) loop;
  (void) w;
  (void) revents;
  len = sizeof(src);
  recvfrom(sock, &b, 1, 0, &src, &len);
  p = get_peer(&src, len);
  switch (b)
  {
    case CON:
      printf("client wants to connect\n");
      if (!p)
      {
        p = new_peer();
        memcpy(&p->addr, &src, len);
        p->state = ACKNOWLEDGING;
        acknowledge(p);
      }
      else if (p->state == DEAD)
      {
        acknowledge(p);
        p->state = ACKNOWLEDGING;
      }  
      return;
    case ACK:
      if (p && (p->state == CONNECTING || p->state == ESTABLISHED))
      {
        establish(p);
        p->state = ESTABLISHED;
        printf("established\n");
      }
      return;
    case EST:
      if (p && p->state == ACKNOWLEDGING)
      {
        printf("established\n");
        p->state = ESTABLISHED;
        return;
      }
    case DIE:
      if (p)
      {
        printf("peer disconected\n");
        remove_peer(p);
      }
  }
}
Пример #3
0
void Listener::start_accept()
{
  shared_ptr<tcp::socket> socket(new tcp::socket(acceptor.get_io_service()));

  Peer* new_peer(new Peer(socket));

  list<Peer*>::iterator new_peer_it;
  new_peer_it = pending_peers.insert(pending_peers.begin(), new_peer);

  acceptor.async_accept(new_peer->get_socket(),
                        bind(&Listener::handle_accept, this, new_peer_it,
                             asio::placeholders::error) );
}
Пример #4
0
int
ctrl_init(struct switch_cfg *_cfg)
{
	static struct event	*ev_int;

	cfg = _cfg;
	cfg->ctrl_running = 1;

	jlog(L_NOTICE, "Control initializing...");

	if ((base = event_base_new()) == NULL) {
		jlog(L_ERROR, "event_base_new failed");
		goto out;
	}

	if ((ev_int = evsignal_new(base, SIGHUP, sighandler, NULL)) == NULL) {
		jlog(L_ERROR, "evsignal_new failed");
		goto out;
	}

	if (event_add(ev_int, NULL) < 0) {
		jlog(L_ERROR, "event_add failed");
		goto out;
	}

	if (new_peer() == -1) {
		jlog(L_ERROR, "new_peer failed");
	}

	bufev_pipe = bufferevent_socket_new(base, pipefd[0], BEV_OPT_CLOSE_ON_FREE);
	bufferevent_enable(bufev_pipe, EV_READ|EV_WRITE);
	bufferevent_setcb(bufev_pipe, pipe_read_cb, NULL, pipe_event_cb, NULL);

	event_base_dispatch(base);

	if (bufev_sock != NULL) {
		bufferevent_free(bufev_sock);
	}

	event_base_free(base);
	return 0;
out:
	event_base_free(base);
	return -1;
}
Пример #5
0
void Listener::handle_accept(list<Peer*>::iterator new_peer_it,
                             const system::error_code& error)
{
  if (!error) {
    shared_ptr<Peer> new_peer(*new_peer_it);

    network->add_peer(new_peer);

    pending_peers.erase(new_peer_it);

    DEBUG("Peer at address " << new_peer->get_address() << " has joined!");

    start_accept();
  }
  else {
    DEBUG("Listener::handle_accept: " << error.message());
  }
        
}
Пример #6
0
int main(int argc, char *argv[])
{
  ev_io udp_watcher;
  struct ev_signal signal_watcher;
  struct ev_loop *loop;
  struct Peer *p;

  p = 0;
  listen_addr_len = sizeof(listen_addr);
  sock = socket(PF_INET, SOCK_DGRAM, 0);
  fcntl(sock, F_SETFL, O_NONBLOCK);
  bzero(&listen_addr, listen_addr_len);
  listen_addr.sin_family = AF_INET;
  listen_addr.sin_port = htons(42000);
  listen_addr.sin_addr.s_addr = INADDR_ANY;
  if (bind(sock, (struct sockaddr*) &listen_addr, listen_addr_len) != 0)
    fprintf(stderr, "could not bind\n");

  if (argc == 2)
  {
    p = new_peer();
    lookup(argv[1], p);
    p->state = CONNECTING;
    _connect(p);
  }

  loop = ev_default_loop(0);

  ev_io_init(&udp_watcher, udp_readable_cb, sock, EV_READ);
  ev_io_start(loop, &udp_watcher);

  ev_signal_init(&signal_watcher, sigint_cb, SIGINT);
  ev_signal_start(loop, &signal_watcher);

  ev_run(loop, 0);

  for (p = peers; p; p = p->next)
    die(p);

  return EXIT_SUCCESS;
}
Пример #7
0
/**
 * Finds a peer based on the FQDN and Realm.
 * @param fqdn - the FQDN to look for
 * @param realm - the Realm to look for
 * @returns the peer* or NULL if not found
 */
peer *get_peer_from_fqdn(str fqdn,str realm)
{
	peer *i;
	lock_get(peer_list_lock);
	i = peer_list->head;
	while(i){
		if (fqdn.len == i->fqdn.len && strncasecmp(fqdn.s,i->fqdn.s,fqdn.len)==0) 
			break;
		i = i->next;
	}
	lock_release(peer_list_lock);
	if (!i&&config->accept_unknown_peers){
		i = new_peer(fqdn,realm,3868);
		if (i){
			i->is_dynamic=1;
			touch_peer(i);
			add_peer(i);
		}
	}
	return i;
}
Пример #8
0
void
on_timeout_cb(evutil_socket_t fd, short what, void *arg)
{
	new_peer();
}
Пример #9
0
abstract_actor_ptr remote_actor_impl(stream_ptr_pair io, string_set expected) {
    CPPA_LOGF_TRACE("io{" << io.first.get() << ", " << io.second.get() << "}");
    auto mm = get_middleman();
    auto pinf = mm->node();
    std::uint32_t process_id = pinf->process_id();
    // throws on error
    io.second->write(&process_id, sizeof(std::uint32_t));
    io.second->write(pinf->host_id().data(), pinf->host_id().size());
    // deserialize: actor id, process id, node id, interface
    actor_id remote_aid;
    std::uint32_t peer_pid;
    node_id::host_id_type peer_node_id;
    std::uint32_t iface_size;
    std::set<std::string> iface;
    auto& in = io.first;
    // -> actor id
    in->read(&remote_aid, sizeof(actor_id));
    // -> process id
    in->read(&peer_pid, sizeof(std::uint32_t));
    // -> node id
    in->read(peer_node_id.data(), peer_node_id.size());
    // -> interface
    in->read(&iface_size, sizeof(std::uint32_t));
    if (iface_size > max_iface_size) {
        throw std::invalid_argument("Remote actor claims to have more than"
                                    +std::to_string(max_iface_size)+
                                    " message types? Someone is trying"
                                    " something nasty!");
    }
    std::vector<char> strbuf;
    for (std::uint32_t i = 0; i < iface_size; ++i) {
        std::uint32_t str_size;
        in->read(&str_size, sizeof(std::uint32_t));
        if (str_size > max_iface_clause_size) {
            throw std::invalid_argument("Remote actor claims to have a"
                                        " reply_to<...>::with<...> clause with"
                                        " more than"
                                        +std::to_string(max_iface_clause_size)+
                                        " characters? Someone is"
                                        " trying something nasty!");
        }
        strbuf.reserve(str_size + 1);
        strbuf.resize(str_size);
        in->read(strbuf.data(), str_size);
        strbuf.push_back('\0');
        iface.insert(std::string{strbuf.data()});
    }
    // deserialization done, check interface
    if (iface != expected) {
        auto tostr = [](const std::set<std::string>& what) -> std::string {
            if (what.empty()) return "actor";
            std::string tmp;
            tmp = "typed_actor<";
            auto i = what.begin();
            auto e = what.end();
            tmp += *i++;
            while (i != e) tmp += *i++;
            tmp += ">";
            return tmp;
        };
        auto iface_str = tostr(iface);
        auto expected_str = tostr(expected);
        if (expected.empty()) {
            throw std::invalid_argument("expected remote actor to be a "
                                        "dynamically typed actor but found "
                                        "a strongly typed actor of type "
                                        + iface_str);
        }
        if (iface.empty()) {
            throw std::invalid_argument("expected remote actor to be a "
                                        "strongly typed actor of type "
                                        + expected_str +
                                        " but found a dynamically typed actor");
        }
        throw std::invalid_argument("expected remote actor to be a "
                                    "strongly typed actor of type "
                                    + expected_str +
                                    " but found a strongly typed actor of type "
                                    + iface_str);
    }
    auto pinfptr = make_counted<node_id>(peer_pid, peer_node_id);
    if (*pinf == *pinfptr) {
        // this is a local actor, not a remote actor
        CPPA_LOGF_INFO("remote_actor() called to access a local actor");
        auto ptr = get_actor_registry()->get(remote_aid);
        return ptr;
    }
    struct remote_actor_result { remote_actor_result* next; actor value; };
    std::mutex qmtx;
    std::condition_variable qcv;
    intrusive::single_reader_queue<remote_actor_result> q;
    mm->run_later([mm, io, pinfptr, remote_aid, &q, &qmtx, &qcv] {
        CPPA_LOGC_TRACE("cppa",
                        "remote_actor$create_connection", "");
        auto pp = mm->get_peer(*pinfptr);
        CPPA_LOGF_INFO_IF(pp, "connection already exists (re-use old one)");
        if (!pp) mm->new_peer(io.first, io.second, pinfptr);
        auto res = mm->get_namespace().get_or_put(pinfptr, remote_aid);
        q.synchronized_enqueue(qmtx, qcv, new remote_actor_result{0, res});
    });
    std::unique_ptr<remote_actor_result> result(q.synchronized_pop(qmtx, qcv));
    CPPA_LOGF_DEBUG(CPPA_MARG(result, get));
    return raw_access::get(result->value);
}