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"; }
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); }
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; }