OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
/// <summary>
/// Actually send a packet to a client.
/// </summary>
/// <param name="outgoingPacket"></param>
Actually send a packet to a client.
Actually send a packet to a client .
internal void SendPacketFinal(OutgoingPacket outgoingPacket)
        {
            UDPPacketBuffer buffer = outgoingPacket.Buffer;
            byte flags = buffer.Data[0];
            bool isResend = (flags & Helpers.MSG_RESENT) != 0;
            bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
            bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
            LLUDPClient udpClient = outgoingPacket.Client;
            if (!udpClient.IsConnected)
                return;
            #region ACK Appending
            int dataLength = buffer.DataLength;
            if (!isZerocoded)
            {
                uint ackCount = 0;
                uint ack;
                while (dataLength + 5 < buffer.Data.Length && udpClient.PendingAcks.Dequeue(out ack))
                {
                    Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
                    dataLength += 4;
                    ++ackCount;
                }
                if (ackCount > 0)
                {
                    buffer.Data[dataLength++] = (byte)ackCount;
                    buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
                }
            }
            buffer.DataLength = dataLength;
            #endregion ACK Appending
            #region Sequence Number Assignment
            if (!isResend)
            {
                uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence);
                Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
                outgoingPacket.SequenceNumber = sequenceNumber;
                if (udpClient.ProcessUnackedSends && isReliable)
                {
                    udpClient.NeedAcks.Add(outgoingPacket);
                }
            }
            else
            {
                Interlocked.Increment(ref udpClient.PacketsResent);
                PacketsResentCount++;
            }
            #endregion Sequence Number Assignment
            Interlocked.Increment(ref udpClient.PacketsSent);
            PacketsSentCount++;
            if (udpClient.DebugDataOutLevel > 0)
                m_log.DebugFormat(
                    "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
                    outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name);
            AsyncBeginSend(buffer);
            outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
        }
internal void SendPacketFinal ( OutgoingPacket outgoingPacket ) { UDPPacketBuffer buffer = outgoingPacket . Buffer ; byte flags = buffer . Data [ 0 ] ; bool isResend = ( flags & Helpers . MSG_RESENT ) != 0 ; bool isReliable = ( flags & Helpers . MSG_RELIABLE ) != 0 ; bool isZerocoded = ( flags & Helpers . MSG_ZEROCODED ) != 0 ; LLUDPClient udpClient = outgoingPacket . Client ; if ( ! udpClient . IsConnected ) return ; region  ACK Appending int dataLength = buffer . DataLength ; if ( ! isZerocoded ) { uint ackCount = 0 ; uint ack ; while ( dataLength + 5 < buffer . Data . Length && udpClient . PendingAcks . Dequeue ( out ack ) ) { Utils . UIntToBytesBig ( ack , buffer . Data , dataLength ) ; dataLength += 4 ; ++ ackCount ; } if ( ackCount > 0 ) { buffer . Data [ dataLength ++ ] = ( byte ) ackCount ; buffer . Data [ 0 ] = ( byte ) ( buffer . Data [ 0 ] | Helpers . MSG_APPENDED_ACKS ) ; } } buffer . DataLength = dataLength ; endregion  ACK Appending region  Sequence Number Assignment if ( ! isResend ) { uint sequenceNumber = ( uint ) Interlocked . Increment ( ref udpClient . CurrentSequence ) ; Utils . UIntToBytesBig ( sequenceNumber , buffer . Data , 1 ) ; outgoingPacket . SequenceNumber = sequenceNumber ; if ( udpClient . ProcessUnackedSends && isReliable ) { udpClient . NeedAcks . Add ( outgoingPacket ) ; } } else { Interlocked . Increment ( ref udpClient . PacketsResent ) ; PacketsResentCount ++ ; } endregion  Sequence Number Assignment Interlocked . Increment ( ref udpClient . PacketsSent ) ; PacketsSentCount ++ ; if ( udpClient . DebugDataOutLevel > 0 ) m_log . DebugFormat ( " " , outgoingPacket . SequenceNumber , isReliable , isResend , udpClient . AgentID , Scene . Name ) ; AsyncBeginSend ( buffer ) ; outgoingPacket . TickCount = Environment . TickCount & Int32 . MaxValue ; }
Actually send a packet to a client.
Actually send a packet to a client .
// NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here // Keep appending ACKs until there is no room left in the buffer or there are // no more ACKs to append // Set the last byte of the packet equal to the number of appended ACKs // Set the appended ACKs flag on this packet // Not a resend, assign a new sequence number // Add this packet to the list of ACK responses we are waiting on from the server // We're not going to worry about interlock yet since its not currently critical that this total count // is 100% correct // Stats tracking // We're not going to worry about interlock yet since its not currently critical that this total count // is 100% correct // Put the UDP payload on the wire // Keep track of when this packet was sent out (right now)
outgoingPacket
OutgoingPacket
None