void SocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout) { if (_sockfd == POCO_INVALID_SOCKET) { init(address.af()); } setBlocking(false); try { #if defined(POCO_VXWORKS) int rc = ::connect(_sockfd, (sockaddr*) address.addr(), address.length()); #else int rc = ::connect(_sockfd, address.addr(), address.length()); #endif if (rc != 0) { int err = lastError(); if (err != POCO_EINPROGRESS && err != POCO_EWOULDBLOCK) error(err, address.toString()); if (!poll(timeout, SELECT_READ | SELECT_WRITE | SELECT_ERROR)) throw Poco::TimeoutException("connect timed out", address.toString()); err = socketError(); if (err != 0) error(err); } } catch (Poco::Exception&) { setBlocking(true); throw; } setBlocking(true); }
SocketAddress::SocketAddress(const SocketAddress& socketAddress) { if (socketAddress.family() == IPAddress::IPv4) newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr())); else newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr())); }
SocketAddress::SocketAddress(const SocketAddress& socketAddress) { if (socketAddress.family() == IPv4) newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr())); #if defined(POCO_HAVE_IPv6) else if (socketAddress.family() == IPv6) newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr())); #endif #if defined(POCO_OS_FAMILY_UNIX) else if (socketAddress.family() == UNIX_LOCAL) newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr())); #endif }
int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& address, int flags) { int rc; do { if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException(); #if defined(POCO_VXWORKS) rc = ::sendto(_sockfd, (char*) buffer, length, flags, (sockaddr*) address.addr(), address.length()); #else rc = ::sendto(_sockfd, reinterpret_cast<const char*>(buffer), length, flags, address.addr(), address.length()); #endif } while (_blocking && rc < 0 && lastError() == POCO_EINTR); if (rc < 0) error(); return rc; }
void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only) { #if defined(POCO_HAVE_IPv6) if (address.family() != IPAddress::IPv6) throw Poco::InvalidArgumentException("SocketAddress must be an IPv6 address"); if (_sockfd == POCO_INVALID_SOCKET) { init(address.af()); } #ifdef IPV6_V6ONLY setOption(IPPROTO_IPV6, IPV6_V6ONLY, ipV6Only ? 1 : 0); #else if (ipV6Only) throw Poco::NotImplementedException("IPV6_V6ONLY not defined."); #endif if (reuseAddress) { setReuseAddress(true); setReusePort(true); } int rc = ::bind(_sockfd, address.addr(), address.length()); if (rc != 0) error(address.toString()); #else throw Poco::NotImplementedException("No IPv6 support available"); #endif }
UInt8 RTMFPServer::p2pHandshake(const string& tag,PacketWriter& response,const SocketAddress& address,const UInt8* peerIdWanted) { // find the flash client equivalence Session* pSession = NULL; Sessions::Iterator it; for(it=_sessions.begin(); it!=_sessions.end(); ++it) { pSession = it->second; if(memcmp(pSession->peer().address.addr(),address.addr(),address.length())==0 && pSession->peer().address.port() == address.port()) break; } if(it==_sessions.end()) pSession=NULL; Session* pSessionWanted = _sessions.find(peerIdWanted); if(_pCirrus) { // Just to make working the man in the middle mode ! if(!pSession) { ERROR("UDP Hole punching error : middle equivalence not found for session wanted"); return 0; } PacketWriter& request = ((Middle*)pSession)->handshaker(); request.write8(0x22); request.write8(0x21); request.write8(0x0F); request.writeRaw(pSessionWanted ? ((Middle*)pSessionWanted)->middlePeer().id : peerIdWanted,32); request.writeRaw(tag); ((Middle*)pSession)->sendHandshakeToCirrus(0x30); // no response here! return 0; } if(!pSessionWanted) { DEBUG("UDP Hole punching : session wanted not found, must be dead"); return 0; } else if(pSessionWanted->failed()) { DEBUG("UDP Hole punching : session wanted is deleting"); return 0; } /// Udp hole punching normal process pSessionWanted->p2pHandshake(address,tag,pSession); response.writeAddress(pSessionWanted->peer().address,true); vector<Address>::const_iterator it2; for(it2=pSessionWanted->peer().privateAddress.begin(); it2!=pSessionWanted->peer().privateAddress.end(); ++it2) { const Address& addr = *it2; if(addr == address) continue; response.writeAddress(addr,false); } return 0x71; }
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress) { if (_sockfd == POCO_INVALID_SOCKET) { init(address.af()); } if (reuseAddress) { setReuseAddress(true); setReusePort(true); } #if defined(POCO_VXWORKS) int rc = ::bind(_sockfd, (sockaddr*) address.addr(), address.length()); #else int rc = ::bind(_sockfd, address.addr(), address.length()); #endif if (rc != 0) error(address.toString()); }
void SocketImpl::connectNB(const SocketAddress& address) { if (_sockfd == POCO_INVALID_SOCKET) { init(address.af()); } setBlocking(false); #if defined(POCO_VXWORKS) int rc = ::connect(_sockfd, (sockaddr*) address.addr(), address.length()); #else int rc = ::connect(_sockfd, address.addr(), address.length()); #endif if (rc != 0) { int err = lastError(); if (err != POCO_EINPROGRESS && err != POCO_EWOULDBLOCK) error(err, address.toString()); } }
void SocketImpl::connect(const SocketAddress& address) { if (_sockfd == POCO_INVALID_SOCKET) { init(address.af()); } int rc; do { #if defined(POCO_VXWORKS) rc = ::connect(_sockfd, (sockaddr*) address.addr(), address.length()); #else rc = ::connect(_sockfd, address.addr(), address.length()); #endif } while (rc != 0 && lastError() == POCO_EINTR); if (rc != 0) { int err = lastError(); error(err, address.toString()); } }
void Session::p2pHandshake(const SocketAddress& address,const std::string& tag,Session* pSession) { DEBUG("Peer newcomer address send to peer '%u' connected",id()); Address const* pAddress = NULL; UInt16 size = 0x36; if(pSession) { map<string,UInt8>::iterator it = _p2pHandshakeAttemps.find(tag); if(it==_p2pHandshakeAttemps.end()) { it = _p2pHandshakeAttemps.insert(pair<string,UInt8>(tag,0)).first; // If two clients are on the same lan, starts with private address if(memcmp(address.addr(),peer().address.addr(),address.length())==0 && pSession->peer().privateAddress.size()>0) it->second=1; } if(it->second>0) { pAddress = &pSession->peer().privateAddress[it->second-1]; size += pAddress->host.size(); } ++it->second; if(it->second > pSession->peer().privateAddress.size()) it->second=0; } if(!pAddress) size += (address.host().family() == IPAddress::IPv6 ? 16 : 4); PacketWriter& writer = writeMessage(0x0F,size); writer.write8(0x22); writer.write8(0x21); writer.write8(0x0F); writer.writeRaw(_peer.id,ID_SIZE); if(pAddress) writer.writeAddress(*pAddress,false); else writer.writeAddress(address,true); writer.writeRaw(tag); flush(); }
// BEWARE blocking method!! bool DNS::HostByAddress(Exception& ex,const IPAddress& address, HostEntry& host) { if (!Net::InitializeNetwork(ex)) return false; SocketAddress sa; sa.set(address, 0); static char fqname[1024]; int rc = getnameinfo(sa.addr(), sa.size(), fqname, sizeof(fqname), NULL, 0, NI_NAMEREQD); if (rc == 0) { struct addrinfo* pAI; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; rc = getaddrinfo(fqname, NULL, &hints, &pAI); if (rc == 0) { host.set(ex, pAI); freeaddrinfo(pAI); return true; } } SetAIError(ex, rc, " (address=",address.toString(),")"); return false; }