Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
bool DNS::Resolve(Exception& ex, const char* address, HostEntry& host) {
	IPAddress ip;
	Exception ignore;
	if (ip.set(ignore, address))
		return HostByAddress(ex,ip,host);
	return HostByName(ex, address, host);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
ADD_TEST(DNSTest, HostByAddress) {
	Exception ex;
	HostEntry hostEntry;

	IPAddress ip;
	ip.set(ex, "80.122.195.86");
	CHECK(!ex)
	DNS::HostByAddress(ex, ip, hostEntry);
	CHECK(!ex)
	CHECK(hostEntry.name() == "mailhost.appinf.com");
	CHECK(hostEntry.aliases().empty());
	CHECK(hostEntry.addresses().size() >= 1);
	CHECK(hostEntry.addresses().front().toString() == "80.122.195.86");

	ip.set(ex, "10.0.244.253");
	CHECK(!ex)
	DNS::HostByAddress(ex, ip, hostEntry);
	CHECK(ex)
}
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
bool SDP::build(Exception& ex, const string& text) {

	SDPMedia* pMedia = NULL;

	vector<string> lines;
	String::Split(text, "\r\n", lines, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
	for(string& line : lines) {

		if(line.empty() || line[1] != '=') {
			ex.set(Exception::FORMATTING, "SDP line ",line," malformed, second byte isn't an equal sign");
			return false;
		}
	
		UInt8 type = line[0];
		line.erase(0,2);
		String::Trim(line, String::TRIM_LEFT);

		// 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>
				vector<string> fields;
				String::Split(line, " ", fields, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
				if (fields.size()!=6) {
					ex.set(Exception::PROTOCOL, "fields.size()!=6");
					break;
				}
				user = fields[0];
				sessionId = String::ToNumber<UInt32>(ex, fields[1]);
				if (ex)
					break;
				sessionVersion = String::ToNumber<UInt32>(ex, fields[2]);
				if (ex)
					break;

				unicastAddress.set(ex,fields[5],fields[4]=="IP6" ? IPAddress::IPv6 : IPAddress::IPv4);
				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)
				vector<string> fields;
				String::Split(line, " ", fields, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
				if(fields.size()!=3) {
					ex.set(Exception::PROTOCOL, "fields.size()!=3");
					break;
				}

				IPAddress defaultAddress;  // TODO defaultAddress is useless for what?
				defaultAddress.set(ex,fields[2], fields[1] == "IP6" ? IPAddress::IPv6 : IPAddress::IPv4);
				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>
				vector<string> values;
				String::Split(line, " ", values, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
				if (values.size()<4) {
					ex.set(Exception::PROTOCOL , "values.size()<4");
					break;
				}

				UInt16 val = String::ToNumber<UInt16>(ex, values[1]);
				if (ex)
					break;

				pMedia = addMedia(values[0], val, values[2]);
				for(const string& st : values) {
					pMedia->formats.emplace_back(String::ToNumber<UInt8>(ex, st));
					if (ex)
						break;
				}
				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;

				vector<string> fields;
				String::Split(line, " ", fields, String::SPLIT_IGNORE_EMPTY | String::SPLIT_TRIM);
				for(const string& st : fields) {
					size_t pos = st.find(':');
					string key,value;
					if(pos!=string::npos) {
						key = st.substr(0,pos);
						value = st.substr(pos+1);
					} else 
						key = st;

					// 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");
					} else if(pFields)
						pFields->emplace_back(st);
					else if(!fingerHash.empty())
						int i=0; // TODO finger = talk_base::SSLFingerprint::CreateFromRfc4572(fingerHash, field);
					else if(key=="group") // RFC 5888 and draft-holmberg-mmusic-sdp-bundle-negotiation-00
						pFields = &groups[value];
					else if(key=="ice-ufrag")
						iceUFrag = value;
					else if(key=="ice-pwd")
						icePwd = value;
					else if(key=="ice-options") {
						pFields = &iceOptions;
						iceOptions.emplace_back(value);
					} else if(key=="fingerprint") // fingerprint:<hash> <algo>
						fingerHash = value; // fingerprint:<hash>
					else if(key=="msid-semantic")
						supportMsId = value=="VMS";
					else if(key=="extmap") // RFC 5285 a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
						pFields = &extensions[value];
					else 
						WARN("SDP attribute ",key," unknown");
				}
			} // case 'a':
			break;
		} // switch(type)

		if (ex) {
			ex.set(Exception::PROTOCOL, "SDP '",type,"' value ",line," malformed, ",ex.error());
			return false;
		}
	} // for(string& line : lines)

	return true;
}