示例#1
0
bool PortMapping::UPnP::check(String &host)
{
	LogDebug("PortMapping::UPnP", "Trying UPnP...");
	
	Address addr;
	addr.set("239.255.255.250", 1900, AF_INET, SOCK_DGRAM);
	
	String message;
	message << "M-SEARCH * HTTP/1.1\r\n";
	message << "HOST: "<<addr<<"\r\n";
	message << "MAN: ssdp:discover\r\n";
	message << "MX: 10\r\n";
	message << "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n";
	
	int attempts = 3;
	duration timeout = milliseconds(250.);
	for(int i=0; i<attempts; ++i)
	{
		BinaryString dgram(message);
		mSock.write(dgram, addr);
		
		using clock = std::chrono::steady_clock;
		std::chrono::time_point<clock> end = clock::now() + std::chrono::duration_cast<clock::duration>(timeout);
		
		while(clock::now() < end)
		{
			Address sender;
			duration left = end - clock::now();
			if(!mSock.read(dgram, sender, left)) break;
			
			if(!sender.isPrivate()) continue;
			
			LogDebug("PortMapping::UPnP", String("Got response from ") + sender.toString());
			try {
				if(parse(dgram))
				{
					LogDebug("PortMapping::UPnP", "UPnP is available");
					mGatewayAddr = sender;
					host = mExternalHost;
					return true;
				}
			}
			catch(const Exception &e)
			{
				// Nothing to do
			}
		}
		
		timeout*= 2;
	}
	
	//LogDebug("PortMapping::UPnP", "UPnP is not available");
	return false;
}
示例#2
0
/*!
\brief Sends an error via the socket
\param sd Socket to send the error to
\param ec Error code to send
\param errMsg Error message string

The packet format is this:
<pre>
	2 bytes  2 bytes        string    1 byte
	----------------------------------------
ERROR | 05    |  ErrorCode |   ErrMsg   |   0  |
	----------------------------------------
</pre>

*/
void sendError(TransferInfo &ti, ErrorCode ec, const QString &errMsg)
{
	qWarning("About to send error %d [%s]", ec, errMsg.latin1());
	QByteArray dgram( errMsg.length() + 5 );
	
	wordOfArray(dgram)[0] = htons( (uint16_t)ERROR );
	wordOfArray(dgram)[1] = htons( (uint16_t)ec );
	
	memcpy( dgram.data() + 4, errMsg.ascii(), errMsg.length()+1 );
	
	if( ti.sd->writeBlock(dgram.data(), dgram.size(), ti.dAddr, ti.dPort) == -1 )
		qWarning( "Error sending error packet o_O %d", ti.sd->error() );
}