Example #1
0
void TCPConnectionPair::onPeerDataReceived(net::Socket&,
                                           const MutableBuffer& buffer,
                                           const net::Address& peerAddress)
{
    TraceS(this) << "Peer => Client: " << buffer.size() << endl;
    // assert(pkt.buffer.position() == 0);
    // if (pkt.buffer.available() < 300)
    //    TraceS(this) << "Peer => Client: " << pkt.buffer << endl;
    // auto socket = reinterpret_cast<net::Socket*>(sender);
    // char* buf = bufferCast<char*>(buf);

    // Buffer& buf = pkt.buffer;
    const char* buf = bufferCast<const char*>(buffer);
    std::size_t len = buffer.size();
    if (client) {

        allocation.updateUsage(len);
        if (allocation.deleted())
            return;

        // assert(buf.position() == 0);
        client->send(buf, len);
    }

    // Flash policy requests
    // TODO: Handle elsewhere? Bloody flash...
    else if (len == 23 && (strcmp(buf, "<policy-file-request/>") == 0)) {
        TraceS(this) << "Handle flash policy" << endl;
        std::string policy(
            "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from "
            "domain=\"*\" to-ports=\"*\" /></cross-domain-policy>");
        // assert(peer->get() == pkt.info->socket);
        peer->send(policy.c_str(), policy.length() + 1);
        peer->close();
    }

    // Buffer early media
    // TODO: Make buffer size server option
    else {
        std::size_t maxSize =
            allocation.server().options().earlyMediaBufferSize;
        DebugS(this) << "Buffering early data: " << len << endl;
        //#ifdef _DEBUG
        //        DebugS(this) << "Printing early data: " << std::string(buf,
        //        len) << endl;
        //#endif
        if (len > maxSize)
            WarnL << "Dropping early media: Oversize packet: " << len << endl;
        if (earlyPeerData.size() > maxSize)
            WarnL << "Dropping early media: Buffer at capacity >= " << maxSize
                  << endl;

        // earlyPeerData.append(static_cast<const char*>(pkt.data()), len);
        earlyPeerData.insert(earlyPeerData.end(), buf, buf + len);
    }
}
void Server::onSocketRecv(void* sender, const MutableBuffer& buffer, const net::Address& peerAddress)
{
    TraceL << "Data received: " << buffer.size() << endl;    
     //auto info = reinterpret_cast<net::PacketInfo*>(packet.info);
    //assert(info);
    //if (!info)
    //    return;    const net::TCPSocket::Ptr& socket
    stun::Message message;
    auto socket = reinterpret_cast<net::Socket*>(sender);        
    char* buf = bufferCast<char*>(buffer);
    std::size_t len = buffer.size();
    std::size_t nread = 0;
    while (len > 0 && (nread = message.read(constBuffer(buf, len))) > 0) {
        if (message.classType() == stun::Message::Request || 
            message.classType() == stun::Message::Indication) {                
            Request request(message, socket->transport(), socket->address(), peerAddress); //getTCPSocket(socket->address()), 
            //if (!request.socket) {
            //    assert(0 && "invalid socket");
            //    continue;
            //}

            // TODO: Only authenticate stun::Message::Request types
            handleRequest(request, _observer.authenticateRequest(this, request));
        }
        else {
            assert(0 && "unknown request type");
        }

        buf += nread;
        len -= nread;
    }
    if (len == buffer.size())
        WarnL << "Non STUN packet received" << std::endl;

#if 0
    stun::Message message;
    if (message.read(constBuffer(packet.data(), packet.size()))) {
        assert(message.state() == stun::Message::Request);    

        Request request(*info->socket, message, info->socket->address(), info->peerAddress);
        AuthenticationState state = _observer.authenticateRequest(this, request);
        handleRequest(request, state);
    }
    else
#endif
}


void Server::onTCPSocketClosed(void* sender)
{
    TraceL << "TCP socket closed" << endl;    
    releaseTCPSocket(reinterpret_cast<net::Socket*>(sender));
}
Example #3
0
void TCPConnectionPair::onClientDataReceived(void*, const MutableBuffer& buffer, const net::Address& peerAddress)
{
	TraceLS(this) << "Client => Peer: " << buffer.size() << endl;	
	//assert(packet.buffer.position() == 0);
	//if (packet.size() < 300)
	//	TraceLS(this) << "Client => Peer: " << packet.buffer << endl;	

	if (peer) {
		allocation.updateUsage(buffer.size());
		if (allocation.deleted())
			return;

		peer->send(bufferCast<char*>(buffer), buffer.size());
	}
}
Example #4
0
void WebSocketAdapter::handleServerRequest(const MutableBuffer& buffer)
{
	//http::Request request;
	http::Parser parser(&_request);
	if (parser.parse(bufferCast<char *>(buffer), buffer.size())) {
		throw std::runtime_error("WebSocket error: Cannot parse request: Incomplete HTTP message");
	}
	
	TraceLS(this) << "Verifying handshake: " << _request << endl;

	// Allow the application to verify the incoming request.
	// TODO: Handle authentication
	//VerifyServerRequest.emit(this, request);
	
	// Verify the WebSocket handshake request
	try {
		framer.acceptRequest(_request, _response);
		TraceLS(this) << "Handshake success" << endl;
	}
	catch (std::exception& exc) {
		WarnL << "Handshake failed: " << exc.what() << endl;		
	}

	// Allow the application to override the response
	//PrepareServerResponse.emit(this, response);
				
	// Send response
	std::ostringstream oss;
	_response.write(oss);
	
	assert(socket);
	/*socket->*/SocketAdapter::send(oss.str().c_str(), oss.str().length());
}
Example #5
0
void UDPAllocation::onPeerDataReceived(void*, const MutableBuffer& buffer, const net::Address& peerAddress)
{	
	//auto source = reinterpret_cast<net::PacketInfo*>(packet.info);
	TraceL << "Received UDP Datagram from " << peerAddress << endl;	
	
	if (!hasPermission(peerAddress.host())) {
		TraceL << "No Permission: " << peerAddress.host() << endl;	
		return;
	}

	updateUsage(buffer.size());
	
	// Check that we have not exceeded out lifetime and bandwidth quota.
	if (IAllocation::deleted())
		return;
	
	stun::Message message(stun::Message::Indication, stun::Message::DataIndication);
		
	// Try to use the externalIP value for the XorPeerAddress 
	// attribute to overcome proxy and NAT issues.
	std::string peerHost(server().options().externalIP);
	if (peerHost.empty()) {
		peerHost.assign(peerAddress.host());
		assert(0 && "external IP not set");
	}
	
	auto peerAttr = new stun::XorPeerAddress;
	peerAttr->setAddress(net::Address(peerHost, peerAddress.port()));
	message.add(peerAttr);

	auto dataAttr = new stun::Data;
	dataAttr->copyBytes(bufferCast<const char*>(buffer), buffer.size());
	message.add(dataAttr);
	
	//Mutex::ScopedLock lock(_mutex);

	TraceL << "Send data indication:" 
		<< "\n\tFrom: " << peerAddress
		<< "\n\tTo: " << _tuple.remote()
		//<< "\n\tData: " << std::string(packet.data(), packet.size())
		<< endl;
		
	server().udpSocket().sendPacket(message, _tuple.remote());
	
	//net::Address tempAddress("58.7.41.244", _tuple.remote().port());
	//server().udpSocket().send(message, tempAddress);
}
Example #6
0
void Server::onSocketRecv(net::Socket& socket, const MutableBuffer& buffer,
                          const net::Address& peerAddress)
{
    TraceL << "Data received: " << buffer.size() << endl;

    stun::Message message;
    char* buf = bufferCast<char*>(buffer);
    std::size_t len = buffer.size();
    std::size_t nread = 0;
    while (len > 0 && (nread = message.read(constBuffer(buf, len))) > 0) {
        if (message.classType() == stun::Message::Request ||
            message.classType() == stun::Message::Indication) {
            Request request(message, socket.transport(), socket.address(),
                            peerAddress);

            // TODO: Only authenticate stun::Message::Request types
            handleRequest(request,
                          _observer.authenticateRequest(this, request));
        } else {
            assert(0 && "unknown request type");
        }

        buf += nread;
        len -= nread;
    }
    if (len == buffer.size())
        WarnL << "Non STUN packet received" << std::endl;

#if 0
    stun::Message message;
    if (message.read(constBuffer(packet.data(), packet.size()))) {
        assert(message.state() == stun::Message::Request);

        Request request(*info->socket, message, info->socket->address(), info->peerAddress);
        AuthenticationState state = _observer.authenticateRequest(this, request);
        handleRequest(request, state);
    }
    else
#endif
}


void Server::onTCPSocketClosed(net::Socket& socket)
{
    TraceL << "TCP socket closed" << endl;
    releaseTCPSocket(&socket);
}
Example #7
0
void WebSocketAdapter::handleClientResponse(const MutableBuffer& buffer)
{
	TraceLS(this) << "Client response: " << buffer.size() << endl;
	http::Parser parser(&_response);
	if (!parser.parse(bufferCast<char *>(buffer), buffer.size())) {
		throw std::runtime_error("WebSocket error: Cannot parse response: Incomplete HTTP message");
	}
	
	// TODO: Handle resending request for authentication
	// Should we implement some king of callback for this?

	// Parse and check the response
	if (framer.checkHandshakeResponse(_response)) {				
		TraceLS(this) << "Handshake success" << endl;
		SocketAdapter::onSocketConnect();
	}			
}
void ConnectionAdapter::onSocketRecv(const MutableBuffer& buf, const net::Address& /* peerAddr */)
{
    TraceS(this) << "On socket recv: " << buf.size() << endl;
    // TraceS(this) << "On socket recv: " << buf.str() << endl;

    if (_parser.complete()) {
        // Buggy HTTP servers might send late data or multiple responses,
        // in which case the parser state might already be HPE_OK.
        // In this case we discard the late message and log the error here,
        // rather than complicate the app with this error handling logic.
        // This issue was noted using Webrick with Ruby 1.9.
        WarnS(this) << "Dropping late HTTP response: " << buf.str() << endl;
        return;
    }

    // Parse incoming HTTP messages
    _parser.parse(bufferCast<const char*>(buf), buf.size());
}
Example #9
0
void TCPClient::onRelayDataReceived(void* sender, const MutableBuffer& buffer, const net::Address& peerAddress)
{
	auto ptr = reinterpret_cast<net::Socket*>(sender);
	auto req = reinterpret_cast<RelayConnectionBinding*>(ptr->opaque);
	assert(connections().has(req->peerAddress));
	//TraceL << "Relay Data Received: " << peerAddress << ": " << req->peerAddress << endl;	
	//assert(req->peerAddress == peerAddress);
	
	_observer.onRelayDataReceived(*this, bufferCast<const char*>(buffer), buffer.size(), req->peerAddress);
}
Example #10
0
void ClientConnection::onPayload(const MutableBuffer& buffer)
{
    TraceS(this) << "On payload: " << buffer.size() << endl;

    // Update download progress
    IncomingProgress.update(buffer.size());

    if (Incoming.numAdapters() > 0 ||
        Incoming.emitter.ndelegates() > 0) {
        // if (!Incoming.active());
        //     throw std::runtime_error("startInputStream() must be called");
        Incoming.write(bufferCast<const char*>(buffer), buffer.size());
    }

    // if (_readStream) {
    //     TraceS(this) << "Writing to stream: " << buffer.size() << endl;
    //     _readStream->write(bufferCast<const char*>(buffer), buffer.size());
    //     _readStream->flush();
    // }

    Payload.emit(this, buffer);
}
Example #11
0
void Connection::onSocketRecv(const MutableBuffer& buffer, const net::Address& peerAddress)
{        
    TraceS(this) << "On socket recv" << endl;
    //_timeout.stop();
            
    if (Incoming.emitter.ndelegates()) {
        //RawPacket p(packet.data(), packet.size());
        //Incoming.write(p);
        Incoming.write(bufferCast<const char*>(buffer), buffer.size());
    }

    // Handle payload data
    onPayload(buffer); //mutableBuffer(bufferCast<const char*>(buf)
}
Example #12
0
void ClientConnection::onPayload(const MutableBuffer& buffer)
{
    // LTrace("On payload: ", buffer.size())

    //// Update download progress
    //IncomingProgress.update(buffer.size());

    //// Write to the incoming packet stream if adapters are attached
    //if (Incoming.numAdapters() > 0 || Incoming.emitter.nslots() > 0) {
    //    // if (!Incoming.active());
    //    //     throw std::runtime_error("startInputStream() must be called");
    //    Incoming.write(bufferCast<const char*>(buffer), buffer.size());
    //}

    // Write to the STL read stream if available
    if (_readStream) {
        // LTrace("Writing to stream: ", buffer.size())
        _readStream->write(bufferCast<const char*>(buffer), buffer.size());
        _readStream->flush();
    }

    Payload.emit(buffer);
}
Example #13
0
void TCPSocket::onRecv(const MutableBuffer& buf)
{
    TraceLS(this) << "Recv: " << buf.size() << endl;
    onSocketRecv(buf, peerAddress());
}
Example #14
0
void WebSocketAdapter::onSocketRecv(const MutableBuffer& buffer, const net::Address& peerAddress)
{
	TraceLS(this) << "On recv: " << buffer.size() << endl; // << ": " << buffer

	//assert(buffer.position() == 0);

	if (framer.handshakeComplete()) {

		// Note: The spec wants us to buffer partial frames, but our
		// software does not require this feature, and furthermore
		// it goes against our nocopy where possible policy. 
		// This may need to change in the future, but for now
		// we just parse and emit packets as they arrive.
		//
		// Incoming frames may be joined, so we parse them
		// in a loop until the read buffer is empty.
		BitReader reader(buffer);
		int total = reader.available();
		int offset = reader.position();
		while (offset < total) {
			char* payload = nullptr;
			UInt64 payloadLength = 0;
			try {
				// Restore buffer state for next read
				//reader.position(offset);
				//reader.limit(total);
					
#if 0
				TraceLS(this) << "Read frame at: " 
					 << "\n\tinputPosition: " << offset
					 << "\n\tinputLength: " << total
					 << "\n\tbufferPosition: " << reader.position() 
					 << "\n\tbufferAvailable: " << reader.available() 
					 << "\n\tbufferLimit: " << reader.limit() 
					 << "\n\tbuffer: " << std::string(reader.current(), reader.limit())
					 << endl;	
#endif
				
				// Parse a frame to throw
				//int payloadLength = framer.readFrame(reader);
				payloadLength = framer.readFrame(reader, payload);
				assert(payload);

				// Update the next frame offset
				offset = reader.position(); // + payloadLength; 
				if (offset < total)
					DebugLS(this) << "Splitting joined packet at "
						<< offset << " of " << total << endl;

				// Drop empty packets
				if (!payloadLength) {
					DebugLS(this) << "Dropping empty frame" << endl;
					continue;
				}
			} 
			catch (std::exception& exc) {
				WarnL << "Parser error: " << exc.what() << endl;		
				socket->setError(exc.what());	
				return;
			}
			
			// Emit the result packet
			assert(payload);
			assert(payloadLength);
			SocketAdapter::onSocketRecv(mutableBuffer(payload, (std::size_t)payloadLength), peerAddress);
		}
		assert(offset == total);
	}
	else {		
		try {
			if (framer.mode() == ws::ClientSide)
				handleClientResponse(buffer);
			else
				handleServerRequest(buffer);
		} 
		catch (std::exception& exc) {
			WarnL << "Read error: " << exc.what() << endl;		
			socket->setError(exc.what());	
		}
		return;
	}	
}
void UDPSocket::onRecv(const MutableBuffer& buf, const net::Address& address)
{
    TraceS(this) << "Recv: " << buf.size() << endl;    
    //emitRecv(buf, address);
    onSocketRecv(buf, address);
}