コード例 #1
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::sendCumAck()
{
	UdpHeader header;

	header.control  = 0;
	header.length 	= sizeof( header );
	header.srcId  	= m_connection->GetSelfTag();
	header.dstId  	= m_connection->GetRemoteTag();
	header.seq 		= 0;
	header.ack 		= m_sendCumAck;

	header.Set( UdpHeader::ACK );

	m_connection->SendRaw( (void*)&header, sizeof( header ) );
}
コード例 #2
0
ファイル: udp6.cpp プロジェクト: lanyuwen/openthread
otError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
{
    otError error = OT_ERROR_NONE;
    MessageInfo messageInfoLocal;
    UdpHeader udpHeader;

    messageInfoLocal = aMessageInfo;

    if (messageInfoLocal.GetSockAddr().IsUnspecified())
    {
        messageInfoLocal.SetSockAddr(GetSockName().GetAddress());
    }

    if (GetSockName().mPort == 0)
    {
        GetSockName().mPort = static_cast<Udp *>(mTransport)->GetEphemeralPort();
    }

    if (messageInfoLocal.GetPeerAddr().IsUnspecified())
    {
        VerifyOrExit(!GetPeerName().GetAddress().IsUnspecified(), error = OT_ERROR_INVALID_ARGS);

        messageInfoLocal.SetPeerAddr(GetPeerName().GetAddress());
    }

    if (messageInfoLocal.mPeerPort == 0)
    {
        VerifyOrExit(GetPeerName().mPort != 0, error = OT_ERROR_INVALID_ARGS);
        messageInfoLocal.mPeerPort = GetPeerName().mPort;
    }

    udpHeader.SetSourcePort(GetSockName().mPort);
    udpHeader.SetDestinationPort(messageInfoLocal.mPeerPort);
    udpHeader.SetLength(sizeof(udpHeader) + aMessage.GetLength());
    udpHeader.SetChecksum(0);

    SuccessOrExit(error = aMessage.Prepend(&udpHeader, sizeof(udpHeader)));
    aMessage.SetOffset(0);
    SuccessOrExit(error = static_cast<Udp *>(mTransport)->SendDatagram(aMessage, messageInfoLocal, kProtoUdp));

exit:
    return error;
}
コード例 #3
0
bool Filter::Accept(Message &aMessage) const
{
    bool rval = false;
    Header ip6;
    UdpHeader udp;
    TcpHeader tcp;
    uint16_t dstport;

    // Allow all received IPv6 datagrams with link security enabled
    if (aMessage.IsLinkSecurityEnabled())
    {
        ExitNow(rval = true);
    }

    // Read IPv6 header
    VerifyOrExit(sizeof(ip6) == aMessage.Read(0, sizeof(ip6), &ip6));

    // Allow only link-local unicast or multicast
    VerifyOrExit(ip6.GetDestination().IsLinkLocal() || ip6.GetDestination().IsLinkLocalMulticast());

    switch (ip6.GetNextHeader())
    {
    case kProtoUdp:
        // Read the UDP header and get the dst port
        VerifyOrExit(sizeof(udp) == aMessage.Read(sizeof(ip6), sizeof(udp), &udp));

        dstport = udp.GetDestinationPort();

        // Allow MLE traffic
        if (dstport == Mle::kUdpPort)
        {
            ExitNow(rval = true);
        }

        break;

    case kProtoTcp:
        // Read the TCP header and get the dst port
        VerifyOrExit(sizeof(tcp) == aMessage.Read(sizeof(ip6), sizeof(tcp), &tcp));

        dstport = tcp.GetDestinationPort();

        break;

    default:
        // Allow UDP or TCP traffic only
        ExitNow();
    }

    // Check against allowed unsecure port list
    for (int i = 0; i < kMaxUnsecurePorts; i++)
    {
        if (mUnsecurePorts[i] != 0 && mUnsecurePorts[i] == dstport)
        {
            ExitNow(rval = true);
        }
    }

exit:
    return rval;
}
コード例 #4
0
ファイル: udp6.cpp プロジェクト: lanyuwen/openthread
otError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
{
    otError error = OT_ERROR_NONE;
    UdpHeader udpHeader;
    uint16_t payloadLength;
    uint16_t checksum;

    payloadLength = aMessage.GetLength() - aMessage.GetOffset();

    // check length
    VerifyOrExit(payloadLength >= sizeof(UdpHeader), error = OT_ERROR_PARSE);

    // verify checksum
    checksum = Ip6::ComputePseudoheaderChecksum(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(),
                                                payloadLength, kProtoUdp);
    checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength);

#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    VerifyOrExit(checksum == 0xffff, error = OT_ERROR_DROP);
#endif

    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(udpHeader), &udpHeader) == sizeof(udpHeader),
                 error = OT_ERROR_PARSE);
    aMessage.MoveOffset(sizeof(udpHeader));
    aMessageInfo.mPeerPort = udpHeader.GetSourcePort();
    aMessageInfo.mSockPort = udpHeader.GetDestinationPort();

    // find socket
    for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext())
    {
        if (socket->GetSockName().mPort != udpHeader.GetDestinationPort())
        {
            continue;
        }

        if (socket->GetSockName().mScopeId != 0 &&
            socket->GetSockName().mScopeId != aMessageInfo.mInterfaceId)
        {
            continue;
        }

        if (!aMessageInfo.GetSockAddr().IsMulticast() &&
            !socket->GetSockName().GetAddress().IsUnspecified() &&
            socket->GetSockName().GetAddress() != aMessageInfo.GetSockAddr())
        {
            continue;
        }

        // verify source if connected socket
        if (socket->GetPeerName().mPort != 0)
        {
            if (socket->GetPeerName().mPort != udpHeader.GetSourcePort())
            {
                continue;
            }

            if (!socket->GetPeerName().GetAddress().IsUnspecified() &&
                socket->GetPeerName().GetAddress() != aMessageInfo.GetPeerAddr())
            {
                continue;
            }
        }

        socket->HandleUdpReceive(aMessage, aMessageInfo);
    }

exit:
    return error;
}
コード例 #5
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::OnRecv( const UdpHeader& header, void* data, uint len )
{
	K_ASSERT( data != 0 );
	K_ASSERT( len > 0 );
	K_ASSERT( header.length < len );
	K_ASSERT( header.IsSet( UdpHeader::RLE) );

	if ( header.seq <= m_sendCumAck )
	{
		LOG( FT_DEBUG, 
			 _T("Reliable::OnRecv> self[%d] remote[%d] dup %d checked by m_sendCumAck %d"), 
			 m_connection->GetSelfTag(), 
			 m_connection->GetRemoteTag(),
			 header.seq, 
			 m_sendCumAck );

		return; 
	}

	byte* p	   = (byte*)data;
	byte* head = (byte*)(p + header.length);

	// save payload only
	data = (void*)head;
	len = len - header.length;

	LOG( FT_DEBUG, _T("Reliable::OnRecv> self[%d] remote[%d] seq %d"), 
		 m_connection->GetSelfTag(), 
		 m_connection->GetRemoteTag(),
		 header.seq );

	// if in sequence
	if ( header.seq == m_sendCumAck + 1 )
	{
		LOG( FT_DEBUG, _T("Reliable::OnRecv> In order %d"), header.seq );

		m_communicator->OnRecv( m_connection->GetRemoteTag(), data, len );

		++m_sendCumAck;

		clearIfExists( m_sendCumAck );

		K_ASSERT( header.seq == m_sendCumAck );

		m_cumAckInterval = CUMULATIVE_ACK_INTERVAL;
	}
	else
	{
		LOG( FT_DEBUG, _T("Reliable::OnRecv>  Out of order %d"), header.seq );

		if ( isDuplicateRecv( header.seq ) )
		{
			LOG( FT_DEBUG, _T("Reliable::OnRecv> Dup %d check by search"), header.seq );

			return;
		}

		UdpRecvBlock* rv 	= allocRecvBlock();
		rv->ordered 	= false;
		rv->seq 	 	= header.seq;
		rv->ackCount 	= 0;

		if ( header.IsSet( UdpHeader::ORD ) )
		{
			rv->ordered = true;
			rv->data 	= allocData( len );
			rv->len  	= len;

			::memcpy( rv->data, data, len );
		}
		else
		{
			m_communicator->OnRecv( m_connection->GetRemoteTag(), data, len );
		}

		K_ASSERT( rv->seq > m_sendCumAck );

		insertRecvBlock( rv );
		runRecvBlockList();

		// only 1 eak is used.
		// send immediately when not in order
		sendEak( header.seq );

		m_tickCumulativeAck.Reset();
	}
}