Пример #1
0
 bool operator()(const MessageNodeList::value_type& a,
                 const MessageNodeList::value_type& b) const
 {
     gcomm_assert(MessageNodeList::value(a).view_id() ==
                  MessageNodeList::value(b).view_id());
     return (MessageNodeList::value(a).im_range().hs() <
             MessageNodeList::value(b).im_range().hs());
 }
 void set_restored_view(View* rst_view) {
     gcomm_assert(state_ == S_CLOSED);
     rst_view_ = rst_view;
     NodeMap::value(self_i_).set_last_prim(
         // set last prim just for exchanging uuid and seq.
         // but actually restored view is not actual prim view.
         ViewId(V_NON_PRIM,
                rst_view -> id().uuid(),
                rst_view -> id().seq()));
 }
void gcomm::AsioUdpSocket::connect(const gu::URI& uri)
{
    gcomm_assert(state() == S_CLOSED);
    Critical<AsioProtonet> crit(net_);
    asio::ip::udp::resolver resolver(net_.io_service_);

    asio::ip::udp::resolver::query query(unescape_addr(uri.get_host()),
                                   uri.get_port());
    asio::ip::udp::resolver::iterator conn_i(resolver.resolve(query));

    target_ep_ = conn_i->endpoint();

    socket_.open(conn_i->endpoint().protocol());
    socket_.set_option(asio::ip::udp::socket::reuse_address(true));
    socket_.set_option(asio::ip::udp::socket::linger(true, 1));
    set_fd_options(socket_);
    asio::ip::udp::socket::non_blocking_io cmd(true);
    socket_.io_control(cmd);

    const std::string if_addr(
        unescape_addr(
            uri.get_option("socket.if_addr",
                           anyaddr(conn_i->endpoint().address()))));
    asio::ip::address local_if(asio::ip::address::from_string(if_addr));

    if (is_multicast(conn_i->endpoint()) == true)
    {
        join_group(socket_, conn_i->endpoint(), local_if);
        socket_.set_option(
            asio::ip::multicast::enable_loopback(
                gu::from_string<bool>(uri.get_option("socket.if_loop", "false"))));
        socket_.set_option(
            asio::ip::multicast::hops(
                gu::from_string<int>(uri.get_option("socket.mcast_ttl", "1"))));
        socket_.bind(*conn_i);
    }
    else
    {
        socket_.bind(
            asio::ip::udp::endpoint(
                local_if,
                gu::from_string<unsigned short>(uri.get_port())));
    }

    async_receive();
    state_ = S_CONNECTED;
}
static void join_group(asio::ip::udp::socket& socket,
                       const asio::ip::udp::endpoint& ep,
                       const asio::ip::address& local_if)
{
    gcomm_assert(is_multicast(ep) == true);
    if (ep.address().is_v4() == true)
    {
        socket.set_option(asio::ip::multicast::join_group(ep.address().to_v4(),
                                                    local_if.to_v4()));
        socket.set_option(asio::ip::multicast::outbound_interface(local_if.to_v4()));
    }
    else
    {
        gu_throw_fatal << "mcast interface not implemented";
        socket.set_option(asio::ip::multicast::join_group(ep.address().to_v6()));
    }
}
Пример #5
0
void gcomm::PC::connect(bool start_prim)
{
    try
    {
        // for backward compatibility with old approach: gcomm://0.0.0.0
        start_prim = (start_prim || host_is_any (uri_.get_host()));
    }
    catch (gu::NotSet& ns)
    {
        start_prim = true;
    }

    const bool wait_prim(
        gu::from_string<bool>(
            uri_.get_option(Conf::PcWaitPrim, Defaults::PcWaitPrim)));

    const gu::datetime::Period wait_prim_timeout(
        gu::from_string<gu::datetime::Period>(
            uri_.get_option(Conf::PcWaitPrimTimeout,
                            Defaults::PcWaitPrimTimeout)));

    pstack_.push_proto(gmcast_);
    pstack_.push_proto(evs_);
    pstack_.push_proto(pc_);
    pstack_.push_proto(this);
    pnet().insert(&pstack_);

    gmcast_->connect();

    closed_ = false;

    evs_->shift_to(evs::Proto::S_JOINING);
    pc_->connect(start_prim);

    // Due to #658 there is limited announce period after which
    // node is allowed to proceed to non-prim if other nodes
    // are not detected.
    gu::datetime::Date try_until(gu::datetime::Date::now() + announce_timeout_);
    while (start_prim == false && evs_->known_size() <= 1)
    {
        // Send join messages without handling them
        evs_->send_join(false);
        pnet().event_loop(gu::datetime::Sec/2);

        if (try_until < gu::datetime::Date::now())
        {
            break;
        }
    }

    log_debug << "PC/EVS Proto initial state: " << *evs_;
    if (evs_->state() != evs::Proto::S_OPERATIONAL)
    {
        log_debug << "PC/EVS Proto sending join request";
        evs_->send_join();
    }
    gcomm_assert(evs_->state() == evs::Proto::S_GATHER ||
                 evs_->state() == evs::Proto::S_INSTALL ||
                 evs_->state() == evs::Proto::S_OPERATIONAL);

    // - Due to #658 we loop here only if node is told to start in prim.
    // - Fix for #680, bypass waiting prim only if explicitly required
    try_until = gu::datetime::Date::now() + wait_prim_timeout;
    while ((wait_prim == true || start_prim == true) &&
           pc_->state() != pc::Proto::S_PRIM)
    {
        pnet().event_loop(gu::datetime::Sec/2);
        if (try_until < gu::datetime::Date::now())
        {
            pc_->close();
            evs_->close();
            gmcast_->close();
            pnet().erase(&pstack_);
            pstack_.pop_proto(this);
            pstack_.pop_proto(pc_);
            pstack_.pop_proto(evs_);
            pstack_.pop_proto(gmcast_);
            gu_throw_error(ETIMEDOUT) << "failed to reach primary view";
        }
    }

    pc_->set_mtu(mtu());
}
Пример #6
0
 void set_operational(const bool op)
 {
     gcomm_assert(op == false);
     operational_ = op;
 }
 void set_last_prim(const ViewId& vid)
 {
     gcomm_assert(vid.type() == V_PRIM);
     NodeMap::value(self_i_).set_last_prim(vid);
 }