IPAddress::IPAddress(const std::string& addr) { IPv4AddressImpl empty4 = IPv4AddressImpl(); if (addr.empty() || trim(addr) == "0.0.0.0") { newIPv4(empty4.addr()); return; } IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr)); if (addr4 != empty4) { newIPv4(addr4.addr()); return; } #if defined(POCO_HAVE_IPv6) IPv6AddressImpl empty6 = IPv6AddressImpl(); if (addr.empty() || trim(addr) == "::") { newIPv6(empty6.addr()); return; } IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr)); if (addr6 != IPv6AddressImpl()) { newIPv6(addr6.addr(), addr6.scope()); return; } #endif throw InvalidAddressException(addr); }
/** * `Socket` Constructor. * * Constructs a `Socket` object given a listening address/port and begins * listening for clients. * * @param addr `std::string` object containing the listen address * @param port `int` containing the port number to listen on */ Socket::Socket(const std::string& addr, int port) { // Ensure the validity of the provided port if (port < 1 || port > 65535) throw InvalidArgument{"The provided port number is out of range."}; // Fetch a finalized sockaddr_storage for the given address struct sockaddr_storage address = parseAddress(addr); // Use the appropriate setup helper depending on the address family if (address.ss_family == AF_INET || address.ss_family == AF_INET6) { // Assign the appropriate address family to describe the `Connection` this->family = (address.ss_family == AF_INET ? SocketFamily::IPv4 : SocketFamily::IPv6); // Determine the appropriate pointer type for the remote address auto addrPtr = (address.ss_family == AF_INET ? addr4(address) : addr6(address)); // Store a text-based representation of the remote address char addressString[INET6_ADDRSTRLEN + 1] = {}; this->host = inet_ntop(address.ss_family, addrPtr, addressString, INET6_ADDRSTRLEN); // Assign the port to the sockaddr struct *(this->family == SocketFamily::IPv4 ? port4(address) : port6(address)) = htons(this->port = port); } else { // Remote address has an unexpected address family throw InvalidArgument{"The remote address has an unexpected address " "family."}; } // Setup the socket using the appropriate address family and type this->socket = ::socket(address.ss_family, SOCK_STREAM, 0); // Attempt to bind the socket to the listening address if (bind(this->socket, addr_(address), this->family == SocketFamily::IPv4 ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) < 0) { // A problem occurred, close the socket and throw an exception close(this->socket); throw UnexpectedError{"Couldn't bind to [" + this->host + "]:" + std::to_string(this->port)}; } else { // Allow reusing the socket int reuse = 1; setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); // Listen with a backlog of 16 clients listen(this->socket, 16); } }
IPAddress::IPAddress(const std::string& addr, Family family) { if (family == IPv4) { IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr)); newIPv4(addr4.addr()); return; } #if defined(POCO_HAVE_IPv6) else if (family == IPv6) { IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr)); newIPv6(addr6.addr(), addr6.scope()); return; } #endif else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); }
/** * Accepts an incoming client and creates a `Connection` object for it. * * This method blocks execution until a client is accepted. * * @return `Connection` object representing the accepted client. */ std::shared_ptr<Connection> Socket::accept() const { // Create storage to accept and capture the client's remote address std::string raddress{}; struct sockaddr_storage cli_addr = {}; socklen_t cli_addr_len = sizeof(struct sockaddr); int cli_fd = -1; // Check if the Socket is valid if (this->valid()) { // Accept an incoming client cli_fd = ::accept(this->socket, (struct sockaddr*)&cli_addr, &cli_addr_len); // Store a text-based representation of the remote address if (cli_addr.ss_family == AF_INET || cli_addr.ss_family == AF_INET6) { // Determine the appropriate pointer type for the remote address auto addrPtr = (cli_addr.ss_family == AF_INET ? addr4(cli_addr) : addr6(cli_addr)); // Assign the resulting address to the raddress string char addressString[INET6_ADDRSTRLEN + 1] = {}; raddress = inet_ntop(cli_addr.ss_family, addrPtr, addressString, INET6_ADDRSTRLEN); } // If cli_fd is negative, an error occurred if (cli_fd < 0) { throw UnexpectedError{"Couldn't accept client on [" + this->host + "]:" + std::to_string(this->port) + " - Invalid client file " "descriptor"}; } } else { // Cannot accept a client on an invalid Socket throw UnexpectedError{"Couldn't accept client on [" + this->host + "]:" + std::to_string(this->port) + " - Invalid socket"}; } // Return a shared_ptr to the newly created Connection object return std::shared_ptr<Connection>{ new Connection{this->host, raddress, this->port, cli_fd} }; }
void test() { namespace ip = std::experimental::net::ip; try { std::error_code ec; std::string string_value; // address constructors. ip::address addr1; const ip::address_v4 const_addr_v4; ip::address addr2(const_addr_v4); const ip::address_v6 const_addr_v6; ip::address addr3(const_addr_v6); ip::address addr4("127.0.0.1"); ip::address addr5("127.0.0.1", ec); ip::address addr6(string_value); ip::address addr7(string_value, ec); // address functions. bool b = addr1.is_v4(); (void)b; b = addr1.is_v6(); (void)b; b = addr1.is_loopback(); (void)b; b = addr1.is_unspecified(); (void)b; b = addr1.is_multicast(); (void)b; ip::address_v4 addr_v4_value = ip::address_cast<ip::address_v4>(addr1); (void)addr_v4_value; ip::address_v6 addr_v6_value = ip::address_cast<ip::address_v6>(addr1); (void)addr_v6_value; string_value = addr1.to_string(); string_value = addr1.to_string(ec); // address comparisons. b = (addr1 == addr2); (void)b; b = (addr1 != addr2); (void)b; b = (addr1 < addr2); (void)b; b = (addr1 > addr2); (void)b; b = (addr1 <= addr2); (void)b; b = (addr1 >= addr2); (void)b; // address creation functions. addr1 = ip::make_address("127.0.0.1"); addr1 = ip::make_address("127.0.0.1", ec); addr1 = ip::make_address(string_value); addr1 = ip::make_address(string_value, ec); // address I/O. std::ostringstream os; os << addr1; std::wostringstream wos; wos << addr1; } catch (std::exception&) { } }
TVerdict CresolvertpcollisionorlooplStep::doTestStepL() { SetTestStepResult(EFail); CRtpCollisionMng *collMgr = NULL; CRtpSourceEntry *entry = NULL; INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL()")); /* Normal Call */ TRAPD(res,collMgr = CRtpCollisionMng::NewL(iRtpController,iSSRC1,iCname1)); if(KErrNone != res) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() (iRtpController,iSSRC1,iCname1) Failed")); return TestStepResult(); } entry = collMgr->FindEntry(iSSRC1); /* Set the RTP and RTCP Source address */ TInetAddr addrLocal(iLocalIpAddr,iPort1); entry->SetRtpSourceAddr(addrLocal); addrLocal.SetPort(iPort1 + 1); entry->SetRtcpSourceAddr(addrLocal); //A dummy SSRC is given and a New Source is Created */ TRAP(res,entry = collMgr->CreateNewSourceL(iSSRC2)); if(res != KErrNone) { /* Failed .. Return */ INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed")); delete collMgr; return TestStepResult(); } /* Set the RTP and RTCP Source address */ TInetAddr addr(iIpAddr1,iPort1); entry->SetRtpSourceAddr(addr); addr.SetPort(iPort1+1); entry->SetRtcpSourceAddr(addr); //A dummy SSRC is given and a New Source is Created */ TRAP(res,entry = collMgr->CreateNewSourceL(iSSRC3)); if(res != KErrNone) { /* Failed .. Return */ INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed")); delete collMgr; return TestStepResult(); } /* Set the RTP and RTCP Source address */ TInetAddr addr2(iIpAddr2,iPort2); entry->SetRtpSourceAddr(addr2); addr2.SetPort(iPort2+1); entry->SetRtcpSourceAddr(addr2); /* Now check a Normal recv from BABE2 */ entry = collMgr->FindEntry(iSSRC2); if(collMgr->IsCollisionOrLoopback(entry,addr,ERtcp)) { /* This was not a Collision and was flagged as a Collision.*/ INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed-Normal Rec Flagged as Collision")); delete collMgr; return TestStepResult(); } entry = collMgr->FindEntry(iSSRC2); /* Simulating a Collision. Make a Dummy IP Address */ TInetAddr addr3(iIpAddr3,iPort1); if(!collMgr->IsCollisionOrLoopback(entry,addr3,ERtp)) { /* This was a Collision and was flagged as not a Collision.*/ INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Collision Not Detected")); delete collMgr; return TestStepResult(); } entry = collMgr->FindEntry(iSSRC2); /* Simulating a Collision. Make a Dummy IP Address */ TInetAddr addr_rtcp(iIpAddr3,iPort1+1); if(!collMgr->IsCollisionOrLoopback(entry,addr_rtcp,ERtcp)) { /* This was a Collision and was flagged as not a Collision.*/ INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Collision Not Detected")); delete collMgr; return TestStepResult(); } /* Calling Resolve Collision */ if(collMgr->ResolveRtpCollisionOrLoopL(iSSRC2,addr3,ERtp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Collision TRUE for processing :(")); delete collMgr; return TestStepResult(); } /* Calling Resolve Collision ..Our Address Given*/ if(!collMgr->ResolveRtpCollisionOrLoopL(iSSRC1,addr3,ERtp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Local Collision FALSE for processing :(")); delete collMgr; return TestStepResult(); } if(collMgr->GetLocalEntry()->SRC() == iSSRC1) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Local SSRC not Changed :(")); delete collMgr; return TestStepResult(); } TInt changedSSRC = collMgr->GetLocalEntry()->SRC(); /* Calling Resolve Collision ..Our Address Given*/ if(!collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtp|KIsAlreadySending)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Local Collision FALSE for processing :(")); delete collMgr; return TestStepResult(); } if(collMgr->GetLocalEntry()->SRC() == changedSSRC) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Local SSRC not Changed :(")); delete collMgr; return TestStepResult(); } /* Try a Loop Test .. Now */ /* Calling Resolve Collision ..Give the new SSRC and Old Addresss */ if(collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Loop Detection 1 :(")); delete collMgr; return TestStepResult(); } if(collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtp|KIsAlreadySending)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Loop Detection 2 :(")); delete collMgr; return TestStepResult(); } /* Calling again */ /* Calling Resolve Collision ..Give the new SSRC and Old Addresss */ if(collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtp|KIsAlreadySending)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Loop Detection 3 :(")); delete collMgr; return TestStepResult(); } /* Calling Resolve Collision ..Give the new SSRC and Old Addresss */ if(collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Loop Detection 4 :(")); delete collMgr; return TestStepResult(); } if(collMgr->ResolveRtpCollisionOrLoopL(collMgr->GetLocalEntry()->SRC(),addr3,ERtcp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Loop Detection 5 :(")); delete collMgr; return TestStepResult(); } /* We have received only one RTP from the colliding Source. What if we receive an RTCP from a Different source With the same SSRC ? */ /*This condition tickles an old issue. So lets keep it that way */ #if 0 TInetAddr addr4(iIpAddr4,iPort4); entry = collMgr->FindEntry(iSSRC1); if(!collMgr->IsCollisionOrLoopback(entry,addr4,ERtcp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Incorrect Collision Detection")); delete collMgr; return TestStepResult(); } /* Now receiving an RTCP from the same Source.. See it that is not flagged as a Collision */ addr3.SetPort(iPort1+1); entry = collMgr->FindEntry(iSSRC1); if(collMgr->IsCollisionOrLoopback(entry,addr3,ERtcp)) { INFO_PRINTF1(_L("CresolvertpcollisionorlooplStep::doStepL() - Failed - Incorrect Collision Dectection")); delete collMgr; return TestStepResult(); } #endif SetTestStepResult(EPass); delete collMgr; return TestStepResult(); }