void InternalConnection::unsubscribe_range(channel_t lo, channel_t hi)
 {
     Datagram dg(CONTROL_REMOVE_RANGE);
     dg.add_channel(lo);
     dg.add_channel(hi);
     send_datagram(dg);
 }
/* \brief Just runs automatic tests

Function sends a number of datagrams, spawns child thread or process and
tries to receive at least one datagram.
\retval 0 datagram was received
\retval -1 datagram was not received
*/
int run_auto_test (const ACE_TCHAR *prog_name)
{
#if defined (ACE_HAS_PROCESS_SPAWN)
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in process mode\n")));

  ACE_Process_Options opts;
  pid_t child_pid;
  opts.command_line (ACE_TEXT ("%s -p %d -t %d -a -r"),
                     prog_name, dgram_port, dgram_recv_timeout.msec ());
  if ((child_pid = ACE_Process_Manager::instance ()->spawn (opts)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n()")), -1);

#elif defined (ACE_HAS_THREADS)
  ACE_UNUSED_ARG (prog_name);
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in thread mode\n")));
  if (ACE_Thread_Manager::instance ()->spawn (run_thread_receiver) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("%p\n"),
                       ACE_TEXT ("spawn_n ()")), -1);
#else
  ACE_ERROR_RETURN ((LM_ERROR,
                     ACE_TEXT ("Cannot run in auto_test mode without fork or threads.\n")),
                      -1);
#endif /* defined (ACE_HAS_PROCESS_SPAWN) */

  ACE_DEBUG ((LM_INFO,
              ACE_TEXT ("Sending datagrams on port %d in auto_test mode\n"),
              dgram_port));

  ACE_SOCK_Dgram_Bcast socket;

  if (socket.open (ACE_Addr::sap_any) != -1)
    {
      // send datagrams until child finishes
      while (1)
        {
          send_datagram (socket, dgrams_no--);
          ACE_Time_Value child_timeout (1);
#if defined (ACE_HAS_PROCESS_SPAWN)

          if (ACE_Process_Manager::instance ()->wait (child_pid,
                                                      child_timeout,
                                                      &receiver_exit_code) == child_pid)
            break;
#else /* ACE_HAS_THREADS */
          // sleep 1 second or wait for child thread
          child_timeout += ACE_OS::gettimeofday () ;
          if (ACE_Thread_Manager::instance ()->wait (&child_timeout) == 0)
            break;
#endif
        }
      socket.close ();
      ACE_DEBUG ((LM_INFO, ACE_TEXT ("Child finished with %d exit code\n"),
                  receiver_exit_code));
    }
  else
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                       ACE_TEXT ("Cannot open broadcast socket")), -1);
  return (receiver_exit_code);
}
Exemple #3
0
int main(int argc, char *argv[])
{
    int port, srvport, retval;
    datagram_t datagram;

    // Check command line arguments
    if (argc != 3) {
        fprintf(stderr, "usage: %s <localport> <serverport>\n", argv[0]);
        exit(-1);
    }
    port = atoi(argv[1]);
    srvport = atoi(argv[2]);

    init_datagram_service(port, DEBUG_ALL);

    // Prepare datagram
    bzero(&datagram, sizeof(datagram));
    strcpy(datagram.srcaddr, "128.2.13.139"); // These should be command line inputs
    strcpy(datagram.dstaddr, "128.2.13.139"); // I am just being lazy here :-).
                                           // replace with your ip values before running
    datagram.srcport = port;
    datagram.dstport = srvport;
    strcpy(datagram.data, "Hello World!");
    datagram.size = 12;

    // Send datagram
    retval = send_datagram(&datagram);
    if (retval < 0) {
        perror("Send error");
    }
    printf("Sent %d bytes\n", retval);

    return 0;
}
Exemple #4
0
void Host::network_tick()
{

	while (!commands_.empty() && commands_.front().get_time() == virtual_time_)
	{
		Command command = commands_.front();
		commands_.pop();
		std::string cmd_string = command.get_command();

		if (service_type_ == IRCC)
			application_->process_command(cmd_string, *this);
	}

	if (!send_datagram_queue.empty())
		if (send_datagram(send_datagram_queue.front()))
			send_datagram_queue.pop();

	if (!received_datagram_queue.empty()) {
		// Recolhe os datagramas da fila de datagramas recebidos (provavelmente
		// vai ser só 1 por vez, mas né) e manipula ele do jeito que precisa.
		// Provavelmente o melhor a se fazer é algo como, enviar para a
		// aplicação, que daí ela processa esse datagrama e depois converte isso
		// em novos datagramas pra serem enviados.
		application_->receive_datagram(received_datagram_queue.front(), *this);
		received_datagram_queue.pop();
	}

	virtual_time_ += 1;
}
void MDNetworkParticipant::handle_datagram(DatagramHandle dg, DatagramIterator&)
{
	logger().trace() << "MDNetworkParticipant sending to downstream MD" << std::endl;
	try
	{
		send_datagram(dg);
	}
	catch(boost::system::system_error &e)
	{
		logger().warning() << "Received a system error while sending a datagram to a network "
		                   "participant (the participant may have lost connection)." << std::endl;
		return;
	}
}
/*\brief Send a sequence of datagrams with 1 second period
  \note Th function employs dgram_port and dgrams_no global variables
  \retval -1 if error
  \retval 0 if sent
*/
int run_sender( )
{
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("Sending %d datagrams on port %d\n"),
                dgrams_no,
                dgram_port));
    ACE_SOCK_Dgram_Bcast socket;

    if (socket.open (ACE_Addr::sap_any) != -1)
      {
        while (dgrams_no-- != 0)
          {
            if (send_datagram (socket, dgrams_no) < 0)
              break;
            ACE_OS::sleep (1);
          }
        socket.close ();
        return (0);
      }

    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                       ACE_TEXT ("Cannot open broadcast socket")), -1);
}
 void InternalConnection::set_conn_name(std::string name)
 {
     Datagram dg(CONTROL_SET_CON_NAME);
     dg.add_string(name);
     send_datagram(dg);
 }
 void InternalConnection::set_conn_url(std::string uri)
 {
     Datagram dg(CONTROL_SET_CON_URL);
     dg.add_string(uri);
     send_datagram(dg);
 }
 void InternalConnection::clear_post_removes()
 {
     send_datagram(Datagram(CONTROL_CLEAR_POST_REMOVES));
 }
 void InternalConnection::add_post_remove(const Datagram &post)
 {
     Datagram dg(CONTROL_ADD_POST_REMOVE);
     dg.add_blob(post);
     send_datagram(dg);
 }
 void InternalConnection::unsubscribe_channel(channel_t channel)
 {
     Datagram dg(CONTROL_REMOVE_CHANNEL);
     dg.add_channel(channel);
     send_datagram(dg);
 }
Exemple #12
0
// handle_datagram is the handler for datagrams received from the Astron cluster
void Client::handle_datagram(Datagram &dg, DatagramIterator &dgi)
{
	channel_t sender = dgi.read_uint64();
	uint16_t msgtype = dgi.read_uint16();
	switch(msgtype)
	{
		case CLIENTAGENT_EJECT:
		{
			uint16_t reason = dgi.read_uint16();
			std::string error_string = dgi.read_string();
			send_disconnect(reason, error_string);
			return;
		}
		break;
		case CLIENTAGENT_DROP:
		{
			handle_drop();
			return;
		}
		break;
		case CLIENTAGENT_SET_STATE:
		{
			m_state = (ClientState)dgi.read_uint16();
		}
		break;
		case STATESERVER_OBJECT_SET_FIELD:
		{
			uint32_t do_id = dgi.read_uint32();
			if(!lookup_object(do_id))
			{
				m_log->warning() << "Received server-side field update for unknown object " << do_id << std::endl;
				return;
			}
			if(sender != m_channel)
			{
				uint16_t field_id = dgi.read_uint16();
				handle_set_field(do_id, field_id, dgi);
			}
		}
		break;
		case STATESERVER_OBJECT_DELETE_RAM:
		{
			uint32_t do_id = dgi.read_uint32();
			if(!lookup_object(do_id))
			{
				m_log->warning() << "Received server-side object delete for unknown object " << do_id << std::endl;
				return;
			}

			if(m_seen_objects.find(do_id) != m_seen_objects.end())
			{
				m_seen_objects.erase(do_id);
				m_id_history.insert(do_id);
				handle_remove_object(do_id);
			}

			if(m_owned_objects.find(do_id) != m_owned_objects.end())
			{
				m_owned_objects.erase(do_id);
				handle_remove_ownership(do_id);
			}

			m_dist_objs.erase(do_id);
		}
		break;
		case STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER:
        case STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED:
		{
			uint32_t do_id = dgi.read_uint32();
			uint32_t parent = dgi.read_uint32();
			uint32_t zone = dgi.read_uint32();
			uint16_t dc_id = dgi.read_uint16();
			m_owned_objects.insert(do_id);

			if(m_dist_objs.find(do_id) == m_dist_objs.end())
			{
				VisibleObject obj;
				obj.id = do_id;
				obj.parent = parent;
				obj.zone = zone;
				obj.dcc = g_dcf->get_class(dc_id);
				m_dist_objs[do_id] = obj;
			}

			handle_add_ownership(do_id, parent, zone, dc_id, dgi, true);
		}
		break;
		case CLIENTAGENT_SET_CLIENT_ID:
		{
			if(m_channel != m_allocated_channel)
			{
				unsubscribe_channel(m_channel);
			}

			m_channel = dgi.read_uint64();
			subscribe_channel(m_channel);
		}
		break;
		case CLIENTAGENT_SEND_DATAGRAM:
		{
			Datagram forward;
			forward.add_data(dgi.read_string());
			send_datagram(forward);
		}
		break;
		case CLIENTAGENT_OPEN_CHANNEL:
		{
			subscribe_channel(dgi.read_uint64());
		}
		break;
		case CLIENTAGENT_CLOSE_CHANNEL:
		{
			unsubscribe_channel(dgi.read_uint64());
		}
		break;
		case CLIENTAGENT_ADD_POST_REMOVE:
		{
			add_post_remove(dgi.read_string());
		}
		break;
		case CLIENTAGENT_CLEAR_POST_REMOVES:
		{
			clear_post_removes();
		}
		break;
		case STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED:
		case STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER:
		{
			uint32_t do_id = dgi.read_uint32();
			uint32_t parent = dgi.read_uint32();
			uint32_t zone = dgi.read_uint32();
			uint16_t dc_id = dgi.read_uint16();
			if(m_owned_objects.find(do_id) != m_owned_objects.end() ||
			        m_seen_objects.find(do_id) != m_seen_objects.end())
			{
				return;
			}
			if(m_dist_objs.find(do_id) == m_dist_objs.end())
			{
				VisibleObject obj;
				obj.id = do_id;
				obj.dcc = g_dcf->get_class(dc_id);
				obj.parent = parent;
				obj.zone = zone;
				m_dist_objs[do_id] = obj;
			}
			m_seen_objects.insert(do_id);

			handle_add_object(do_id, parent, zone, dc_id, dgi,
			                  msgtype == STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER);

			// TODO: This is a tad inefficient as it checks every pending interest.
			// In practice, there shouldn't be many add-interest operations active
			// at once, however.
			std::list<uint32_t> deferred_deletes;
			for(auto it = m_pending_interests.begin(); it != m_pending_interests.end(); ++it)
			{
				if(it->second->is_ready(m_dist_objs))
				{
					handle_interest_done(it->second->m_interest_id, it->second->m_client_context);
					deferred_deletes.push_back(it->first);
				}
			}
			for(auto it = deferred_deletes.begin(); it != deferred_deletes.end(); ++it)
			{
				m_pending_interests.erase(*it);
			}
		}
		break;
		case STATESERVER_OBJECT_GET_ZONES_COUNT_RESP:
		{
			uint32_t context = dgi.read_uint32();
			uint32_t count = dgi.read_uint32();

			if(m_pending_interests.find(context) == m_pending_interests.end())
			{
				m_log->error() << "Received GET_ZONES_COUNT_RESP for unknown context "
				               << context << std::endl;
				return;
			}

			m_pending_interests[context]->store_total(count);

			if(m_pending_interests[context]->is_ready(m_dist_objs))
			{
				handle_interest_done(m_pending_interests[context]->m_interest_id,
				                     m_pending_interests[context]->m_client_context);
				m_pending_interests.erase(context);
			}
		}
		break;
		case STATESERVER_OBJECT_CHANGING_LOCATION:
		{
			uint32_t do_id = dgi.read_uint32();
			uint32_t n_parent = dgi.read_uint32();
			uint32_t n_zone = dgi.read_uint32();
			dgi.read_uint32(); // Old parent; we don't care about this.
			dgi.read_uint32(); // Old zone; we don't care about this.
			bool disable = true;
			for(auto it = m_interests.begin(); it != m_interests.end(); ++it)
			{
				Interest &i = it->second;
				for(auto it2 = i.zones.begin(); it2 != i.zones.end(); ++it2)
				{
					if(*it2 == n_zone)
					{
						disable = false;
						break;
					}
				}
			}

			if(m_dist_objs.find(do_id) != m_dist_objs.end())
			{
				m_dist_objs[do_id].parent = n_parent;
				m_dist_objs[do_id].zone = n_zone;
			}

			if(disable && m_owned_objects.find(do_id) == m_owned_objects.end())
			{
				handle_remove_object(do_id);
				m_seen_objects.erase(do_id);
				m_dist_objs.erase(do_id);
			}
			else
			{
				handle_change_location(do_id, n_parent, n_zone);
			}
		}
		break;
		default:
			m_log->error() << "Recv'd unk server msgtype " << msgtype << std::endl;
	}
}