Exemple #1
0
TEST_F(P2pSessionTest, testConnectFailed)
{
    const P2pConfig p2pConfig(nsrpc::P2pConfig::peerDefaultRtt, 100);

    TestP2pEventHandler peerEventHandler;
    boost::scoped_ptr<P2pSession> peer(
        P2pSessionFactory::create(2, peerEventHandler, p2pConfig));
    EXPECT_TRUE(peer->open(ACE_DEFAULT_SERVER_PORT + 1));
    PeerAddresses invalidAddresses;
    invalidAddresses.push_back(
        PeerAddress(ACE_LOCALHOST, ACE_DEFAULT_SERVER_PORT + 3));
    peer->connect(invalidAddresses);

    const ACE_Time_Value startTime = ACE_OS::gettimeofday();
    while ((ACE_OS::gettimeofday() - startTime).msec() < getConnectDelay()) {
        peer->tick();
        hostSession_->tick();

        if (pseudoHostPeerId == peerEventHandler.getConnectFailedPeerId()) {
            break;
        }
    }

    EXPECT_EQ(pseudoHostPeerId, peerEventHandler.getConnectFailedPeerId()) <<
        "connect failed";
}
Exemple #2
0
PeerAddress UvTcpServerStream::GetPeerAddress()
{
	sockaddr_storage addr;
	int len = sizeof(addr);

	uv_tcp_getpeername(m_client.get(), reinterpret_cast<sockaddr*>(&addr), &len);

	return PeerAddress(reinterpret_cast<sockaddr*>(&addr), static_cast<socklen_t>(len));
}
void
UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint,
	UnixEndpoint* listeningEndpoint, UnixFifo* fifo)
{
	ProtocolSocket::Open();

	fIsChild = true;
	fPeerEndpoint = connectingEndpoint;
	fPeerEndpoint->AcquireReference();

	fReceiveFifo = fifo;

	PeerAddress().SetTo(&connectingEndpoint->socket->address);

	fCredentials = listeningEndpoint->fCredentials;

	fState = UNIX_ENDPOINT_CONNECTED;
}
QByteArray Discovery::Announce::toBinary(const QHostAddress &localAddress, quint16 port, MessageType mode) const {
	std::vector<char> buffer;
	libtorrent::entry::dictionary_type data;

	data.insert(std::make_pair("share", mSecret.getShareHashStdString()));
	data.insert(std::make_pair("peer", mPeer.getIdBinaryStdString()));
	data.insert(std::make_pair("la", PeerAddress(localAddress, port).getBinaryAddressStdString()));
	data.insert(std::make_pair("m", mode));

	libtorrent::bencode(std::back_inserter(buffer), data);

	std::string str(buffer.begin(), buffer.end());
	QByteArray rc;

	rc.reserve(str.length()+6);
	rc.append("BSYNC\0", 6);
	rc.append(str.data(), str.length());

	return rc;
}
status_t
UnixEndpoint::Connect(const struct sockaddr *_address)
{
	if (_address->sa_family != AF_UNIX)
		RETURN_ERROR(EAFNOSUPPORT);

	TRACE("[%ld] %p->UnixEndpoint::Connect(\"%s\")\n", find_thread(NULL), this,
		ConstSocketAddress(&gAddressModule, _address).AsString().Data());

	const sockaddr_un* address = (const sockaddr_un*)_address;

	UnixEndpointLocker endpointLocker(this);

	if (fState == UNIX_ENDPOINT_CONNECTED)
		RETURN_ERROR(EISCONN);

	if (fState != UNIX_ENDPOINT_NOT_CONNECTED)
		RETURN_ERROR(B_BAD_VALUE);
// TODO: If listening, we could set the backlog to 0 and connect.

	// check the address first
	UnixAddress unixAddress;

	if (address->sun_path[0] == '\0') {
		// internal address space (or empty address)
		int32 internalID;
		if (UnixAddress::IsEmptyAddress(*address))
			RETURN_ERROR(B_BAD_VALUE);

		internalID = UnixAddress::InternalID(*address);
		if (internalID < 0)
			RETURN_ERROR(internalID);

		unixAddress.SetTo(internalID);
	} else {
		// FS address space
		size_t pathLen = strnlen(address->sun_path, sizeof(address->sun_path));
		if (pathLen == 0 || pathLen == sizeof(address->sun_path))
			RETURN_ERROR(B_BAD_VALUE);

		struct stat st;
		status_t error = vfs_read_stat(-1, address->sun_path, true, &st,
			!gStackModule->is_syscall());
		if (error != B_OK)
			RETURN_ERROR(error);

		if (!S_ISSOCK(st.st_mode))
			RETURN_ERROR(B_BAD_VALUE);

		unixAddress.SetTo(st.st_dev, st.st_ino, NULL);
	}

	// get the peer endpoint
	UnixAddressManagerLocker addressLocker(gAddressManager);
	UnixEndpoint* listeningEndpoint = gAddressManager.Lookup(unixAddress);
	if (listeningEndpoint == NULL)
		RETURN_ERROR(ECONNREFUSED);
	BReference<UnixEndpoint> peerReference(listeningEndpoint);
	addressLocker.Unlock();

	UnixEndpointLocker peerLocker(listeningEndpoint);

	if (!listeningEndpoint->IsBound()
		|| listeningEndpoint->fState != UNIX_ENDPOINT_LISTENING
		|| listeningEndpoint->fAddress != unixAddress) {
		RETURN_ERROR(ECONNREFUSED);
	}

	// Allocate FIFOs for us and the socket we're going to spawn. We do that
	// now, so that the mess we need to cleanup, if allocating them fails, is
	// harmless.
	UnixFifo* fifo = new(nothrow) UnixFifo(UNIX_MAX_TRANSFER_UNIT);
	UnixFifo* peerFifo = new(nothrow) UnixFifo(UNIX_MAX_TRANSFER_UNIT);
	ObjectDeleter<UnixFifo> fifoDeleter(fifo);
	ObjectDeleter<UnixFifo> peerFifoDeleter(peerFifo);

	status_t error;
	if ((error = fifo->Init()) != B_OK || (error = peerFifo->Init()) != B_OK)
		return error;

	// spawn new endpoint for accept()
	net_socket* newSocket;
	error = gSocketModule->spawn_pending_socket(listeningEndpoint->socket,
		&newSocket);
	if (error != B_OK)
		RETURN_ERROR(error);

	// init connected peer endpoint
	UnixEndpoint* connectedEndpoint = (UnixEndpoint*)newSocket->first_protocol;

	UnixEndpointLocker connectedLocker(connectedEndpoint);

	connectedEndpoint->_Spawn(this, listeningEndpoint, peerFifo);

	// update our attributes
	_UnsetReceiveFifo();

	fPeerEndpoint = connectedEndpoint;
	PeerAddress().SetTo(&connectedEndpoint->socket->address);
	fPeerEndpoint->AcquireReference();
	fReceiveFifo = fifo;

	fCredentials.pid = getpid();
	fCredentials.uid = geteuid();
	fCredentials.gid = getegid();

	fifoDeleter.Detach();
	peerFifoDeleter.Detach();

	fState = UNIX_ENDPOINT_CONNECTED;

	gSocketModule->set_connected(newSocket);

	release_sem(listeningEndpoint->fAcceptSemaphore);

	connectedLocker.Unlock();
	peerLocker.Unlock();
	endpointLocker.Unlock();

	RETURN_ERROR(B_OK);
}
Exemple #6
0
boost::optional<PeerAddress> PeerAddress::FromString(const std::string& str, int defaultPort /* = 30120 */, LookupType lookupType /* = LookupType::ResolveWithService */)
{
	// ensure networking is initialized
	EnsureNetInitialized();

	// first, find a port argument in the string and see if it precedes any ']' (i.e. an IPv6 address of the form [::1] should not be seen as port 1)
	int portIdx = str.find_last_of(':');
	uint16_t port = defaultPort;

	std::string resolveName = str;

	if (portIdx != std::string::npos)
	{
		int bracketIdx = str.find_last_of(']');

		if (bracketIdx == std::string::npos || portIdx > bracketIdx)
		{
			resolveName = str.substr(0, portIdx);
			port = atoi(str.substr(portIdx + 1).c_str());
		}
	}

	boost::optional<PeerAddress> retval;

	// if we're supposed to resolve the passed name, try that
	if (lookupType == LookupType::ResolveName || lookupType == LookupType::ResolveWithService)
	{
		// however, if we're supposed to look up a service, perform the lookup for the service first
		if (lookupType == LookupType::ResolveWithService)
		{
			boost::optional<std::string> serviceName = LookupServiceRecord("_cfx._udp." + resolveName, &port);

			if (serviceName.is_initialized())
			{
				resolveName = serviceName.get();
			}
		}

		// then look up the actual host
		addrinfo* addrInfos;

		if (getaddrinfo(resolveName.c_str(), va("%u", port), nullptr, &addrInfos) == 0)
		{
			// loop through for both IPv4 and IPv6
			const int families[] = { AF_INET, AF_INET6, -1 };
			int curFamily = 0;

			while (!retval.is_initialized() && families[curFamily] != -1)
			{
				addrinfo* curInfo = addrInfos;

				while (curInfo)
				{
					// TODO: prioritize ipv6 properly for cases where such connectivity exists
					if (curInfo->ai_family == families[curFamily])
					{
						retval = PeerAddress(curInfo->ai_addr, curInfo->ai_addrlen);

						break;
					}

					curInfo = curInfo->ai_next;
				}

				curFamily++;
			}

			freeaddrinfo(addrInfos);
		}
	}
	else
	{
		assert(!"implement non-resolved names!");
	}

	return retval;
}