/** * 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; }
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); } } }
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) ); }
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; }
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()); } }
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; }
/** * 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; }
void on_timeout_cb(evutil_socket_t fd, short what, void *arg) { new_peer(); }
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); }