/// <summary> /// Cleans out any notifications older than the received carrier ack. /// </summary> internal void OnReceiveCarrier( long curTime, ushort notificationAck, Action <NetEvent> deallocate) { this.traffic.OnReceiveOther(curTime); while (this.outgoing.Count > 0) { NetEvent front = this.outgoing.Peek(); if (NetUtil.UShortSeqDiff(notificationAck, front.Sequence) < 0) { break; } deallocate.Invoke(this.outgoing.Dequeue()); } }
/// <summary> /// Reads a length-prefixed notification block. /// </summary> private static int ReadNotification(byte[] buffer, int length, int position, NetEvent destination) { // Read the length we added ushort dataLength = ReadU16(buffer, position); position += NOTIFICATION_HEADER_SIZE; // Avoid a crash if the packet is bad (or malicious) if ((position + dataLength) > length) { return(-1); } // Read the data into the event's buffer if (destination.ReadData(buffer, position, dataLength) == false) { return(-1); } return(NOTIFICATION_HEADER_SIZE + dataLength); }
/// <summary> /// Reads a collection of notifications packed in the buffer. /// </summary> internal static bool ReadCarrier( Func <NetEventType, NetPeer, NetEvent> eventFactory, NetPeer peer, byte[] buffer, int length, out ushort notificationAck, out ushort notificationSeq, Queue <NetEvent> destinationQueue) { // Read header (already know the type) notificationAck = NetEncoding.ReadU16(buffer, 1); notificationSeq = NetEncoding.ReadU16(buffer, 3); int position = NetEncoding.CARRIER_HEADER_SIZE; // Validate int maxDataPack = NetEncoding.MAX_NOTIFICATION_PACK; if ((position > length) || ((length - position) > maxDataPack)) { return(false); } // Read notifications while (position < length) { NetEvent evnt = eventFactory.Invoke(NetEventType.Notification, peer); int bytesRead = NetEncoding.ReadNotification(buffer, length, position, evnt); if (bytesRead < 0) { return(false); } destinationQueue.Enqueue(evnt); position += bytesRead; } return(true); }
/// <summary> /// Reads payload data from the given buffer. /// </summary> internal static bool ReadPayload( Func <NetEventType, NetPeer, NetEvent> eventFactory, NetPeer peer, byte[] buffer, int length, out ushort sequence, out NetEvent evnt) { evnt = null; // Read header (already know the type) sequence = NetEncoding.ReadU16(buffer, 1); int position = NetEncoding.PAYLOAD_HEADER_SIZE; ushort dataLength = (ushort)(length - position); if ((position + dataLength) > length) { return(false); // We're reading past the end of the packet data } evnt = eventFactory.Invoke(NetEventType.Payload, peer); return(evnt.ReadData(buffer, position, dataLength));; }
/// <summary> /// Returns the first event on the background thread's outgoing queue. /// </summary> internal bool TryReceiveEvent(out NetEvent received) { return(eventOut.TryDequeue(out received)); }
/// <summary> /// Deallocates a pool-spawned event. /// </summary> internal void RecycleEvent(NetEvent evnt) { eventPool.Deallocate(evnt); }