OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
/// <summary>
/// Start the process of sending a packet to the client.
/// </summary>
/// <param name="udpClient"></param>
/// <param name="data"></param>
/// <param name="type"></param>
/// <param name="category"></param>
/// <param name="method">
/// The method to call if the packet is not acked by the client.  If null, then a standard
/// resend of the packet is done.
/// </param>
/// <returns>true if the data was sent immediately, false if it was queued for sending</returns>
Start the process of sending a packet to the client.
Start the process of sending a packet to the client .
public bool SendPacketData(
            LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category, UnackedPacketMethod method)
        {
            int dataLength = data.Length;
            bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
            bool doCopy = true;
            int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
            UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
            if (doZerocode)
            {
                try
                {
                    dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data);
                    doCopy = false;
                }
                catch (IndexOutOfRangeException)
                {
                    m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
                        " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
                    data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
                }
            }
            if (doCopy)
            {
                if (dataLength <= buffer.Data.Length)
                {
                    Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
                }
                else
                {
                    bufferSize = dataLength;
                    buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
                    Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
                }
            }
            buffer.DataLength = dataLength;
            #region Queue or Send
            OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
            if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
                outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
            bool forceQueue = (type == PacketType.KillObject);
            if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
            {
                SendPacketFinal(outgoingPacket);
                return true;
            }
            else
            {
                return false;
            }
            #endregion Queue or Send
        }
public bool SendPacketData ( LLUDPClient udpClient , byte [ ] data , PacketType type , ThrottleOutPacketType category , UnackedPacketMethod method ) { int dataLength = data . Length ; bool doZerocode = ( data [ 0 ] & Helpers . MSG_ZEROCODED ) != 0 ; bool doCopy = true ; int bufferSize = ( dataLength > 180 ) ? LLUDPServer . MTU : 200 ; UDPPacketBuffer buffer = new UDPPacketBuffer ( udpClient . RemoteEndPoint , bufferSize ) ; if ( doZerocode ) { try { dataLength = Helpers . ZeroEncode ( data , dataLength , buffer . Data ) ; doCopy = false ; } catch ( IndexOutOfRangeException ) { m_log . Debug ( " " + type + " " + dataLength + " " + buffer . Data . Length + " " ) ; data [ 0 ] = ( byte ) ( data [ 0 ] & ~ Helpers . MSG_ZEROCODED ) ; } } if ( doCopy ) { if ( dataLength <= buffer . Data . Length ) { Buffer . BlockCopy ( data , 0 , buffer . Data , 0 , dataLength ) ; } else { bufferSize = dataLength ; buffer = new UDPPacketBuffer ( udpClient . RemoteEndPoint , bufferSize ) ; Buffer . BlockCopy ( data , 0 , buffer . Data , 0 , dataLength ) ; } } buffer . DataLength = dataLength ; region  Queue or Send OutgoingPacket outgoingPacket = new OutgoingPacket ( udpClient , buffer , category , null ) ; if ( ( outgoingPacket . Buffer . Data [ 0 ] & Helpers . MSG_RELIABLE ) != 0 ) outgoingPacket . UnackedMethod = ( ( method == null ) ? delegate ( OutgoingPacket oPacket ) { ResendUnacked ( oPacket ) ; } : method ) ; bool forceQueue = ( type == PacketType . KillObject ) ; if ( ! outgoingPacket . Client . EnqueueOutgoing ( outgoingPacket , forceQueue ) ) { SendPacketFinal ( outgoingPacket ) ; return true ; } else { return false ; } endregion  Queue or Send }
Start the process of sending a packet to the client.
Start the process of sending a packet to the client .
// Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here // to accomodate for both common scenarios and provide ample room for ACK appending in both // Zerocode if needed // The packet grew larger than the bufferSize while zerocoding. // Remove the MSG_ZEROCODED flag and send the unencoded data // instead // If the packet data wasn't already copied during zerocoding, copy it now // m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + //     type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); // If we were not provided a method for handling unacked, use the UDPServer default method // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will  // continue to display the deleted object until relog.  Therefore, we need to always queue a kill object // packet so that it isn't sent before a queued update packet. //            if (type == PacketType.ImprovedTerseObjectUpdate) //            { //                m_log.DebugFormat("Direct send ITOU to {0} in {1}", udpClient.AgentID, Scene.Name); //                SendPacketFinal(outgoingPacket); //                return false; //            } //            else //            { //            }
true if the data was sent immediately, false if it was queued for sending
true if the data was sent immediately false if it was queued for sending
udpClient
LLUDPClient
None
data
byte[]
None
type
PacketType
None
category
ThrottleOutPacketType
None
method
UnackedPacketMethod
The method to call if the packet is not acked by the client.  If null, then a standard
resend of the packet is done.
The method to call if the packet is not acked by the client . If null then a standard resend of the packet is done .