Ejemplo n.º 1
0
///////////////////////////////////////////////////////////////////////////////
/// @fn CConnection::Send
/// @description Given a message and wether or not it should be sequenced,
///   write that message to the channel.
/// @pre The CConnection object is initialized.
/// @post If the window is in not full, the message will have been written to
///   to the channel. Before being sent the message has been signed with the
///   UUID, source hostname and sequence number (if it is being sequenced).
///   If the message is being sequenced  and the window is not already full,
///   the timeout timer is cancelled and reset.
/// @param p_mesg A CMessage to write to the channel.
///////////////////////////////////////////////////////////////////////////////
void CConnection::Send(CMessage & p_mesg)
{
    Logger.Debug << __PRETTY_FUNCTION__ << std::endl;

    // If the UUID of the reciepient (The value stored by GetUUID of this
    // object) is the same as the this node's uuid (As stored by the
    // Connection manager) place the message directly into the recieved
    // Queue.
    if(GetUUID() == GetConnectionManager().GetUUID())
    {
        p_mesg.SetSourceUUID(GetConnectionManager().GetUUID());
        p_mesg.SetSourceHostname(GetConnectionManager().GetHostname());
        p_mesg.SetSendTimestampNow();
        GetDispatcher().HandleRequest(GetBroker(),p_mesg);
        return;
    }

    ProtocolMap::iterator sit = m_protocols.find(p_mesg.GetProtocol());    
    
    if(sit == m_protocols.end())
    {
        sit = m_protocols.find(m_defaultprotocol);
    }
    (*sit).second->Send(p_mesg);
}
Ejemplo n.º 2
0
void CListener::HandleRead(const boost::system::error_code& e, 
                           std::size_t bytes_transferred)
{
    Logger.Debug << __PRETTY_FUNCTION__ << std::endl;       
    if (!e)
    {
        boost::tribool result_;
        boost::tie(result_, boost::tuples::ignore) = Parse(
            m_message, m_buffer.data(),
            m_buffer.data() + bytes_transferred);
        if (result_)
        {
            ptree x = static_cast<ptree>(m_message);
            std::string uuid = m_message.GetSourceUUID();
            remotehost hostname = m_message.GetSourceHostname();
            ///Make sure the hostname is registered:
            GetConnectionManager().PutHostname(uuid,hostname);                        
            ///Get the pointer to the connection:
            CConnection::ConnectionPtr conn;
            conn = GetConnectionManager().GetConnectionByUUID(uuid,
                GetSocket().get_io_service(), GetDispatcher());
#ifdef CUSTOMNETWORK
            if((rand()%100) >= GetReliability())
            {
                Logger.Debug<<"Dropped datagram "<<m_message.GetHash()<<":"
                              <<m_message.GetSequenceNumber()<<std::endl;
                goto listen;
            }
#endif
            if(m_message.GetStatus() == freedm::broker::CMessage::Accepted)
            {
                ptree pp = m_message.GetProtocolProperties();
                size_t hash = pp.get<size_t>("src.hash");
                Logger.Debug<<"Recieved ACK"<<hash<<":"
                                <<m_message.GetSequenceNumber()<<std::endl;
                conn->RecieveACK(m_message);
            }
            else if(conn->Recieve(m_message))
            {
                Logger.Debug<<"Accepted message "<<m_message.GetHash()<<":"
                              <<m_message.GetSequenceNumber()<<std::endl;
                GetDispatcher().HandleRequest(m_message);
            }
            else if(m_message.GetStatus() != freedm::broker::CMessage::Created)
            {
                Logger.Notice<<"Rejected message "<<m_message.GetHash()<<":"
                              <<m_message.GetSequenceNumber()<<std::endl;
            }
        }
listen:
        GetSocket().async_receive_from(boost::asio::buffer(m_buffer, 8192),
                m_endpoint, boost::bind(&CListener::HandleRead, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }
    else
    {
        GetConnectionManager().Stop(CListener::ConnectionPtr(this));	
    }
}
Ejemplo n.º 3
0
  void CSConnectionAcquirer::ServerStateInquire(const Request &request)
  {
    QHash<QByteArray, QUrl> id_to_addr;
    const Id &my_id = GetConnectionManager()->GetId();
    const ConnectionTable &ct = GetConnectionManager()->GetConnectionTable();

    foreach(const PublicIdentity &gc, _group.GetSubgroup()) {
      const Id &gc_id = gc.GetId();
      if(gc_id == my_id) {
        continue;
      }

      QSharedPointer<Connection> con = ct.GetConnection(gc_id);
      if(!con) {
        continue;
      }

      id_to_addr[gc_id.GetByteArray()] =
        con->GetEdge()->GetRemotePersistentAddress().GetUrl();
    }

    QByteArray slm;
    QDataStream out_stream(&slm, QIODevice::WriteOnly);
    out_stream << id_to_addr;

    QVariantHash msg;
    msg["connections"] = ct.GetConnections().size();
    msg["list"] = slm;
    request.Respond(msg);
  }
Ejemplo n.º 4
0
  void CSConnectionAcquirer::RequestServerState(const int &)
  {
    const ConnectionTable &ct = GetConnectionManager()->GetConnectionTable();
    if(ct.GetConnections().size() == 1) {
      return;
    }

    foreach(const PublicIdentity &gc, _group.GetSubgroup()) {
      if(gc.GetId() == GetConnectionManager()->GetId()) {
        continue;
      }
      QSharedPointer<Connection> con = ct.GetConnection(gc.GetId());
      if(con != 0) {
        RequestServerState(con);
        return;
      }
    }

    foreach(const QSharedPointer<Connection> &con, ct.GetConnections()) {
      if(con->GetRemoteId() == GetConnectionManager()->GetId()) {
        continue;
      }
      RequestServerState(con);
      return;
    }
  }
Ejemplo n.º 5
0
///////////////////////////////////////////////////////////////////////////////
/// CConnection::Send
/// @description: Given a message and wether or not it should be sequenced,
///   write that message to the channel.
/// @pre: The CConnection object is initialized.
/// @post: If the window is in not full, the message will have been written to
///   to the channel. Before being sent the message has been signed with the
///   UUID, source hostname and sequence number (if it is being sequenced).
///   If the message is being sequenced  and the window is not already full,
///   the timeout timer is cancelled and reset.
/// @param p_mesg: A CMessage to write to the channel.
/// @param sequence: if true, the message will be sequenced and reliably
///   delievered in order. Otherwise it is immediately fired and forgotten.
///   this is mostly meant for use with ACKs. True by default.
///////////////////////////////////////////////////////////////////////////////
void CConnection::Send(CMessage p_mesg, bool sequence)
{
    Logger::Debug << __PRETTY_FUNCTION__ << std::endl;

    //Make a call to the dispatcher to sign the messages
    //With a bunch of shiny stuff.
    ptree x = static_cast<ptree>(p_mesg);
    unsigned int msgseq;

    //m_dispatch.HandleWrite(x);  

    CMessage outmsg(x);

    // Sign the message with the hostname, uuid, and squencenumber
    if(sequence == true)
    {
        if(m_synched == false)
        {
            m_synched = true;
            SendSYN();
        }
        msgseq = m_outsequenceno;
        outmsg.SetSequenceNumber(msgseq);
        m_outsequenceno = (m_outsequenceno+1) % GetSequenceModulo();
    }
    outmsg.SetSourceUUID(GetConnectionManager().GetUUID()); 
    outmsg.SetSourceHostname(GetConnectionManager().GetHostname());

    if(sequence == true)
    {
        // If it isn't squenced then don't put it in the queue.
        m_queue.Push( QueueItem(msgseq,outmsg) );
    }
    // Before, we would put it into a queue to be sent later, now we are going
    // to immediately write it to channel.

    if(m_queue.size() <= GetWindowSize() || sequence == false)
    {
        // Only try to write to the socket if the window isn't already full.
        // Or it is an unsequenced message
        
        HandleSend(outmsg);
        if(sequence == true)
        {
            m_timeout.cancel();
            m_timeout.expires_from_now(boost::posix_time::milliseconds(1000));
            m_timeout.async_wait(boost::bind(&CConnection::Resend,this,
                boost::asio::placeholders::error));
        }
    }
}
Ejemplo n.º 6
0
int
main( int argc, char **argv )
{    
    LOG_FUNCTION_START();
    LogPrint( "S2Sim Started" );
    
    GetConnectionManager();
    GetMatlabManager();
    GetControlManager();
    GetSystemManager();
    
    auto iterationNumber = 0;
    
    GetControlManager().WaitUntilReady();
    while ( 1 )
    {
        try
        {
            GetSystemManager().AdvanceTimeStep();
        }
        catch ( ... )
        {
            ErrorPrint( "System Error, Exiting" );
            break;
        }
        
        ++iterationNumber;
        LogPrint( "Time: ", iterationNumber );
    }
    LOG_FUNCTION_END();
    return ( EXIT_SUCCESS );
}
Ejemplo n.º 7
0
  void CSOverlay::OnStart()
  {
    _csca = QSharedPointer<CSConnectionAcquirer>(new CSConnectionAcquirer(
        GetConnectionManager(), GetRpcHandler(), _group));
    AddConnectionAcquirer(_csca);

    BaseOverlay::OnStart();
  }
Ejemplo n.º 8
0
  bool CSConnectionAcquirer::CheckAndConnect(const QByteArray &bid, const QUrl &url)
  {
    if(!IsServer()) {
      return false;
    }

    const ConnectionTable &ct = GetConnectionManager()->GetConnectionTable();
    Id id(bid);

    if(id == Id::Zero()) {
      qDebug() << "Found a malformed Id";
      return false;
    } else if(id == GetConnectionManager()->GetId()) {
      // It is me
      return false;
    } else if(ct.GetConnection(id) != 0) {
      // Already connected
      return false;
    } else if(!_group.GetSubgroup().Contains(id)) {
      if(_group.Contains(id)) {
        qWarning() << "Found a connection in another servers list that is not a"
          << "server in my own list:" << id.ToString();
      } else {
        qDebug() << "Found an unknown identity in another servers list:"
          << id.ToString() << "Must have stale info";
      }
      return false;
    }

    if(!url.isValid()) {
      qWarning() << "Remote gave us an invalid url:" << url;
      return false;
    }

    Address addr = Transports::AddressFactory::GetInstance().CreateAddress(url);
    GetConnectionManager()->ConnectTo(addr);
    _local_initiated[id] = true;
    _addr_to_id[addr] = id;
    return true;
  }
Ejemplo n.º 9
0
///////////////////////////////////////////////////////////////////////////////
/// CConnection::HandleWrite
/// @description: Write callback. Closes the connection on error, does nothing
///   otherwise.
/// @param e: The error that occured if any.
/// @pre: A message has been written to the channel.
/// @post: If there was an error the socket has been closed.
///////////////////////////////////////////////////////////////////////////////
void CConnection::HandleWrite(const boost::system::error_code& e)
{
    Logger::Debug << __PRETTY_FUNCTION__ << std::endl;

    if (!e)
    {
        //All good
    }
    if (e == boost::asio::error::operation_aborted)
    {
        GetConnectionManager().Stop(CConnection::ConnectionPtr(this));
    }
}
Ejemplo n.º 10
0
  void CSConnectionAcquirer::ClientHandleServerStateResponse(
      const Id &, const QHash<QByteArray, QUrl> &id_to_addr, int)
  {
    if(id_to_addr.size() == 0) {
      return;
    }

    const ConnectionTable &ct = GetConnectionManager()->GetConnectionTable();
    foreach(const PublicIdentity &gc, _group.GetSubgroup()) {
      if(ct.GetConnection(gc.GetId()) != 0) {
        return;
      }
    }

    QByteArray bid = id_to_addr.keys()[CryptoRandom().GetInt(0, id_to_addr.size())];
    CheckAndConnect(bid, id_to_addr[bid]);
  }
Ejemplo n.º 11
0
  void CSConnectionAcquirer::UpdateGroup(const Group &group)
  {
    _group = group;

    if(!IsServer()) {
      return;
    }

    if(!IsServer() && !_bootstrapping) {
      return;
    }

    foreach(const PublicIdentity &gc, _group.GetSubgroup()) {
      if(GetConnectionManager()->GetConnectionTable().GetConnection(gc.GetId())) {
        continue;
      }
      RequestServerState();
      break;
    }
  }