예제 #1
0
bool SocketAddress::setIntern(Exception& ex,const string& hostAndPort,bool resolveHost) {
	ASSERT_RETURN(!hostAndPort.empty(),false);

	string host, port;
	auto it  = hostAndPort.begin();
	auto& end = hostAndPort.end();
	if (*it == '[') {
		++it;
		while (it != end && *it != ']')
			host += *it++;
		if (it == end) {
			ex.set(Exception::NETADDRESS,"Malformed IPv6 address ", hostAndPort);
			return false;
		}
		++it;
	} else {
		while (it != end && *it != ':')
			host += *it++;
	}
	if (it != end && *it == ':') {
		++it;
		while (it != end)
			port += *it++;
	}
	else {
		ex.set(Exception::NETADDRESS, "Missing port number in ", hostAndPort);
		return false;
	}
	return setIntern(ex,host, resolveService(ex,port),resolveHost);
}
예제 #2
0
bool SocketAddress::setIntern(Exception& ex,const string& host, UInt16 port,bool resolveHost) {
	IPAddress ip;
	Exception ignore;
	if (ip.set(ignore, host)) {
		set(ip, port);
		return true;
	}
	HostEntry entry;
	if (!resolveHost) {
		if (ignore)
			ex.set(ignore);
		return false;
	}
	if (!DNS::HostByName(ex, host, entry))
		return false;
	auto& addresses = entry.addresses();
	if (addresses.size() > 0) {
		// if we get both IPv4 and IPv6 addresses, prefer IPv4
		for (const IPAddress& address : addresses) {
			if (address.family() == IPAddress::IPv4) {
				set(address, port);
				return true;
			}
		}
		set(addresses.front(), port);
		return true;
	}
	ex.set(Exception::NETADDRESS, "No address found for the host ", host);
	return false;
}
예제 #3
0
bool FileSystem::Remove(Exception& ex,const char* path,bool all) {
	bool isFolder(IsFolder(path));
	if (all && isFolder) {
		FileSystem::ForEach forEach([&ex](const string& filePath){
			Remove(ex, filePath, true);
		});
		Exception ignore;
		Paths(ignore, path, forEach); // if exception it's a not existent folder
	}
	if (!Exists(path))
		return !ex;; // already removed!
#if defined(_WIN32)
	if (isFolder) {
		wchar_t wFile[_MAX_PATH];
		MultiByteToWideChar(CP_UTF8, 0, path, -1, wFile, _MAX_PATH);
		if (RemoveDirectoryW(wFile)==0)
			ex.set(Exception::FILE, "Impossible to remove folder ", path);
	} else {
		wchar_t wFile[_MAX_PATH];
		MultiByteToWideChar(CP_UTF8, 0, path, -1, wFile, _MAX_PATH);
		if(_wremove(wFile) != 0)
			ex.set(Exception::FILE, "Impossible to remove file ", path);
	}
	return !ex;
#endif
	if (remove(path) == 0)
		return !ex;
	if (isFolder)
		ex.set(Exception::FILE, "Impossible to remove folder ", path);
	else
		ex.set(Exception::FILE, "Impossible to remove file ", path);
	return false;
}
예제 #4
0
UInt32 FileSystem::Paths(Exception& ex, const char* path, const ForEach& forEach) {
	int err = 0;
	string directory(path);
	FileSystem::MakeDirectory(directory);
	UInt32 count(0);
	string pathFile;

#if defined(_WIN32)
	directory.append("*");

	wchar_t wDirectory[_MAX_PATH];
	MultiByteToWideChar(CP_UTF8, 0, directory.c_str(), -1, wDirectory, _MAX_PATH);
	
	WIN32_FIND_DATAW fileData;
	HANDLE	fileHandle = FindFirstFileW(wDirectory, &fileData);
	if (fileHandle == INVALID_HANDLE_VALUE) {
		if ((err = GetLastError()) != ERROR_NO_MORE_FILES) {
			ex.set(Exception::FILE, "The system cannot find the directory ", path);
			return count;
		}
		return count;
	}
	do {
		if (wcscmp(fileData.cFileName, L".") != 0 && wcscmp(fileData.cFileName, L"..") != 0) {
			++count;
			String::Append(MakeDirectory(pathFile.assign(path)), fileData.cFileName);
			if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				pathFile.append("/");
			forEach(pathFile);
		}
	} while (FindNextFileW(fileHandle, &fileData) != 0);
	FindClose(fileHandle);
#else
	DIR* pDirectory = opendir(directory.c_str());
	if (!pDirectory) {
		ex.set(Exception::FILE, "The system cannot find the directory ",directory);
		return count;
	}
	struct dirent* pEntry(NULL);
	while((pEntry = readdir(pDirectory))) {
		if (strcmp(pEntry->d_name, ".")!=0 && strcmp(pEntry->d_name, "..")!=0) {
			++count;
			String::Append(pathFile.assign(directory), pEntry->d_name);
			// Cross-platform solution when DT_UNKNOWN or symbolic link
			if(pEntry->d_type==DT_DIR)
				pathFile.append("/");
			else if(pEntry->d_type==DT_UNKNOWN || pEntry->d_type==DT_LNK) {
				Status status;
				Stat(pathFile, status);
				if ((status.st_mode&S_IFMT) == S_IFDIR)
					pathFile.append("/");
			}
			forEach(pathFile);
		}
	}
	closedir(pDirectory);
#endif
	return count;
}
예제 #5
0
파일: LUAXML.cpp 프로젝트: 8088/MonaServer
bool LUAXML::LUAToXML(Exception& ex, lua_State* pState, int index, const PoolBuffers& poolBuffers) {
	// index - LUA XML table
	if (!lua_istable(pState, index)) {
		ex.set(Exception::APPLICATION, "Just LUA table can be convert to XML");
		return false;
	}

	PacketWriter writer(poolBuffers);
	const char* name(NULL);
	bool result(false);
	
	lua_pushnil(pState);  // first key 
	while (lua_next(pState, index) != 0) {
		// uses 'key' (at index -2) and 'value' (at index -1) 
		if (lua_type(pState, -2) == LUA_TSTRING) {

			name = lua_tostring(pState, -2);

			if (lua_istable(pState, -1)) {

				// information fields { xml = {version = 1.0}, ... }

				writer.write("<?").write(name).write(" ");

				lua_pushnil(pState);  // first key 
				while (lua_next(pState, -2) != 0) {
					// uses 'key' (at index -2) and 'value' (at index -1) 
					if (lua_type(pState, -2) == LUA_TSTRING && lua_isstring(pState, -1))
						writer.write(lua_tostring(pState, -2)).write("=\"").write(lua_tostring(pState, -1)).write("\" ");
					else
						ex.set(Exception::APPLICATION, "Bad ", name, " XML attribute information, key must be string and value convertible to string");
					lua_pop(pState, 1);
				}

				writer.write("?>");
			} else
				ex.set(Exception::APPLICATION, "Bad ",name," XML information, value must be a table");

		} else if (lua_isnumber(pState, -2)) {
			if(lua_istable(pState, -1))
				result = LUAToXMLElement(ex, pState, writer);
			else
				ex.set(Exception::APPLICATION, "Impossible to write inner XML data on the top of XML level");
		}  else
			ex.set(Exception::APPLICATION, "Impossible to convert the key of type ",lua_typename(pState,lua_type(pState,-2)),"to a correct XML root element");

		lua_pop(pState, 1);
	}

	if (result)
		lua_pushlstring(pState,STR writer.data(), writer.size());

	return result;
}
예제 #6
0
bool SocketSender::run(Exception& ex) {
	if (!_pSocket) {
		ex.set(Exception::SOCKET, "SocketSender ", name, " started in parallel without pointer of socket");
		return false;
	}
	// send
	Exception exc;
	shared_ptr<SocketSender> pThis(_pThis);
	_pSocket->send(exc, pThis);
	if (exc.code() != Exception::ASSERT)
		ex.set(exc);
	return true;
}
예제 #7
0
UInt32 FileSystem::GetSize(Exception& ex,const char* path) {
	Status status;
	status.st_size = 0;
	string file(path);
	size_t oldSize(file.size());
	if (Stat(MakeFile(file).c_str(), status) != 0 || status.st_mode&S_IFDIR) {
		ex.set(Exception::FILE, "File ", path, " doesn't exist");
		return 0;
	}
	if (oldSize>file.size()) { // if was a folder
		ex.set(Exception::FILE, "GetSize works just on file, and ", path, " is a folder");
		return 0;
	}
	return (UInt32)status.st_size;
}
예제 #8
0
WinRegistryKey::Type WinRegistryKey::type(Exception& ex,const string& name) {
	if (!open(ex))
		return REGT_NONE;
	DWORD type = REG_NONE;
	DWORD size;
	if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, NULL, &size) != ERROR_SUCCESS) {
		ex.set(Exception::REGISTRY, "Key ", key(name), " not found");
		return REGT_NONE;
	}
	if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_DWORD) {
		ex.set(Exception::REGISTRY, key(name), ", type not supported");
		return REGT_NONE;
	}
	return (Type)type;
}
예제 #9
0
bool RTMFPCookieComputing::run(Exception& ex) {
	// First execution is for the DH computing if pDH == null, else it's to compute Diffie-Hellman keys
	if (!_diffieHellman.initialized())
		return _diffieHellman.initialize(ex);

	// Compute Diffie-Hellman secret
	_diffieHellman.computeSecret(ex,initiatorKey.data(),initiatorKey.size(),_sharedSecret);
	if (ex)
		return false;

	if (packet.size() > 0) {
		ex.set(Exception::CRYPTO, "RTMFPCookieComputing already executed");
		return false;
	}

	// string hex;
	// DEBUG("Shared Secret : ", Util::FormatHex(_sharedSecret.data(), _sharedSecret.size(), hex));

	// It's our key public part
	int size = _diffieHellman.publicKeySize(ex);
	if (size<0) {
		if (!ex)
			ex.set(Exception::CRYPTO, "DH public key not initialized");
		return false;
	}
	packet.write7BitLongValue(size+11);
	UInt32 noncePos = packet.size();
	packet.writeRaw(EXPAND_DATA_SIZE("\x03\x1A\x00\x00\x02\x1E\x00"));
	UInt8 byte2 = DH_KEY_SIZE-size;
	if(byte2>2) {
		CRITIC("Generation DH key with less of 126 bytes!");
		byte2=2;
	}
	packet.write8(0x81);
	packet.write8(2-byte2);
	packet.write8(0x0D);
	packet.write8(0x02);
	if (size>2000)
		ERROR("RTMFP diffie hellman public key with an error size key of ",size) // TODO remove this log one time fixed!
	_diffieHellman.readPublicKey(ex,packet.buffer(size));
	packet.write8(0x58);

	// Compute Keys
	RTMFP::ComputeAsymetricKeys(_sharedSecret,initiatorNonce.data(),initiatorNonce.size(),packet.data()+noncePos,size+11,decryptKey,encryptKey);
	
	waitHandle();
	return true;
}
예제 #10
0
bool HTTPSender::run(Exception& ex) {
	if (!_pRequest && (!_pWriter || _sizePos>0)) { // accept just HTTPSender::writeRaw call, for media streaming
		ex.set(Exception::PROTOCOL, "No HTTP request to send the reply");
		return false;
	}

	if (!_pWriter) {

		//// GET FILE
		Time time;
		// Not Modified => don't send the file
		if (_file.lastModified()>0 && _pRequest->ifModifiedSince >= _file.lastModified()) {
			write("304 Not Modified", HTTP::CONTENT_ABSENT);
		} else {
			if (_file.lastModified()==0) {
				// file doesn't exist, test directory
				string dir(_file.fullPath());
				if (FileSystem::Exists(FileSystem::MakeDirectory(dir))) {
					// Redirect to the real path of directory
					DataWriter& response = write("301 Moved Permanently"); // TODO check that it happens sometimes or never!
					BinaryWriter& writer = response.packet;
					String::Format(_buffer, "http://", _pRequest->serverAddress, _file.path(), '/');
					HTTP_BEGIN_HEADER(writer)
						HTTP_ADD_HEADER(writer, "Location", _buffer)
					HTTP_END_HEADER(writer)
					HTML_BEGIN_COMMON_RESPONSE(writer, "Moved Permanently")
						writer.writeRaw("The document has moved <a href=\"", _buffer, "\">here</a>.");
					HTML_END_COMMON_RESPONSE(writer, _buffer)
				} else
					writeError(404, String::Format(_buffer,"File ", _file.path(), " doesn't exist"));
			} else {
예제 #11
0
파일: Peer.cpp 프로젝트: fxlt/MonaServer
void Peer::onConnection(Exception& ex, Writer& writer,DataReader& parameters,DataWriter& response) {
	if(!connected) {
		_pWriter = &writer;

		// reset default protocol parameters
		_parameters.clear();
		Parameters::ForEach forEach([this](const string& key,const string& value) {
			_parameters.setString(key,value);
		});
		string buffer;
		_handler.iterate(String::Format(buffer,protocol,"."), forEach);

		ParameterWriter parameterWriter(_parameters);
		SplitWriter parameterAndResponse(parameterWriter,response);

		_handler.onConnection(ex, *this,parameters,parameterAndResponse);
		if (!ex) {
			(bool&)connected = ((Entities<Client>&)_handler.clients).add(*this);
			if (!connected) {
				ex.set(Exception::PROTOCOL, "Client ", Util::FormatHex(id, ID_SIZE, buffer), " exists already");
				ERROR(ex.error());
				_handler.onDisconnection(*this);
			}
		}
		if (!connected) {
			writer.abort();
			_pWriter = NULL;
		} else {
			OnInitParameters::raise(_parameters);
			DEBUG("Client ",address.toString()," connection")
		}
		writer.open(); // open even if "ex" to send error messages!
	} else
예제 #12
0
bool LUAIPAddress::Read(Exception& ex, lua_State *pState, int index, IPAddress& address,bool withDNS) {

	if (lua_type(pState, index)==LUA_TSTRING) // lua_type because can be encapsulated in a lua_next
		return withDNS ? address.setWithDNS(ex, lua_tostring(pState,index)) : address.set(ex, lua_tostring(pState,index));

	if(lua_istable(pState,index)) {
		bool isConst;

		IPAddress* pOther = Script::ToObject<IPAddress>(pState, isConst, index);
		if (pOther) {
			address.set(*pOther);
			return true;
		}

		SocketAddress* pAddress = Script::ToObject<SocketAddress>(pState, isConst, index);
		if (pAddress) {
			address.set(pAddress->host());
			return true;
		}

		ServerConnection* pServer = Script::ToObject<ServerConnection>(pState, isConst, index);
		if (pServer) {
			address.set(pServer->address.host());
			return true;
		}
	}

	ex.set(Exception::NETADDRESS, "No valid IPAddress available to read");
	return false;
}
예제 #13
0
ADD_TEST(DateTest, ParseISO8601Frac) {
	
	CHECK(Parse("2005-01-08T12:30:00.1Z", 2005, 1, 8,6, 12, 30, 0, 100, Date::GMT));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.100Z");
	
	CHECK(Parse("2005-01-08T12:30:00.123+01:00", 2005, 1, 8,6, 12, 30, 0, 123, 3600000));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.123+01:00");
	
	CHECK(Parse("2005-01-08T12:30:00Z", 2005, 1, 8,6, 12, 30, 0, 0, Date::GMT));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.000Z");
	
	CHECK(Parse("2005-01-08T12:30:00+01:00", 2005, 1, 8,6, 12, 30, 0, 0, 3600000));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.000+01:00");

	CHECK(Parse("2014-04-22T06:00:00.000+02:00", 2014, 4, 22, 2, 6, 0, 0, 0, 7200000));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2014-04-22T06:00:00.000+02:00");

	CHECK(!Ex);

	CHECK(Parse("2005-01-08T12:30:00.12345-01:00", 2005, 1, 8,6, 12, 30, 0, 123, -3600000));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.123-01:00");
	
	CHECK(Parse("2010-09-23T16:17:01.2817002+02:00", 2010, 9, 23, 4, 16, 17, 1, 281, 7200000));
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2010-09-23T16:17:01.281+02:00");
	
	CHECK(Parse("2005-01-08T12:30:00.123456", 2005, 1, 8,6, 12, 30, 0, 123, Date::LOCAL));

	CHECK(Parse("2005-01-08T12:30:00.012034", 2005, 1, 8,6, 12, 30, 0, 12, Date::LOCAL));
	_Date.setOffset(4020000);
	CHECK(_Date.offset()==4020000);
	CHECK(_Date.toString(Date::ISO8601_FRAC_FORMAT, _Out) == "2005-01-08T12:30:00.012+01:07");

	CHECK(Ex); // warning on microsecond lost information
	Ex.set(Exception::NIL);
}
예제 #14
0
파일: LUAXML.cpp 프로젝트: 8088/MonaServer
bool LUAXML::LUAToXMLElement(Exception& ex, lua_State* pState, PacketWriter& writer) {
	// -1 => table

	lua_pushstring(pState, "__name");
	lua_rawget(pState, -2);
	const char* name(lua_tostring(pState, -1));
	lua_pop(pState, 1);
	if (!name) {
		ex.set(Exception::APPLICATION, "Impossible to write a XML element without name (__name)");
		return false;
	}

	// write attributes
	writer.write("<").write(name).write(" ");
	lua_pushnil(pState);  // first key 
	while (lua_next(pState, -2) != 0) {
		// uses 'key' (at index -2) and 'value' (at index -1) 
		if (lua_type(pState, -2) == LUA_TSTRING && strcmp(lua_tostring(pState, -2),"__name")!=0 && lua_isstring(pState, -1))
			writer.write(lua_tostring(pState, -2)).write("=\"").write(lua_tostring(pState, -1)).write("\" ");
		lua_pop(pState, 1);
	}
	if (lua_objlen(pState, -1) == 0) {
		writer.write("/>");
		return true;
	}

	writer.write(">");

	// write elements
	lua_pushnil(pState);  // first key 
	while (lua_next(pState, -2) != 0) {
		// uses 'key' (at index -2) and 'value' (at index -1) 
		if (lua_isnumber(pState, -2)) {
			if (lua_istable(pState, -1))
				LUAToXMLElement(ex, pState, writer); // table child
			else if (lua_isstring(pState, -1))
				writer.write(lua_tostring(pState, -1), lua_objlen(pState, -1)); // __value
			else
				ex.set(Exception::APPLICATION, "Impossible to convert the value of type ", lua_typename(pState, lua_type(pState, -1)), "to a correct XML value of ",name);
		} else if (lua_type(pState, -2) != LUA_TSTRING)
			ex.set(Exception::APPLICATION, "Impossible to convert the key of type ",lua_typename(pState,lua_type(pState,-2)),"to a correct XML element of ",name);
		lua_pop(pState, 1);
	}

	writer.write("</").write(name).write(">");
	return true;
}
예제 #15
0
파일: RTMFP.cpp 프로젝트: luc1el/MonaServer
bool RTMFP::Decode(Exception& ex,RTMFPEngine& aesDecrypt,PacketReader& packet) {
	// Decrypt
	aesDecrypt.process(packet.current(),(UInt8*)packet.current(),packet.available());
	bool result = ReadCRC(packet);
	if (!result)
		ex.set(Exception::CRYPTO, "Bad RTMFP CRC sum computing");
	return result;
}
예제 #16
0
bool WinRegistryKey::setString(Exception& ex, const string& name, const string& value) {
	if (!open(ex))
		return false;
	if (RegSetValueExA(_hKey, name.c_str(), 0, REG_SZ, (CONST BYTE*) value.c_str(), (DWORD) value.size() + 1) == ERROR_SUCCESS)
		return true;
	ex.set(Exception::REGISTRY, "Failed to set registry value ", key(name));
	return false;
}
예제 #17
0
bool WinRegistryKey::setInt(Exception& ex,const string& name, int value) {
	if (!open(ex))
		return false;
	DWORD data = value;
	if (RegSetValueExA(_hKey, name.c_str(), 0, REG_DWORD, (CONST BYTE*) &data, sizeof(data)) == ERROR_SUCCESS)
		return true;
	ex.set(Exception::REGISTRY, "Failed to set registry value ", key(name));
	return false;
}
예제 #18
0
void TCPClient::onReadable(Exception& ex,UInt32 available) {

	if (available == 0) {
		close(); // Graceful disconnection
		return;
	}

	lock_guard<recursive_mutex> lock(_mutex);

	if(available>(_pBuffer->size() - _rest))
		_pBuffer->resize(_rest+available,true);

	Exception exRecv;
	int received = _socket.receiveBytes(exRecv,_pBuffer->data()+_rest, available);
	if (received <= 0) {
		if (exRecv)
			onError(exRecv); // to be before onDisconnection!
		close(); // Graceful disconnection
		return;
	} else if (exRecv)
		ex.set(exRecv); // received > 0, so WARN


	_rest += received;

	while (_rest > 0) {

		_pBuffer->resize(_rest,true);
		UInt32 rest = onReception(_pBuffer);

		 // To prevent the case where the buffer has been manipulated during onReception call
		if(_pBuffer.empty())
			rest = 0;
		else if (_pBuffer->size() < _rest)
			_rest = _pBuffer->size();

		if (rest > _rest)
			rest = _rest;
		if (rest == 0) {
			// has consumed all
			_pBuffer.release();
			_rest = 0;
			break;
		}
		if (_rest == rest) // no new bytes consumption, wait next reception
			break;


		// has consumed few bytes (but not all)
		// 0 < rest < _rest <= _pBuffer->size()
		memmove(_pBuffer->data(), _pBuffer->data() + (_rest - rest), rest); // move to the beginning

		_rest = rest;
	}

}
예제 #19
0
int WinRegistryKey::getInt(Exception& ex,const string& name) {
	if (!open(ex))
		return 0;
	int value(0);
	DWORD type;
	DWORD size = sizeof(value);
	if (RegQueryValueExA(_hKey, name.c_str(), NULL, &type, (BYTE*)&value, &size) == ERROR_SUCCESS && type == REG_DWORD)
		return value;
	ex.set(Exception::REGISTRY, "Key ", key(name), " not found");
	return 0;
}
예제 #20
0
bool TCPClient::connect(Exception& ex,const SocketAddress& address) {
	lock_guard<recursive_mutex> lock(_mutex);
	if (_disconnecting) {
		ex.set(Exception::SOCKET, "TCPClient is always connected to ", _peerAddress.toString(), ", call disconnect() before, and wait onDisconnection event");
		return false;
	}
	_connected = _socket.connect(ex, address);
	if (!_connected)
		return false;
	_peerAddress.set(address);
	return true;
}
예제 #21
0
파일: DNS.cpp 프로젝트: blueram/MonaServer
bool DNS::HostName(Exception& ex,string& host) {
	if(!Net::InitializeNetwork(ex))
		return false;
	char buffer[256];
	int rc = gethostname(buffer, sizeof(buffer));
	if (rc == 0) {
		host.assign(buffer);
		return true;
	}
	ex.set(Exception::NETADDRESS,"Cannot get host name");
	return false;
}
예제 #22
0
UInt16 SocketAddress::resolveService(Exception& ex,const string& service) {
	UInt16 port=0;
	if (String::ToNumber<UInt16>(service,port))
		return port;
	if (!Net::InitializeNetwork(ex))
		return 0;
	struct servent* se = getservbyname(service.c_str(), NULL);
	if (se)
		return ntohs(se->s_port);
	ex.set(Exception::NETADDRESS, "Service ", service, " unknown");
	return 0;
}
예제 #23
0
파일: Net.cpp 프로젝트: gz818/MonaServer
bool Net::InitializeNetwork(Exception& ex) {
	lock_guard<mutex> lock(Mutex);
	if (Initialized)
		return true;
	WORD    version = MAKEWORD(2, 2);
	WSADATA data;
	if (WSAStartup(version, &data) != 0) {
		ex.set(Exception::NETWORK, "Failed to initialize network subsystem");
		return false;
	}
	return Initialized = true;
}
예제 #24
0
bool WinRegistryKey::open(Exception& ex) {
	if (_hKey)
		return true;
	if (_readOnly) {
		if (RegOpenKeyExA(_hRootKey, _subKey.c_str(), 0, KEY_READ | _extraSam, &_hKey) == ERROR_SUCCESS)
			return true;
	} else {
		if (RegCreateKeyExA(_hRootKey, _subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | _extraSam, NULL, &_hKey, NULL) == ERROR_SUCCESS)
			return true;
	}
	ex.set(Exception::REGISTRY,"Cannot open registry ", key());
	return false;
}
예제 #25
0
void RTMFPWriter::manage(Exception& ex, Invoker& invoker) {
	if(!consumed() && !_band.failed()) {
		
		if(_trigger.raise(ex))
			raiseMessage();

		if (ex) {
			fail("RTMFPWriter can't deliver its data, ",ex.error());
			return;
		}
	}
	if(critical && state()==CLOSED) {
		ex.set(Exception::NETWORK, "Main flow writer closed, session is closing");
		return;
	}
	flush(false);
}
예제 #26
0
void FileSystem::CreateDirectories(Exception& ex,const string& path) {
	vector<string> directories;
	if (Unpack(path, directories).empty())
		return;
	string dir;
	if (directories.front().size()==2 && directories.front().back() == ':') {
		// device
		dir.append(directories.front());
		directories.erase(directories.begin());
	}
	for (const string& directory : directories) {
		dir.append("/");
		dir.append(directory);
		if (!CreateDirectory(dir)) {
			ex.set(Exception::FILE, "Impossible to create ", dir, " directory");
			return;
		}
	}
}
예제 #27
0
void TCPClient::receive(Exception& ex, UInt32 available) {
	
	if (available>0)
		onSending(0); // to update _idleTime

	if (available == 0) {
		close(); // Graceful disconnection
		return;
	}

	UInt32 size(_pBuffer->size());
	_pBuffer->resize(size+available,true);
	
	Exception exRecv;
	
	int received = _socket.receiveBytes(exRecv,_pBuffer->data()+size, available);

	if (received <= 0) {
		if (exRecv)
			OnError::raise(exRecv); // to be before onDisconnection!
		close(); // Graceful disconnection
		return;
	} else if (exRecv)
		ex.set(exRecv); // received > 0, so WARN

	_pBuffer->resize(size+received,true);
	size = 0;

	while(size<_pBuffer->size()) { // while everything is not consumed

		if (size)
			_pBuffer->clip(size);
		
		size = OnData::raise<0xFFFFFFFF>(_pBuffer); // consumed

		if (!size) // if no consumption
			return; // no release here
	}

	_pBuffer.release();
}
예제 #28
0
파일: SDP.cpp 프로젝트: luc1el/MonaServer
bool SDP::build(Exception& ex, const char* text) {

	SDPMedia* pMedia = NULL;

	String::ForEach forEach([this,&pMedia,&ex](UInt32 index,const char* line){
		if(strlen(line)==0 || line[1] != '=') {
			ex.set(Exception::FORMATTING, "SDP line ",line," malformed, second byte isn't an equal sign");
			return false;
		}
	
		UInt8 type = line[0];
		line = String::TrimLeft(line);

		// RFC 4566
		switch(type) {
			case 'v': // v=  (protocol version)
				version = String::ToNumber<UInt32>(ex, line);
				break;
			case 'o': { // o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
				String::ForEach forEach([&ex,this](UInt32 index, const char* value) {
					switch (index) {
						case 0:
							user.assign(value);
							break;
						case 1:
							sessionId = String::ToNumber<UInt32>(ex, value);
							break;
						case 2:
							sessionVersion = String::ToNumber<UInt32>(ex, value);
							break;
						case 4:
							unicastAddress.set(IPAddress::Wildcard(String::ICompare(value,"IP6")==0 ? IPAddress::IPv6 : IPAddress::IPv4));
							break;
						case 5:
							unicastAddress.set(ex,value,unicastAddress.family());
							break;
					}
					return !ex;
				});
				if(String::Split(line, " ", forEach, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM)<6)
					ex.set(Exception::PROTOCOL, "SDP o line required 6 values (<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>)");
				break;
			}
			case 's': // s=  (session name)
				sessionName = line;
				break;

			/// Optional lines
			case 'i': // i=* (session information)
				sessionInfos = line;
				break;
			case 'u': // u=* (URI of description)
				uri = line;
				break;
			case 'e': // e=* (email address)
				email = line;
				break;
			case 'p': // p=* (phone number)
				phone = line;
				break;
			case 'c': { // c=* (connection information -- not required if included in all media)
				IPAddress defaultAddress;  // TODO defaultAddress is useless for what?
				String::ForEach forEach([&ex,&defaultAddress, this](UInt32 index, const char* value) {
					switch (index) {
						case 1:
							defaultAddress.set(IPAddress::Wildcard(String::ICompare(value,"IP6")==0 ? IPAddress::IPv6 : IPAddress::IPv4));
							break;
						case 2:
							defaultAddress.set(ex,value,defaultAddress.family());
							break;
					}
					return !ex;
				});
				if(String::Split(line, " ", forEach, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM)<3)
					ex.set(Exception::PROTOCOL, "SDP c line required 3 values");
				break;
			}
			case 'b': // b=* (zero or more bandwidth information lines)
				// TODO useless?
				break;
				 
				// One or more time descriptions ("t=" and "r=" lines; see below)
				// t=  (time the session is active)
				// r=* (zero or more repeat times)
			case 't':
				// TODO useless?
				break;
			case 'r':
				// TODO useless?
				break;
			case 'z': // z=* (time zone adjustments)
				// TODO useless?
				break;

			case 'k': // k=* (encryption key)
				encryptKey = line;
				break;
			case 'm': { // m=<name> <port> <proto> <fmt>
				string name;
				UInt16 port;
				String::ForEach forEach([&ex, &pMedia, &name, &port, this](UInt32 index, const char* value) {
					switch (index) {
						case 0:
							name = value;
							break;
						case 1:
							port = String::ToNumber<UInt16>(ex, value);
							break;
						case 2:
							pMedia = addMedia(name, port, value);
							break;
					}
					return !ex;
				});
				if(String::Split(line, " ", forEach, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM)<4)
					ex.set(Exception::PROTOCOL, "SDP m line required 4 values (<name> <port> <proto> <fmt>)");
				break;
			}
			case 'a': { // a=* (zero or more session attribute lines)

				vector<string>* pFields = NULL;
				bool	isMsId = false;
				string   fingerHash;

				// TODO SDPSource* pSource = NULL;
				// TODO list<UInt32>* pSourceGroupe = NULL;


				String::ForEach forEach([&ex, &pMedia, &pFields, &isMsId, &fingerHash, this](UInt32 index, const char* value) {

					// RFC 5576
					if(pMedia) {
						/* TODO
						if(pSourceGroupe)
							pSourceGroupe->push_back(NumberParser::parseUnsigned(field));
						else if(pSource) {
							if(isMsId)
								pSource->msData = field;
							else if(key=="cname") // cname:<value>
								pSource->cname = value;
							else if(key=="msid") {// draft-alvestrand-mmusic-msid-00
								isMsId = true;
								pSource->msId = value;
							} else if(key=="mslabel") // draft-alvestrand-rtcweb-mid-01
								pSource->msLabel = value;
							else if(key=="label") // draft-alvestrand-rtcweb-mid-01
								pSource->label = value;
							else
								WARN("Media source attribute ",key," unknown");
						} else if(key=="ssrc") // a=ssrc:<ssrc-id>
							pSource = &sources[NumberParser::parseUnsigned(key)];// a=ssrc:<ssrc-id> <attribute>
						else if(key=="rtcp-mux")
							pMedia->rtcpMux = true;
						else if(key=="mid")  // RFC 3388, a=mid:<token>
							pMedia->mid = value;
						else if(key=="ssrc-group")  // a=ssrc-group:<semantics>
							pSourceGroupe = &sourceGroupes[value];
						else if(key="crypto") { // a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
							StringTokenizer values(value," ",StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
							poco_assert(values.size()>2)
							pMedia->cryptoTag = 
						} else 
							WARN("Media attribute ",key," unknown");*/
						ERROR("TODO")
					} else if(pFields)
						pFields->emplace_back(value);
					else if(!fingerHash.empty())
						int i=0; // TODO finger = talk_base::SSLFingerprint::CreateFromRfc4572(fingerHash, field);
					else {
						const char* key(value);
						const char* value(String::Empty.c_str());
						const char* colon(strchr(value,':'));
						if (colon) {
							*(char*)colon = 0;
							value = colon + 1;
						}

						if (String::ICompare(key,"group")==0) // RFC 5888 and draft-holmberg-mmusic-sdp-bundle-negotiation-00
							pFields = &groups[value];
						else if (String::ICompare(key,"ice-ufrag")==0)
							iceUFrag = value;
						else if (String::ICompare(key,"ice-pwd")==0)
							icePwd = value;
						else if (String::ICompare(key,"ice-options")==0) {
							pFields = &iceOptions;
							iceOptions.emplace_back(value);
						} else if (String::ICompare(key,"fingerprint")==0) // fingerprint:<hash> <algo>
							fingerHash = value; // fingerprint:<hash>
						else if (String::ICompare(key,"msid-semantic")==0)
							supportMsId = String::ICompare(value ,"VMS")==0;
						else if (String::ICompare(key,"extmap")==0) // RFC 5285 a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
							pFields = &extensions[value];
						else
							WARN("SDP attribute ", key, " unknown");
					}

					return true;
				});

				String::Split(line, " ", forEach, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
				break;
			} // case 'a':

		} // switch(type)
예제 #29
0
void WSSession::packetHandler(PacketReader& packet) {
	UInt8 type = 0;
	Exception ex;
	if(peer.connected) {
		type = packet.read8();	
		
		switch(type) {
			case WS::TYPE_BINARY: {
				RawReader reader(packet);
				peer.onMessage(ex, "onMessage",reader,WS::TYPE_BINARY);
				break;
			}
			case WS::TYPE_TEXT: {
				if(!JSONReader::IsValid(packet)) {
					RawReader reader(packet);
					peer.onMessage(ex, "onMessage",reader);
					break;
				}
				JSONReader reader(packet);
				if(reader.followingType()!=JSONReader::STRING) {
					peer.onMessage(ex, "onMessage",reader);
					break;
				}
				string name;
				reader.readString(name);
				if(name=="__publish") {
					if(reader.followingType()!=JSONReader::STRING) {
						ex.set(Exception::PROTOCOL, "__publish method takes a stream name in first parameter",WS::CODE_MALFORMED_PAYLOAD);
						break;
					}
					reader.readString(name);
					if(_pPublication)
						invoker.unpublish(peer,_pPublication->name());
					_pPublication = invoker.publish(ex, peer,name);
				} else if(name=="__play") {
					if(reader.followingType()!=JSONReader::STRING) {
						ex.set(Exception::PROTOCOL, "__play method takes a stream name in first parameter",WS::CODE_MALFORMED_PAYLOAD);
						break;
					}
					reader.readString(name);
					
					closeSusbcription();
				} else if(name=="__closePublish") {
					closePublication();
				} else if(name=="__closePlay") {
					closeSusbcription();
				} else if (name == "__close") {
					closePublication();
					closeSusbcription();
					
				} else if(_pPublication) {
					reader.reset();
					_pPublication->pushData(reader);
				} else
					peer.onMessage(ex, name,reader);
				break;
			}
			case WS::TYPE_CLOSE:
				_writer.close(packet.available() ? packet.read16() : 0);
				break;
			case WS::TYPE_PING:
				_writer.writePong(packet.current(),packet.available());
				break;
			case WS::TYPE_PONG:
				peer.setPing(_writer.ping = (UInt16)(_time.elapsed()/1000));
				break;
			default:
				ex.set(Exception::PROTOCOL, Format<UInt8>("Type %#x unknown", type), WS::CODE_MALFORMED_PAYLOAD);
				break;
		}
		
		if (ex) {
			ERROR(ex.error());
			_writer.close((ex.code()==Exception::APPLICATION || ex.code() == Exception::SOFTWARE) ? WS::CODE_PROTOCOL_ERROR : ex.code());	
		}
		
	}

	if(!peer.connected || type==WS::TYPE_CLOSE)
		kill();
	else
		_writer.flush();
}
예제 #30
0
Type String::ToNumber(Exception& ex, Type failValue, const char* value, size_t size) {
	int digit = 1, comma = 0;	
	bool beginning = true, negative = false;

	long double result(0);

	bool isSigned = numeric_limits<Type>::is_signed;
	Type max = numeric_limits<Type>::max();

	const char* current(value);
	if (size == string::npos)
		size = strlen(value);

	while(current && size-->0) {

		if (iscntrl(*current) || *current==' ') {
			if (beginning) {
				++current;
				continue;
			}
			ex.set(Exception::FORMATTING, value, " is not a correct number");
			return failValue;
		}

		if (*current == '-') {
			if (isSigned && beginning && !negative) {
				negative = true;
				++current;
				continue;
			}
			ex.set(Exception::FORMATTING, value, " is not a correct number");
			return failValue;
		}

		if (*current == '.' || *current == ',') {
			if (comma == 0 && !beginning) {
				comma = 1;
				++current;
				continue;
			}
			ex.set(Exception::FORMATTING, value, " is not a correct number");
			return failValue;
		}

		if (beginning)
			beginning = false;

		if (isdigit(*current) == 0) {
			ex.set(Exception::FORMATTING, value, " is not a correct number");
			return failValue;
		}

		result = result * 10 + (*current - '0');
		comma *= 10;
		++current;
	}

	if (beginning) {
		ex.set(Exception::FORMATTING, "Empty string is not a number");
		return failValue;
	}

	if (comma > 0)
		result /= comma;

	if (result > max) {
		ex.set(Exception::FORMATTING, value, " exceeds maximum number capacity");
		return failValue;
	}

	if (negative)
		result *= -1;

	return (Type)result;
}