public Task Send(SimPacket msg) { if (_def.PacketLoss != null && _def.PacketLoss(_network.Rand)) { Debug(LogType.Fault, msg, $"LOST {msg.BodyString()}", _def.LogFaults); // we just lost a packet. return(Task.FromResult(true)); } Debug(LogType.Info, msg, $"Send {msg.BodyString()}"); // TODO: network cancellation _factory.StartNew(async() => { // delivery wait try { var latency = _def.Latency(_network.Rand); await SimDelayTask.Delay(latency); _network.InternalDeliver(msg); } catch (Exception ex) { Debug(LogType.Error, msg, $"FATAL: {ex}"); } }); return(Task.FromResult(true)); }
public void Deliver(SimPacket msg) { if (_connections.TryGetValue(msg.Source, out var conn)) { conn.Deliver(msg); return; } if (msg.Flag == SimFlag.Syn) { AcceptNewConnection(msg); return; } Debug($"Drop non SYN: {msg.BodyString()}"); }
void AcceptNewConnection(SimPacket msg) { var conn = new SimConn(this, msg.Source, _proc, 0, msg.NextSeqNumber); _connections.Add(msg.Source, conn); _proc.Schedule(async() => { await conn.Write(null, SimFlag.Ack | SimFlag.Syn); var resp = await conn.Read(5.Sec()); if (resp.Flag != SimFlag.Ack) { Debug($"Non ACK packet: {msg.BodyString()}"); await conn.Write(null, SimFlag.Reset); _connections.Remove(msg.Source); return; } AddEstablishedConnection(conn); }); }
public void Deliver(SimPacket msg) { if (msg.SeqNumber != _ackNumber) { //_socket.Debug($"Out-of-order packet {msg.BodyString()} from {msg.Source} with Seq {msg.SeqNumber}. Ours {_ackNumber}"); if (_outOfOrder.ContainsKey(msg.SeqNumber)) { _proc.Machine.Runtime.Halt($"Duplicate packet for {RemoteAddress}->{_socket.Endpoint}", new ArgumentException($"{_ackNumber} has '{_outOfOrder[msg.SeqNumber].BodyString()}' trying to put {msg.SeqNumber} '{msg.BodyString()}'")); return; } _outOfOrder.Add(msg.SeqNumber, msg); return; } HandOut(msg); // try to deliver out-of-order packets // maybe this packet unblocks them while (_outOfOrder.TryGetValue(_ackNumber, out var value)) { HandOut(value); _outOfOrder.Remove(_ackNumber); } }