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); } }
public void SendPacket(SimPacket packet) { var source = packet.Source.Machine; var destination = packet.Destination.Machine; var routeId = new RouteId(GetNetwork(source), GetNetwork(destination)); Routes[routeId].Send(packet); }
void Debug(LogType type, SimPacket msg, string l, bool force = false) { if (force || _def.Debug(msg)) { var route = $"{msg.Source}->{msg.Destination}"; _network.Debug(type, $" {route,-34} {l}"); } }
public bool TryDeliver(SimPacket msg) { if (_sockets.TryGetValue(msg.Destination.Port, out var socket)) { socket.Deliver(msg); return(true); } return(false); }
public async Task Write(object message, SimFlag flag = SimFlag.None) { if (_closed) { throw new IOException("Socket closed"); } var packet = new SimPacket(_socket.Endpoint, RemoteAddress, message, _sequenceNumber, _ackNumber, flag); _socket.SendMessage(packet); _sequenceNumber++; }
void HandOut(SimPacket msg) { _ackNumber = msg.NextSeqNumber; if (_pendingRead != null) { _pendingRead.SetResult(msg); _pendingRead = null; } else { _readBuffer.Enqueue(msg); } }
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()}"); }
public void InternalDeliver(SimPacket msg) { if (ResolveHost(msg.Destination.Machine, out var machine)) { if (machine.TryDeliver(msg)) { return; } } var back = new SimPacket(msg.Destination, msg.Source, new IOException("Connection refused"), msg.AckNumber, msg.NextSeqNumber, SimFlag.Reset ); SendPacket(back); }
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 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 SendMessage(SimPacket message) { _net.SendPacket(message); }