ServerSocket(int port) { sockFD = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockFD == -1) throw NetException("ServerSocket::ServerSocket()", "socket() failed"); int optReuseAddress = 1; int setsockoptResult = ::setsockopt(sockFD, SOL_SOCKET, SO_REUSEADDR, &optReuseAddress, sizeof(int)); if (setsockoptResult == -1) throw NetException("ServerSocket::ServerSocket()", "setsockopt() failed"); memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(port); sockAddr.sin_addr.s_addr = ::htonl(INADDR_ANY ); int bindResult = ::bind(sockFD, (const sockaddr*) &sockAddr, sizeof(sockAddr)); if (bindResult == -1) throw NetException("ServerSocket::ServerSocket()", "bind() failed"); // max 10 pending int listenResult = ::listen(sockFD, 10); if (listenResult == -1) throw NetException("ServerSocket::ServerSocket()", "listen() failed"); }
const IpAddress& NetworkInterfaceImpl::get_dest_address(AddressList::size_type index) const { if (!is_p2p()) { throw NetException("Unsupported operation"); } else if (index < m_address_list.size()) { return std::get<NetworkInterface::BROADCAST_ADDRESS>(m_address_list[index]); } throw NetException("IpAddress of NetworkInterface not found"); }
void ServerSocket::accept(Socket &sock) { if(mSock == INVALID_SOCKET) throw NetException("Socket not listening"); sock.close(); socket_t clientSock = ::accept(mSock, NULL, NULL); if(clientSock == INVALID_SOCKET) throw NetException(String("Listening socket closed on port ")+String::number(mPort) + " (error "+String::number(sockerrno)+")"); sock.mSock = clientSock; }
void HTTPRequest::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); std::string method; std::string uri; std::string version; method.reserve(16); uri.reserve(64); version.reserve(64); int ch = istr.get(); if (istr.bad()) throw NetException("Network failure while reading HTTP request header"); if (istr.bad()) throw NetException("Error reading HTTP request header"); if (ch == eof) throw NoMessageException(); while (Ascii::isSpace(ch)) ch = istr.get(); if (ch == eof) throw MessageException("No HTTP request header"); while (!Ascii::isSpace(ch) && ch != eof && method.length() < MAX_METHOD_LENGTH) { method += (char) ch; ch = istr.get(); } if (!Ascii::isSpace(ch)) throw MessageException("HTTP request method invalid or too long"); while (Ascii::isSpace(ch)) ch = istr.get(); while (!Ascii::isSpace(ch) && ch != eof && uri.length() < MAX_URI_LENGTH) { uri += (char) ch; ch = istr.get(); } if (!Ascii::isSpace(ch)) throw MessageException("HTTP request URI invalid or too long"); while (Ascii::isSpace(ch)) ch = istr.get(); while (!Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); } if (!Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string"); while (ch != '\n' && ch != eof) { ch = istr.get(); } HTTPMessage::read(istr); ch = istr.get(); while (ch != '\n' && ch != eof) { ch = istr.get(); } setMethod(method); setURI(uri); setVersion(version); }
DataSerializer::DataSerializer(std::vector<char> &data_, size_t maxBytes_, const SerializedMessageDesc *msgTemplate) { if (data_.size() < maxBytes_) data_.resize(maxBytes_); if (data_.size() == 0 || maxBytes_ == 0) throw NetException("Cannot instantiate a DataSerializer object to a zero-sized std::vector-based buffer!"); data = &data_[0]; maxBytes = maxBytes_; if (!msgTemplate) throw NetException("Null message template cannot be passed in to DataSerializer ctor!"); iter = new SerializedDataIterator(*msgTemplate); ResetFill(); }
int CNetServer::list(const int maxConnect) { if(!isValid()) { throw NetException("Server Socket error"); } _maxConnect = maxConnect; int result = ::listen(_sock, _maxConnect); if(result < 0) { throw NetException("Server Listen Error"); } return 0; }
void Net_API initializeNetwork() { WORD version = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(version, &data) != 0) throw NetException("Failed to initialize network subsystem"); }
void SerializedMessageList::ParseMessages(TiXmlElement *root) { #ifdef KNET_USE_TINYXML TiXmlElement *node = root->FirstChildElement("message"); while(node) { SerializedMessageDesc desc; int success = node->QueryIntAttribute("id", (int*)&desc.id); if (success == TIXML_NO_ATTRIBUTE) { KNET_LOG(LogError, "Error parsing message attribute 'id' as int!"); node = node->NextSiblingElement("message"); continue; } success = node->QueryIntAttribute("priority", (int*)&desc.priority); if (success == TIXML_NO_ATTRIBUTE) desc.priority = 0; // If priority not specified, use the default priority of zero - the lowest priority possible. if (node->Attribute("name")) desc.name = node->Attribute("name"); desc.reliable = ParseBool(node->Attribute("reliable")); desc.inOrder = ParseBool(node->Attribute("inOrder")); desc.data = ParseNode(node, 0); // Work a slight convenience - if there is a single struct inside a single struct inside a single struct - jump straight through to the data. messages.push_back(desc); node = node->NextSiblingElement("message"); } #else throw NetException("kNet was built without TinyXml support! SerializedMessageList is not available!"); #endif }
void HTTPResponse::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); std::string version; std::string status; std::string reason; int ch = istr.get(); if (istr.bad()) throw NetException("Error reading HTTP response header"); if (ch == eof) throw NoMessageException(); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); if (ch == eof) throw MessageException("No HTTP response header"); while (!Poco::Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string"); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); while (!Poco::Ascii::isSpace(ch) && ch != eof && status.length() < MAX_STATUS_LENGTH) { status += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP status code"); while (Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n' && ch != eof) ch = istr.get(); while (ch != '\r' && ch != '\n' && ch != eof && reason.length() < MAX_REASON_LENGTH) { reason += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP reason string too long"); if (ch == '\r') ch = istr.get(); if (ch != '\n') throw MessageException("Unterminated HTTP response line"); HTTPMessage::read(istr); ch = istr.get(); while (ch != '\n' && ch != eof) { ch = istr.get(); } setVersion(version); setStatus(status); setReason(reason); }
int CNetServer::bind(const char * address, const int port) { if(!isValid()) { throw NetException("Server Socket error"); } setAddr(address, port); int result = ::bind(_sock, (struct sockaddr *) & _addr, sizeof(_addr)); if(result < 0) { throw NetException("Server Bind error"); } return 0; }
const HostEntry& DNS::hostByName(const std::string& hostname) { FastMutex::ScopedLock lock(_mutex); DNSCache::const_iterator it = _cache.find(hostname); if (it != _cache.end()) { return it->second; } else { #if defined(_WIN32) && defined(POCO_HAVE_IPv6) struct addrinfo* pAI; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; if (getaddrinfo(hostname.c_str(), NULL, &hints, &pAI) == 0) { std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(hostname, HostEntry(pAI))); freeaddrinfo(pAI); return res.first->second; } #else struct hostent* he = gethostbyname(hostname.c_str()); if (he) { std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(hostname, HostEntry(he))); return res.first->second; } #endif } error(lastError(), hostname); // will throw an appropriate exception throw NetException(); // to silence compiler }
const IpAddress& NetworkInterfaceImpl::get_first_address(AddressFamily family) const { for (const auto& address_tuple : m_address_list) { const auto& addr = std::get<NetworkInterface::IP_ADDRESS>(address_tuple); if (addr.get_address_family() == family) { return addr; } } throw NetException("IpAddress of NetworkInterface not found"); }
void PIL_API initializeNetwork() { #if defined(PIL_OS_FAMILY_WINDOWS) WORD version = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(version, &data) != 0) throw NetException("Failed to initialize network subsystem"); #endif }
std::shared_ptr<Socket> accept() { int connFD = ::accept(sockFD, nullptr, nullptr); if (connFD < 0) throw NetException("ServerSocket::accept()", "accept() failed"); return std::shared_ptr<Socket>(new Socket(connFD)); }
Address ServerSocket::getBindAddress(void) const { sockaddr_storage sa; socklen_t sl = sizeof(sa); int ret = ::getsockname(mSock, reinterpret_cast<sockaddr*>(&sa), &sl); if(ret < 0) throw NetException("Cannot obtain address of socket"); return Address(reinterpret_cast<sockaddr*>(&sa), sl); }
std::string DNS::hostName() { char buffer[256]; int rc = gethostname(buffer, sizeof(buffer)); if (rc == 0) return std::string(buffer); else throw NetException("Cannot get host name"); }
void initializeNetwork() { #if defined(_WIN32) WORD version = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(version, &data) != 0) throw NetException("Failed to initialize network subsystem"); #endif // _WIN32 }
NetworkInterface NetworkInterface::for_name(const std::string& name) { auto map = NetworkInterface::get_interfaces_map(); for (const auto& nic: map) { if (nic.second.get_name() == name) { return nic.second; } } throw NetException("NetworkInterface '" + name + "' not found"); }
void DataSerializer::AddAlignedByteArray(const void *srcData, u32 numBytes) { assert(bitOfs == 0); assert(!iter); if (elemOfs + numBytes > maxBytes) throw NetException("DataSerializer::AddAlignedByteArray: Attempted to write past the array end buffer!"); memcpy(&data[elemOfs], srcData, numBytes); elemOfs += numBytes; }
void Initialize() { Connections = std::vector<SOCKET>(); WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) throw NetException(iResult); BufferSize = 256; Buffer = new char[BufferSize]; }
NetworkInterface NetworkInterface::for_index(unsigned i) { if (i != NetworkInterfaceImpl::NO_INDEX) { Map map = NetworkInterface::get_interfaces_map(); auto it = map.find(i); if (it != map.end()) { return it->second; } } throw NetException("NetworkInterface for index " + std::to_string(i) + " not found"); }
void DNS::error(int code, const std::string& arg) { switch (code) { case POCO_ESYSNOTREADY: throw NetException("Net subsystem not ready"); case POCO_ENOTINIT: throw NetException("Net subsystem not initialized"); case POCO_HOST_NOT_FOUND: throw HostNotFoundException(arg); case POCO_TRY_AGAIN: throw DNSException("Temporary DNS error while resolving", arg); case POCO_NO_RECOVERY: throw DNSException("Non recoverable DNS error while resolving", arg); case POCO_NO_DATA: throw NoAddressFoundException(arg); default: throw IOException(NumberFormatter::format(code)); } }
DataSerializer::DataSerializer(std::vector<char> &data_, size_t maxBytes_) { if (data_.size() < maxBytes_) data_.resize(maxBytes_); if (data_.size() == 0 || maxBytes_ == 0) throw NetException("Cannot instantiate a DataSerializer object to a zero-sized std::vector-based buffer!"); data = &data_[0]; maxBytes = maxBytes_; ResetFill(); }
bool CNetClient::connect(const char * address, const int port) { setAddr(address, port); int result = ::connect(_sock, (struct sockaddr *)&_addr, sizeof(_addr)); if(result < 0) { throw NetException("Client Connect Error"); } _connected = true; return true; }
bool CNetClient::disconnect() { int result = ::shutdown(_sock, 0); if(result < 0) { throw NetException("Client Disconnect Error"); } _connected = false; return true; }
HostEntry DNS::hostByAddress(const IPAddress& address, unsigned #ifdef POCO_HAVE_ADDRINFO hintFlags #endif ) { #if defined(POCO_HAVE_LIBRESOLV) Poco::ScopedReadRWLock readLock(resolverLock); #endif #if defined(POCO_HAVE_ADDRINFO) SocketAddress sa(address, 0); static char fqname[1024]; int rc = getnameinfo(sa.addr(), sa.length(), fqname, sizeof(fqname), NULL, 0, NI_NAMEREQD); if (rc == 0) { struct addrinfo* pAI; struct addrinfo hints; std::memset(&hints, 0, sizeof(hints)); hints.ai_flags = hintFlags; rc = getaddrinfo(fqname, NULL, &hints, &pAI); if (rc == 0) { HostEntry result(pAI); freeaddrinfo(pAI); return result; } else { aierror(rc, address.toString()); } } else { aierror(rc, address.toString()); } #elif defined(POCO_VXWORKS) char name[MAXHOSTNAMELEN + 1]; if (hostGetByAddr(*reinterpret_cast<const int*>(address.addr()), name) == OK) { return HostEntry(std::string(name), address); } #else struct hostent* he = gethostbyaddr(reinterpret_cast<const char*>(address.addr()), address.length(), address.af()); if (he) { return HostEntry(he); } #endif int err = lastError(); error(err, address.toString()); // will throw an appropriate exception throw NetException(); // to silence compiler }
void WriteBufferFromPocoSocket::nextImpl() { if (!offset()) return; Stopwatch watch; size_t bytes_written = 0; while (bytes_written < offset()) { ssize_t res = 0; /// Add more details to exceptions. try { res = socket.impl()->sendBytes(working_buffer.begin() + bytes_written, offset() - bytes_written); } catch (const Poco::Net::NetException & e) { throw NetException(e.displayText() + ", while writing to socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR); } catch (const Poco::TimeoutException &) { throw NetException("Timeout exceeded while writing to socket (" + peer_address.toString() + ")", ErrorCodes::SOCKET_TIMEOUT); } catch (const Poco::IOException & e) { throw NetException(e.displayText() + ", while writing to socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR); } if (res < 0) throw NetException("Cannot write to socket (" + peer_address.toString() + ")", ErrorCodes::CANNOT_WRITE_TO_SOCKET); bytes_written += res; } ProfileEvents::increment(ProfileEvents::NetworkSendElapsedMicroseconds, watch.elapsedMicroseconds()); }
void SerializedMessageList::ParseStructs(TiXmlElement *root) { #ifdef KNET_USE_TINYXML TiXmlElement *node = root->FirstChildElement("struct"); while(node) { ParseNode(node, 0); node = node->NextSiblingElement("struct"); } #else throw NetException("kNet was built without TinyXml support! SerializedMessageList is not available!"); #endif }
NetworkInterface NetworkInterface::for_address(const IpAddress& addr) { auto map = NetworkInterface::get_interfaces_map(); for (const auto& nic : map) { if (nic.second.supports_ip()) { auto size = nic.second.get_address_list().size(); for (AddressList::size_type i = 0; i < size; ++i) { if (nic.second.get_address(i) == addr) { return nic.second; } } } } throw NetException("NetworkInterface for address " + addr.to_string() + " not found"); }
const HostEntry& DNS::hostByAddress(const IPAddress& address) { FastMutex::ScopedLock lock(_mutex); #if defined(_WIN32) && defined(POCO_HAVE_IPv6) SocketAddress sa(address, 0); static char fqname[1024]; if (getnameinfo(sa.addr(), sa.length(), fqname, sizeof(fqname), NULL, 0, 0) == 0) { DNSCache::const_iterator it = _cache.find(std::string(fqname)); if (it != _cache.end()) { return it->second; } else { struct addrinfo* pAI; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; if (getaddrinfo(fqname, NULL, &hints, &pAI) == 0) { std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(std::string(fqname), HostEntry(pAI))); freeaddrinfo(pAI); return res.first->second; } } } #elif defined(POCO_VXWORKS) char buffer[2048]; struct hostent* he = resolvGetHostByAddr(reinterpret_cast<const char*>(address.addr()), buffer, sizeof(buffer)); if (he) { std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(std::string(he->h_name), HostEntry(he))); return res.first->second; } #else struct hostent* he = gethostbyaddr(reinterpret_cast<const char*>(address.addr()), address.length(), address.af()); if (he) { std::pair<DNSCache::iterator, bool> res = _cache.insert(std::pair<std::string, HostEntry>(std::string(he->h_name), HostEntry(he))); return res.first->second; } #endif int err = lastError(); error(err, address.toString()); // will throw an appropriate exception throw NetException(); // to silence compiler }