static private void ReceiveThread(object Param) { Logger.WriteLine($"Receive thread started with id {Task.CurrentId}"); SharedObject data = (SharedObject)Param; while (!data.Ended) { data.Socket.ReceiveTimeout = (int)PacketsProps.WAIT_TIME; try { CommunicationPacket p = CommunicationFacade.Receive(data.Socket); UInt64 currentPoint; lock (data.CountersLocker) currentPoint = data.Confirmed; UInt64 confirmationNumber = CommunicationFacade.ComputeRealNumber(p.ConfirmationNumber, currentPoint, UInt16.MaxValue, (uint)Sizes.WINDOW_SIZE); UploadRecvPacket recv = new UploadRecvPacket(p.ConnectionNumber, p.Flags, p.Data, confirmationNumber); lock (data.ArriveQueue) data.ArriveQueue.Enqueue(recv); } catch (SocketException e) when(e.SocketErrorCode == SocketError.TimedOut) { } } }
static private UploadRecvPacket Validate(UploadRecvPacket p, UInt32 connectionNumber, UInt64 required) { if (p.ConnectionNumber != connectionNumber) { throw new InvalidPacketException($"Connection number not match, required: {connectionNumber:X} accepted: {p.ConnectionNumber:X}"); } if (p.Flags > 0 && p.Flags != (byte)Flag.FIN && p.Flags != (byte)Flag.SYN && p.Flags != (byte)Flag.RST) { throw new InvalidPacketException($"Invalid packet, obtained {Convert.ToString(p.Flags, 2)}"); } if (p.Flags == (byte)Flag.RST) { throw new CommunicationException(); } UInt64 i = 0; UInt64 max = (UInt64)Sizes.WINDOW_PACKETS * 4; for (i = 0; i < max; i++) { if (p.ConfirmationNumber + i * (UInt64)Sizes.MAX_DATA == required || p.ConfirmationNumber + i * (UInt64)Sizes.MAX_DATA == required + (UInt64)Sizes.WINDOW_SIZE) { break; } } if (i == max) { throw new InvalidPacketNumberException($"Invalid packet serial, min required: {required}, obtained: {p.ConfirmationNumber}"); } if (p.Flags == (byte)Flag.FIN && p.Data.Length > 0) { throw new InvalidPacketException("Packet with FIN contains data"); } return(p); }