예제 #1
0
    void run ()
    {
        uint16 raport = sConfig.GetIntDefault ("Ra.Port", 3443);
        std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0");

        ACE_INET_Addr listen_addr(raport, stringip.c_str());

        if (m_Acceptor->open (listen_addr, m_Reactor, ACE_NONBLOCK) == -1)
        {
            sLog.outError ("MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str ());
        }

        sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ());

        while (!m_Reactor->reactor_event_loop_done())
        {
            ACE_Time_Value interval (0, 10000);

            if (m_Reactor->run_reactor_event_loop (interval) == -1)
                break;

            if(World::IsStopped())
            {
                m_Acceptor->close();
                break;
            }
        }
        sLog.outString("RARunnable thread ended");
    }
예제 #2
0
void RARunnable::run()
{
    if (!sConfig->GetBoolDefault("Ra.Enable", false))
        return;

    ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor;

    uint16 raport = sConfig->GetIntDefault("Ra.Port", 3443);
    std::string stringip = sConfig->GetStringDefault("Ra.IP", "0.0.0.0");

    ACE_INET_Addr listen_addr(raport, stringip.c_str());

    if (acceptor.open(listen_addr, m_Reactor) == -1)
    {
        sLog->outError("Trinity RA can not bind to port %d on %s", raport, stringip.c_str());
        return;
    }

    sLog->outString("Starting Trinity RA on port %d on %s", raport, stringip.c_str());

    while (!World::IsStopped())
    {
        // don't be too smart to move this outside the loop
        // the run_reactor_event_loop will modify interval
        ACE_Time_Value interval(0, 100000);

        if (m_Reactor->run_reactor_event_loop(interval) == -1)
            break;
    }

    sLog->outStaticDebug("Trinity RA thread exiting");
}
예제 #3
0
/** \brief convert the object into a string
 */
std::string	tcp_resp_t::to_string()	const throw()
{
	// handle the null case
	if( is_null() )	return "null";
	// return the listen_addr_t in a string
	return listen_addr().to_string();
}
예제 #4
0
void RARunnable::run()
{
    if (!ConfigMgr::GetBoolDefault("Ra.Enable", false))
        return;

    ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor;

    uint16 raport = uint16(ConfigMgr::GetIntDefault("Ra.Port", 3443));
    std::string stringip = ConfigMgr::GetStringDefault("Ra.IP", "0.0.0.0");
    ACE_INET_Addr listen_addr(raport, stringip.c_str());

    if (acceptor.open(listen_addr, m_Reactor) == -1)
    {
        TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Trinity RA can not bind to port %d on %s", raport, stringip.c_str());
        return;
    }

    TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Starting Trinity RA on port %d on %s", raport, stringip.c_str());

    while (!World::IsStopped())
    {
        // don't be too smart to move this outside the loop
        // the run_reactor_event_loop will modify interval
        ACE_Time_Value interval(0, 100000);
        if (m_Reactor->run_reactor_event_loop(interval) == -1)
            break;
    }

    TC_LOG_DEBUG(LOG_FILTER_WORLDSERVER, "Trinity RA thread exiting");
}
예제 #5
0
void SocketConnectorRunnable::run()
{
    if (!ConfigMgr::GetBoolDefault("SocketConnector.Enable", false))
        return;
    
    ACE_Acceptor<SocketConnector, ACE_SOCK_ACCEPTOR> acceptor;

    uint16 SocketConnectorPort = ConfigMgr::GetIntDefault("SocketConnector.Port", 3448);
    std::string stringip = ConfigMgr::GetStringDefault("SocketConnector.IP", "0.0.0.0");

    ACE_INET_Addr listen_addr(SocketConnectorPort, stringip.c_str());

    if (acceptor.open(listen_addr, m_Reactor) == -1)
    {
        sLog->outError(LOG_FILTER_WORLDSERVER, "Trinity Socket Connector can not bind to port %d on %s", SocketConnectorPort, stringip.c_str());
        return;
    }

    sLog->outInfo(LOG_FILTER_WORLDSERVER, "Starting Trinity Socket Connector on port %d on %s", SocketConnectorPort, stringip.c_str());

    while (!World::IsStopped())
    {
        // don't be too smart to move this outside the loop
        // the run_reactor_event_loop will modify interval
        ACE_Time_Value interval(0, 100000);

        if (m_Reactor->run_reactor_event_loop(interval) == -1)
            break;
    }

    sLog->outDebug(LOG_FILTER_WORLDSERVER, "Trinity Socket Connector thread exiting");
}
예제 #6
0
/** \brief convert the object to a string
 */
std::string	socket_resp_udp_t::to_string()					const throw()
{
	std::ostringstream	oss;
	// build the string
	oss << "listening on "	<< listen_addr() << " in " << type();
	// return the just built string
	return oss.str();	
}
예제 #7
0
/** \brief set the callback
 */
socket_err_t	socket_resp_udp_t::setup(const socket_type_t &p_socket_type
				, const socket_addr_t &p_listen_addr
				, socket_resp_vapi_cb_t *callback, void* userptr)	throw()
{
	// copy the parameter
	this->m_socket_type	= p_socket_type;
	this->m_listen_addr	= p_listen_addr;
	this->callback		= callback;
	this->userptr		= userptr;
	// copy the listen_addr
	DBG_ASSERT( domain() == listen_addr().get_domain() );
	// return noerror
	return socket_err_t::OK;
}
예제 #8
0
파일: dump.c 프로젝트: MrJoe/gtk-gnutella
/**
 * Dump relayed or locally-emitted packet.
 * If ``from'' is NULL, packet was emitted locally.
 */
static void
dump_packet_from_to(struct dump *dump,
	const struct gnutella_node *from, const struct gnutella_node *to,
	const pmsg_t *mb)
{
	struct dump_header dh_to;	
	struct dump_header dh_from;	

	g_assert(to != NULL);
	g_assert(mb != NULL);
	g_assert(pmsg_read_base(mb) == pmsg_start(mb));

	if (!dump_initialize(dump))
		return;

	/*
	 * This is only for Gnutella packets, leave DHT messages out.
	 */

	if (GTA_MSG_DHT == gnutella_header_get_function(pmsg_start(mb)))
		return;

	if (!ipset_contains_addr(&dump_tx_to_addrs, to->addr, TRUE))
		return;

	if (NULL == from) {
		struct gnutella_node local;
		local.peermode = NODE_IS_UDP(to) ? NODE_P_UDP : NODE_P_NORMAL;
		local.addr = listen_addr();
		local.port = GNET_PROPERTY(listen_port);
		if (!ipset_contains_addr(&dump_tx_from_addrs, local.addr, TRUE))
			return;
		dump_header_set(&dh_from, &local);
	} else {
		if (!ipset_contains_addr(&dump_tx_from_addrs, from->addr, TRUE))
			return;
		dump_header_set(&dh_from, from);
	}

	dump_header_set(&dh_to, to);
	dh_to.data[0] |= DH_F_TO;
	if (pmsg_prio(mb) != PMSG_P_DATA)
		dh_to.data[0] |= DH_F_CTRL;
		
	dump_append(dump, dh_to.data, sizeof dh_to.data);
	dump_append(dump, dh_from.data, sizeof dh_from.data);
	dump_append(dump, pmsg_read_base(mb), pmsg_size(mb));
	dump_flush(dump);
}
예제 #9
0
/** \brief Start the operation
 */
socket_err_t	socket_resp_udp_t::start()					throw()
{
	inet_err_t	inet_err;
	nlay_err_t	nlay_err;
	// sanity check - the mandatory parameter MUST be set
	DBG_ASSERT( !listen_addr().is_null() );
	DBG_ASSERT( !type().is_null() );
	DBG_ASSERT(  callback );
	// sanity check - the profile MUST valid
	DBG_ASSERT( profile().check().succeed() );

// SETUP UDP_RESP_T
	udp_resp	= nipmem_new udp_resp_t();
	// get the listen address
	ipport_addr_t	ipport_addr	= socket_helper_udp_t::ipport_addr(listen_addr());
	// start the udp_resp_t
	inet_err	= udp_resp->start(ipport_addr, this, NULL);
	if( inet_err.failed() )	return socket_err_from_inet(inet_err, "Can't start udp_resp due to " );

	// reread the listen_addr() once the responder is bound, in case of dynamic part
	m_listen_addr	= socket_addr_t(domain().to_string() + "://" + udp_resp->get_listen_addr().to_string());
	DBG_ASSERT( !listen_addr().is_null() );
	
// SETUP NLAY_RESP_T
	// start the nlay_resp_t
	socket_profile_udp_t &	profile_dom	= socket_profile_udp_t::from_socket(m_socket_profile);
	nlay_resp	= nipmem_new nlay_resp_t(&profile_dom, type().to_nlay(), nlay_type_t::DGRAM);
	nlay_err  	= nlay_resp->start();
	if( nlay_err.failed() ){
		nipmem_zdelete udp_resp;
		return socket_err_from_nlay(nlay_err, "Can't start nlay_resp due to ");
	}
	
	// return no error	
	return socket_err_t::OK;
}
예제 #10
0
int
WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
{
    m_UseNoDelay = sConfig->GetBoolDefault ("Network.TcpNodelay", true);

    int num_threads = sConfig->GetIntDefault ("Network.Threads", 1);

    if (num_threads <= 0)
    {
        sLog->outError ("Network.Threads is wrong in your config file");
        return -1;
    }

    m_NetThreadsCount = static_cast<size_t> (num_threads + 1);

    m_NetThreads = new ReactorRunnable[m_NetThreadsCount];

    sLog->outBasic ("Max allowed socket connections %d", ACE::max_handles());

    // -1 means use default
    m_SockOutKBuff = sConfig->GetIntDefault ("Network.OutKBuff", -1);

    m_SockOutUBuff = sConfig->GetIntDefault ("Network.OutUBuff", 65536);

    if (m_SockOutUBuff <= 0)
    {
        sLog->outError ("Network.OutUBuff is wrong in your config file");
        return -1;
    }

    WorldSocket::Acceptor *acc = new WorldSocket::Acceptor;
    m_Acceptor = acc;

    ACE_INET_Addr listen_addr (port, address);

    if (acc->open(listen_addr, m_NetThreads[0].GetReactor(), ACE_NONBLOCK) == -1)
    {
        sLog->outError ("Failed to open acceptor ,check if the port is free");
        return -1;
    }

    for (size_t i = 0; i < m_NetThreadsCount; ++i)
        m_NetThreads[i].Start();

    return 0;
}
예제 #11
0
/** \brief convert the object into a string
 */
std::string	udp_resp_t::to_string()	const throw()
{
	if( is_null() )	return "null";
	return listen_addr().to_string();
}
예제 #12
0
/** \brief start the action
 */
inet_err_t	udp_resp_t::start()						throw()
{
	struct 	sockaddr_in	addr_in;
	std::string		errstr;
	inet_err_t		inet_err;
	// check the parameter
	DBG_ASSERT( !listen_addr().is_null() );
		
	// create the socket
	int	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if( sock_fd < 0 ){
		errstr = "Cant create socket. errno=" + inet_oswarp_t::sock_strerror();
		goto error;
	}

	// bind the socket (with no SO_REUSEADDR)
	addr_in = listen_addr().to_sockaddr_in();
	if( bind(sock_fd, (struct sockaddr *)&addr_in, sizeof(addr_in)) ){
		errstr = "cant bind socket to " + listen_addr().to_string() 
						+ " errno=" + inet_oswarp_t::sock_strerror();
		goto close_socket;
	}
	// if the listen port was undefined, read the one assigned by the system
	if( listen_addr().port() == 0 ){
		socklen_t	addrlen = sizeof(addr_in);
		if( getsockname(sock_fd, (struct sockaddr *)&addr_in, &addrlen)){
			errstr = "cant getsocketname errno=" + inet_oswarp_t::sock_strerror();
			goto close_socket;
		}
		m_listen_addr = ipport_addr_t(addr_in);
	}

	// set this socket in non blocking for the connection
	inet_err	= inet_oswarp_t::set_nonblock(sock_fd);
	if( inet_err.failed() ){
		errstr = inet_err.to_string();
		goto close_socket;
	}


	// if the local_ipport has a multicast ip address, join the multicast group
	if( listen_addr().ipaddr().is_multicast() ){
		struct ip_mreq	mreq;
		// describe the group
		mreq.imr_multiaddr.s_addr = htonl(listen_addr().ipaddr().get_v4_addr());
		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
		// do the IP_ADD_MEMBERSHIP
		inet_err	= inet_oswarp_t::setsockopt(fdwatch->get_fd(), IPPROTO_IP
						, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
		if( inet_err.failed() ){
			errstr = "cant ADD_MEMBERSHIP to socket " + listen_addr().to_string()
						+ " due to " + inet_err.to_string();
			goto close_socket;
		}
	}

	// some logging
	KLOG_DBG("udp_resp_t created on " << listen_addr());		

	// start the fdwatch
	fdwatch = nipmem_new fdwatch_t();
	fdwatch->start(sock_fd, fdwatch_t::INPUT, this, NULL);
	// return no error
	return inet_err_t::OK;
	
close_socket:;	inet_oswarp_t::close_fd( sock_fd );
error:;		return inet_err_t(inet_err_t::SYSTEM_ERR, errstr);
}
예제 #13
0
/**
 * Displays assorted status information
 */
enum shell_reply
shell_exec_status(struct gnutella_shell *sh, int argc, const char *argv[])
{
	const char *cur;
	const option_t options[] = {
		{ "i", &cur },
	};
	int parsed;
	char buf[2048];
	time_t now;

	shell_check(sh);
	g_assert(argv);
	g_assert(argc > 0);

	parsed = shell_options_parse(sh, argv, options, G_N_ELEMENTS(options));
	if (parsed < 0)
		return REPLY_ERROR;

	argv += parsed;	/* args[0] is first command argument */
	argc -= parsed;	/* counts only command arguments now */

	now = tm_time();

	/* Leading flags */
	{
		char flags[47];
		const char *fw;
		const char *fd;
		const char *pmp;
		const char *dht;

		/*
		 * The flags are displayed as followed:
		 *
		 * UMP          port mapping configured via UPnP
		 * NMP          port mapping configured via NAT-PMP
		 * pmp          port mapping available (UPnP or NAT-PMP), un-configured
		 * CLK			clock, GTKG expired
		 * !FD or FD	red or yellow bombs for fd shortage
		 * STL			upload stalls
		 * gUL/yUL/rUL  green, yellow or red upload early stalling levels
		 * CPU			cpu overloaded
		 * MOV			file moving
		 * SHA			SHA-1 rebuilding or verifying
		 * TTH			TTH rebuilding or verifying
		 * LIB			library rescan
		 * :FW or FW	indicates whether hole punching is possible
		 * udp or UDP	indicates UDP firewalling (lowercased for hole punching)
		 * TCP			indicates TCP-firewalled
		 * -			the happy face: no firewall
		 * sDH/lDH/bDH  seeded, own KUID looking or bootstrapping DHT
		 * A or P       active or passive DHT mode
		 * UP or LF		ultrapeer or leaf mode
		 */

		pmp = (GNET_PROPERTY(upnp_possible) || GNET_PROPERTY(natpmp_possible))
			? "pmp " : empty;
		if (
			(GNET_PROPERTY(enable_upnp) || GNET_PROPERTY(enable_natpmp)) &&
			GNET_PROPERTY(port_mapping_successful)
		) {
			pmp = GNET_PROPERTY(enable_natpmp) ? "NMP " : "UMP ";
		}

		if (dht_enabled()) {
			dht = empty;
			switch ((enum dht_bootsteps) GNET_PROPERTY(dht_boot_status)) {
			case DHT_BOOT_NONE:
			case DHT_BOOT_SHUTDOWN:
				break;
			case DHT_BOOT_SEEDED:
				dht = "sDH ";
				break;
			case DHT_BOOT_OWN:
				dht = "lDH ";
				break;
			case DHT_BOOT_COMPLETING:
				dht = "bDH ";
				break;
			case DHT_BOOT_COMPLETED:
				dht = dht_is_active() ? "A " : "P ";
				break;
			case DHT_BOOT_MAX_VALUE:
				g_assert_not_reached();
			}
		} else {
			dht = empty;
		}

		if (GNET_PROPERTY(is_firewalled) && GNET_PROPERTY(is_udp_firewalled)) {
			fw = GNET_PROPERTY(recv_solicited_udp) ? ":FW " : "FW ";
		} else if (GNET_PROPERTY(is_firewalled)) {
			fw = "TCP ";
		} else if (GNET_PROPERTY(is_udp_firewalled)) {
			fw = GNET_PROPERTY(recv_solicited_udp) ? "udp " : "UDP ";
		} else {
			fw = "- ";
		}

		if (GNET_PROPERTY(file_descriptor_runout)) {
			fd = "!FD ";
		} else if (GNET_PROPERTY(file_descriptor_shortage)) {
			fd = "FD ";
		} else {
			fd = empty;
		}

		gm_snprintf(flags, sizeof flags,
			"<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>",
			pmp,
			GNET_PROPERTY(download_queue_frozen) ? "DFZ " : empty,
			GNET_PROPERTY(ancient_version) ? "CLK " : empty,
			fd,
			GNET_PROPERTY(uploads_stalling) ? "STL " : empty,
			GNET_PROPERTY(uploads_bw_ignore_stolen) ? "gUL " : empty,
			GNET_PROPERTY(uploads_bw_uniform) ? "yUL " : empty,
			GNET_PROPERTY(uploads_bw_no_stealing) ? "rUL " : empty,
			GNET_PROPERTY(overloaded_cpu) ? "CPU " : empty,
			GNET_PROPERTY(file_moving) ? "MOV " : empty,
			(GNET_PROPERTY(sha1_rebuilding) || GNET_PROPERTY(sha1_verifying)) ?
				"SHA " : empty,
			(GNET_PROPERTY(tth_rebuilding) || GNET_PROPERTY(tth_verifying)) ?
				"TTH " : empty,
			GNET_PROPERTY(library_rebuilding) ? "LIB " : empty,
			fw, dht,
			settings_is_ultra() ? "UP" : "LF");

		gm_snprintf(buf, sizeof buf,
			"+%s+\n"
			"| %-18s%51s |\n"
			"|%s|\n",
			dashes, "Status", flags, equals);
		shell_write(sh, buf);
	}

	/* General status */ 
	{
		const char *blackout;
		short_string_t leaf_switch;
		short_string_t ultra_check;
	
		leaf_switch = timestamp_get_string(
						GNET_PROPERTY(node_last_ultra_leaf_switch));
		ultra_check = timestamp_get_string(
						GNET_PROPERTY(node_last_ultra_check));

		if (GNET_PROPERTY(is_firewalled) && GNET_PROPERTY(is_udp_firewalled)) {
			blackout =
				GNET_PROPERTY(recv_solicited_udp) ?  "TCP,udp" : "TCP,UDP";
		} else if (GNET_PROPERTY(is_firewalled)) {
			blackout = "TCP";
		} else if (GNET_PROPERTY(is_udp_firewalled)) {
			blackout = GNET_PROPERTY(recv_solicited_udp) ? "udp" : "UDP";
		} else {
			blackout = "None";
		}

		gm_snprintf(buf, sizeof buf,
			"|   Mode: %-9s                   Last Switch: %-19s%2s|\n"
			"| Uptime: %-9s                    Last Check: %-19s%2s|\n"
			"|   Port: %-9u                      Blackout: %-7s%14s|\n"
			"|%s|\n",
			GNET_PROPERTY(online_mode)
				? node_peermode_to_string(GNET_PROPERTY(current_peermode))
				: "offline",
			GNET_PROPERTY(node_last_ultra_leaf_switch)
				? leaf_switch.str : "never", space,
			short_time(delta_time(now, GNET_PROPERTY(start_stamp))),
			GNET_PROPERTY(node_last_ultra_check)
				? ultra_check.str : "never", space,
			socket_listen_port(), blackout, space,
			equals);
		shell_write(sh, buf);
	}

	/* IPv4 info */ 
	switch (GNET_PROPERTY(network_protocol)) {
	case NET_USE_BOTH:
	case NET_USE_IPV4:
		gm_snprintf(buf, sizeof buf,
			"| IPv4: %-44s Since: %-12s|\n",
			host_addr_to_string(listen_addr()),
			short_time(delta_time(now, GNET_PROPERTY(current_ip_stamp))));
		shell_write(sh, buf);
	}

	/* IPv6 info */ 
	switch (GNET_PROPERTY(network_protocol)) {
	case NET_USE_BOTH:
		gm_snprintf(buf, sizeof buf, "|%s|\n", dashes);
		shell_write(sh, buf);
		/* FALL THROUGH */
	case NET_USE_IPV6:
		gm_snprintf(buf, sizeof buf,
			"| IPv6: %-44s Since: %-12s|\n",
			host_addr_to_string(listen_addr6()),
			short_time(delta_time(now, GNET_PROPERTY(current_ip6_stamp))));
		shell_write(sh, buf);
	}

	/* Node counts */
	gm_snprintf(buf, sizeof buf,
		"|%s|\n"
		"| Peers: %-7u Ultra %4u/%-7u  Leaf %4u/%-6u  Legacy %4u/%-4u |\n"
		"|            Downloads %4u/%-4u  Uploads %4u/%-7u Browse %4u/%-4u |\n"
		"|%s|\n",
		equals,
		GNET_PROPERTY(node_ultra_count)
			+ GNET_PROPERTY(node_leaf_count)
			+ GNET_PROPERTY(node_normal_count),
		GNET_PROPERTY(node_ultra_count),
		settings_is_ultra() ?
			GNET_PROPERTY(max_connections) : GNET_PROPERTY(max_ultrapeers),
		GNET_PROPERTY(node_leaf_count),
		GNET_PROPERTY(max_leaves),
		GNET_PROPERTY(node_normal_count),
		GNET_PROPERTY(normal_connections),
		GNET_PROPERTY(dl_active_count), GNET_PROPERTY(dl_running_count),
		GNET_PROPERTY(ul_running), GNET_PROPERTY(ul_registered),
		GNET_PROPERTY(html_browse_served) + GNET_PROPERTY(qhits_browse_served),
		GNET_PROPERTY(html_browse_count) + GNET_PROPERTY(qhits_browse_count),
		equals);
	shell_write(sh, buf);

	/* Bandwidths */
	{	
		const bool metric = GNET_PROPERTY(display_metric_units);
		short_string_t gnet_in, http_in, leaf_in, gnet_out, http_out, leaf_out;
		short_string_t dht_in, dht_out;
		gnet_bw_stats_t bw_stats, bw2_stats;
		const char *bwtype = cur ? "(cur)" : "(avg)";

		gnet_get_bw_stats(BW_GNET_IN, &bw_stats);
		gnet_get_bw_stats(BW_GNET_UDP_IN, &bw2_stats);
		gnet_in = short_rate_get_string(
			cur ? bw_stats.current + bw2_stats.current
				: bw_stats.average + bw2_stats.average, metric);

		gnet_get_bw_stats(BW_GNET_OUT, &bw_stats);
		gnet_get_bw_stats(BW_GNET_UDP_OUT, &bw2_stats);
		gnet_out = short_rate_get_string(
			cur ? bw_stats.current + bw2_stats.current
				: bw_stats.average + bw2_stats.average, metric);
		
		gnet_get_bw_stats(BW_HTTP_IN, &bw_stats);
		http_in = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);
		
		gnet_get_bw_stats(BW_HTTP_OUT, &bw_stats);
		http_out = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);
		
		gnet_get_bw_stats(BW_LEAF_IN, &bw_stats);
		leaf_in = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);

		gnet_get_bw_stats(BW_LEAF_OUT, &bw_stats);
		leaf_out = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);

		gnet_get_bw_stats(BW_DHT_IN, &bw_stats);
		dht_in = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);

		gnet_get_bw_stats(BW_DHT_OUT, &bw_stats);
		dht_out = short_rate_get_string(
			cur ? bw_stats.current : bw_stats.average, metric);

		gm_snprintf(buf, sizeof buf,
			"| %-70s|\n"
			"|%71s|\n"
			"| %5s  In:  %13s %13s %13s %13s   |\n"
			"| %5s Out:  %13s %13s %13s %13s   |\n",
			"Bandwidth:"
				"       Gnutella          Leaf          HTTP           DHT",
			dashes,
			bwtype, gnet_in.str, leaf_in.str, http_in.str, dht_in.str,
			bwtype, gnet_out.str, leaf_out.str, http_out.str, dht_out.str);
		shell_write(sh, buf);
	}
	
	{
		char line[128];
		bool metric = GNET_PROPERTY(display_metric_units);

		gm_snprintf(buf, sizeof buf, "|%s|\n", equals);
		shell_write(sh, buf);
		concat_strings(line, sizeof line,
			"Shares ",
			uint64_to_string(shared_files_scanned()),
			" file",
			shared_files_scanned() == 1 ? "" : "s",
			" ",
			short_kb_size(shared_kbytes_scanned(), metric),
			" total",
			(void *) 0);
		gm_snprintf(buf, sizeof buf,
			"| %-35s Up: %-11s Down: %-11s |\n",
			line,
			short_byte_size(GNET_PROPERTY(ul_byte_count), metric),
			short_byte_size2(GNET_PROPERTY(dl_byte_count), metric));
		shell_write(sh, buf);
		gm_snprintf(buf, sizeof buf, "+%s+\n", dashes);
		shell_write(sh, buf);
	}

	return REPLY_READY;
}
예제 #14
0
/** \brief start the action
 */
inet_err_t	tcp_resp_t::start(const ipport_addr_t &p_listen_addr
				, tcp_resp_cb_t *callback, void *userptr)	throw()
{
	struct 	sockaddr_in	addr_in;
	std::string		errstr;
	inet_err_t		inet_err;

	// copy some parameter
	this->m_listen_addr	= p_listen_addr;
	this->callback		= callback;
	this->userptr		= userptr;
	// sanity check - the listen_addr MUST be non null
	DBG_ASSERT( !listen_addr().is_null() );
		
	// create the socket
	int	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
	if( sock_fd < 0 ){
		errstr = "Cant create socket. due to " + inet_oswarp_t::sock_strerror();
		goto error;
	}
	// set REUSEADDR
	inet_err	= inet_oswarp_t::set_reuseaddr(sock_fd);
	if( inet_err.failed() ){
		errstr = "setsockopt SO_REUSEADDR failed due to " + inet_err.to_string();
		goto close_socket;
	}

	// bind the socket   	
	addr_in = listen_addr().to_sockaddr_in();
	if( bind(sock_fd, (struct sockaddr *)&addr_in, sizeof(addr_in)) ){
		errstr = "cant bind socket to " + listen_addr().to_string() 
				+ " due to " + inet_oswarp_t::sock_strerror();
		goto close_socket;
	}

	// if the listen port was undefined, read the one assigned by the system
	if( listen_addr().get_port() == 0 ){
		socklen_t	addrlen = sizeof(addr_in);
		if( getsockname(sock_fd, (struct sockaddr *)&addr_in, &addrlen)){
			errstr = "cant getsocketname due to " + inet_oswarp_t::sock_strerror();
			goto close_socket;
		}
		// convert the struct socketaddr_in into a ipport_addr_t
		m_listen_addr = ipport_addr_t(addr_in);
	}

	// set this socket in non blocking for the connection
	inet_err	= inet_oswarp_t::set_nonblock(sock_fd);
	if( inet_err.failed() ){
		errstr = inet_err.to_string();
		goto close_socket;
	}

	// put the socket in listen mode
	if( listen(sock_fd, 64) < 0 ){
		errstr = "cant cant listen on to " + listen_addr().to_string() 
					+ " due to " + inet_oswarp_t::sock_strerror();
		goto close_socket;
	}

	// some logging
	KLOG_DBG("tcp_resp_t created on " << listen_addr);		

	// start the fdwatch
	fdwatch = nipmem_new fdwatch_t();
	fdwatch->start(sock_fd, fdwatch_t::INPUT, this, NULL);
	
	// return no error
	return inet_err_t::OK;
	// handle the error case
close_socket:;	inet_oswarp_t::close_fd( sock_fd );
error:;		KLOG_INFO("errstr=" << errstr);
		return inet_err_t(inet_err_t::SYSTEM_ERR, errstr);
}
예제 #15
0
/*
 * Find a server address that can be used by `caller' to contact
 * the local service specified by `serv_uaddr'. If `clnt_uaddr' is
 * non-NULL, it is used instead of `caller' as a hint suggesting
 * the best address (e.g. the `r_addr' field of an rpc, which
 * contains the rpcbind server address that the caller used).
 *
 * Returns the best server address as a malloc'd "universal address"
 * string which should be freed by the caller. On error, returns NULL.
 */
char *
addrmerge(struct netbuf *caller, const char *serv_uaddr, const char *clnt_uaddr,
	  const char *netid)
{
	struct ifaddrs *ifap, *ifp = NULL, *bestif;
	struct netbuf *serv_nbp = NULL, *hint_nbp = NULL, tbuf;
	struct sockaddr *caller_sa, *hint_sa, *ifsa, *ifmasksa, *serv_sa;
	struct sockaddr_storage ss;
	struct netconfig *nconf;
	char *caller_uaddr = NULL;
	const char *hint_uaddr = NULL;
	char *ret = NULL;
	int bestif_goodness;

#ifdef ND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
		    clnt_uaddr == NULL ? "NULL" : clnt_uaddr, netid);
#endif
	caller_sa = caller->buf;
	if ((nconf = rpcbind_get_conf(netid)) == NULL)
		goto freeit;
	if ((caller_uaddr = taddr2uaddr(nconf, caller)) == NULL)
		goto freeit;

	/*
	 * Use `clnt_uaddr' as the hint if non-NULL, but ignore it if its
	 * address family is different from that of the caller.
	 */
	hint_sa = NULL;
	if (clnt_uaddr != NULL) {
		hint_uaddr = clnt_uaddr;
		if ((hint_nbp = uaddr2taddr(nconf, clnt_uaddr)) == NULL)
			goto freeit;
		hint_sa = hint_nbp->buf;
	}
	if (hint_sa == NULL || hint_sa->sa_family != caller_sa->sa_family) {
		hint_uaddr = caller_uaddr;
		hint_sa = caller->buf;
	}

#ifdef ND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge: hint %s\n", hint_uaddr);
#endif
	/* Local caller, just return the server address. */
	if (strncmp(caller_uaddr, "0.0.0.0.", 8) == 0 ||
	    strncmp(caller_uaddr, "::.", 3) == 0 || caller_uaddr[0] == '/') {
		ret = strdup(serv_uaddr);
		goto freeit;
	}

	if (getifaddrs(&ifp) < 0)
		goto freeit;

	/*
	 * Loop through all interface addresses.  We are listening to an address
	 * if any of the following are true:
	 * a) It's a loopback address
	 * b) It was specified with the -h command line option
	 * c) There were no -h command line options.
	 *
	 * Among addresses on which we are listening, choose in order of
	 * preference an address that is:
	 *
	 * a) Equal to the hint
	 * b) A link local address with the same scope ID as the client's
	 *    address, if the client's address is also link local
	 * c) An address on the same subnet as the client's address
	 * d) A non-localhost, non-p2p address
	 * e) Any usable address
	 */
	bestif = NULL;
	bestif_goodness = 0;
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		ifsa = ifap->ifa_addr;
		ifmasksa = ifap->ifa_netmask;

		/* Skip addresses where we don't listen */
		if (ifsa == NULL || ifsa->sa_family != hint_sa->sa_family ||
		    !(ifap->ifa_flags & IFF_UP))
			continue;

		if (!(ifap->ifa_flags & IFF_LOOPBACK) && !listen_addr(ifsa))
			continue;

		if ((hint_sa->sa_family == AF_INET) &&
		    ((((struct sockaddr_in*)hint_sa)->sin_addr.s_addr == 
		      ((struct sockaddr_in*)ifsa)->sin_addr.s_addr))) {
			const int goodness = 4;

			bestif_goodness = goodness;
			bestif = ifap;
			goto found;
		}
#ifdef INET6
		if ((hint_sa->sa_family == AF_INET6) &&
		    (0 == memcmp(&((struct sockaddr_in6*)hint_sa)->sin6_addr,
				 &((struct sockaddr_in6*)ifsa)->sin6_addr,
				 sizeof(struct in6_addr))) &&
		    (((struct sockaddr_in6*)hint_sa)->sin6_scope_id ==
		    (((struct sockaddr_in6*)ifsa)->sin6_scope_id))) {
			const int goodness = 4;

			bestif_goodness = goodness;
			bestif = ifap;
			goto found;
		}
		if (hint_sa->sa_family == AF_INET6) {
			/*
			 * For v6 link local addresses, if the caller is on
			 * a link-local address then use the scope id to see
			 * which one.
			 */
			if (IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(ifsa)) &&
			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(caller_sa)) &&
			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(hint_sa))) {
				if (SA2SIN6(ifsa)->sin6_scope_id ==
				    SA2SIN6(caller_sa)->sin6_scope_id) {
					const int goodness = 3;

					if (bestif_goodness < goodness) {
						bestif = ifap;
						bestif_goodness = goodness;
					}
				}
			}
		}
#endif /* INET6 */
		if (0 == bitmaskcmp(hint_sa, ifsa, ifmasksa)) {
			const int goodness = 2;

			if (bestif_goodness < goodness) {
				bestif = ifap;
				bestif_goodness = goodness;
			}
		}
		if (!(ifap->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
			const int goodness = 1;

			if (bestif_goodness < goodness) {
				bestif = ifap;
				bestif_goodness = goodness;
			}
		}
		if (bestif == NULL)
			bestif = ifap;
	}
	if (bestif == NULL)
		goto freeit;

found:
	/*
	 * Construct the new address using the address from
	 * `bestif', and the port number from `serv_uaddr'.
	 */
	serv_nbp = uaddr2taddr(nconf, serv_uaddr);
	if (serv_nbp == NULL)
		goto freeit;
	serv_sa = serv_nbp->buf;

	memcpy(&ss, bestif->ifa_addr, bestif->ifa_addr->sa_len);
	switch (ss.ss_family) {
	case AF_INET:
		SA2SIN(&ss)->sin_port = SA2SIN(serv_sa)->sin_port;
		break;
#ifdef INET6
	case AF_INET6:
		SA2SIN6(&ss)->sin6_port = SA2SIN6(serv_sa)->sin6_port;
		break;
#endif
	}
	tbuf.len = ss.ss_len;
	tbuf.maxlen = sizeof(ss);
	tbuf.buf = &ss;
	ret = taddr2uaddr(nconf, &tbuf);

freeit:
	if (caller_uaddr != NULL)
		free(caller_uaddr);
	if (hint_nbp != NULL) {
		free(hint_nbp->buf);
		free(hint_nbp);
	}
	if (serv_nbp != NULL) {
		free(serv_nbp->buf);
		free(serv_nbp);
	}
	if (ifp != NULL)
		freeifaddrs(ifp);

#ifdef ND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge: returning %s\n", ret);
#endif
	return ret;
}
예제 #16
0
	/*************** compatibility layer	*******************************/
	const ipport_addr_t &	get_listen_addr()const throw()	{ return listen_addr();		}