예제 #1
0
        public async Task <IConn> Connect(SimProc process, SimEndpoint destination)
        {
            SimRoute route;

            if (!Cluster.TryGetRoute(Name, destination.Machine, out route))
            {
                throw new IOException($"Route not found");
            }


            // todo: allocate port
            // todo: allow Azure SNAT delay scenario
            var socketId     = NextSocketID();
            var source       = new SimEndpoint(Name, socketId);
            var clientSocket = new SimSocket(process, source, Cluster);

            try {
                _sockets.Add(socketId, clientSocket);


                var conn = new SimConn(clientSocket, destination, process, 0, 0);

                clientSocket._connections.Add(destination, conn);


                // handshake
                await conn.Write(null, SimFlag.Syn);

                var response = await conn.Read(5.Sec());

                if (response.Flag != (SimFlag.Ack | SimFlag.Syn))
                {
                    Debug(LogType.Warning, $"Bad handshake: {response.BodyString()}");
                    await conn.Write(null, SimFlag.Reset);

                    clientSocket._connections.Remove(destination);
                    throw new IOException($"Failed to connect (got {response.BodyString()})");
                }

                await conn.Write(null, SimFlag.Ack);

                return(new ClientConn(conn));
            } catch (IOException) {
                throw;
            }
            catch (Exception ex) {
                _sockets.Remove(socketId);
                clientSocket.Dispose();
                throw new IOException($"Failed to connect: {ex.Message}", ex);
            }
        }
예제 #2
0
        void AddEstablishedConnection(SimConn conn)
        {
            var ready = new ClientConn(conn);

            if (_poll != null)
            {
                _poll.SetResult(ready);
                _poll = null;
            }
            else
            {
                _incoming.Enqueue(ready);
            }
        }
예제 #3
0
        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);
            });
        }
예제 #4
0
 public ClientConn(SimConn conn)
 {
     _conn = conn;
 }