Exemple #1
0
        /// <summary>
        /// Sends ERROR_PROTOCOL_VIOLATION to client with message ID set to 0x0BADC0DE.
        /// </summary>
        /// <param name="Client">Client to send the error to.</param>
        public async Task SendProtocolViolation(TcpClient Client)
        {
            MessageBuilderLocNet mb = new MessageBuilderLocNet(0, new List <SemVer>()
            {
                SemVer.V100
            });
            Message response = mb.CreateErrorProtocolViolationResponse(new Message()
            {
                Id = 0x0BADC0DE
            });

            await SendMessageAsync(Client, response);
        }
Exemple #2
0
        /// <summary>
        /// Processes DeregisterServiceRequest message from client.
        /// <para>Removes information about the profile server's NodeProfile.</para>
        /// </summary>
        /// <param name="Client">TCP client that sent the request.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        /// <param name="RequestMessage">Full request message.</param>
        /// <returns>Response message to be sent to the client.</returns>
        public Message ProcessMessageDeregisterServiceRequest(TcpClient Client, MessageBuilderLocNet MessageBuilder, Message RequestMessage)
        {
            log.Trace("()");

            Message res = MessageBuilder.CreateDeregisterServiceResponse(RequestMessage);

            DeregisterServiceRequest deregisterServiceRequest = RequestMessage.Request.LocalService.DeregisterService;

            profileServerPort = 0;

            log.Trace("(-):*.Response.Status={0}", res.Response.Status);
            return(res);
        }
Exemple #3
0
        /// <summary>
        /// Reads messages from the client stream and processes them in a loop until the client disconnects
        /// or until an action (such as a protocol violation) that leads to disconnecting of the client occurs.
        /// </summary>
        /// <param name="Client">TCP client.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        public async Task ReceiveMessageLoop(TcpClient Client, MessageBuilderLocNet MessageBuilder)
        {
            log.Trace("()");

            try
            {
                NetworkStream    stream        = Client.GetStream();
                RawMessageReader messageReader = new RawMessageReader(stream);
                while (!isShutdown)
                {
                    RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(shutdownCancellationTokenSource.Token);

                    bool disconnect        = rawMessage.Data == null;
                    bool protocolViolation = rawMessage.ProtocolViolation;
                    if (rawMessage.Data != null)
                    {
                        Message message = CreateMessageFromRawData(rawMessage.Data);
                        if (message != null)
                        {
                            disconnect = !await ProcessMessageAsync(Client, MessageBuilder, message);
                        }
                        else
                        {
                            protocolViolation = true;
                        }
                    }

                    if (protocolViolation)
                    {
                        await SendProtocolViolation(Client);

                        break;
                    }

                    if (disconnect)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            log.Trace("(-)");
        }
Exemple #4
0
        /// <summary>
        /// Handler for each client that connects to the TCP server.
        /// </summary>
        /// <param name="Client">Client that is connected to TCP server.</param>
        private async void ClientHandlerAsync(TcpClient Client)
        {
            log.Debug("(Client.Client.RemoteEndPoint:{0})", Client.Client.RemoteEndPoint);

            connectedProfileServer = Client;
            connectedProfileServerMessageBuilder = new MessageBuilderLocNet(0, new List <SemVer>()
            {
                SemVer.V100
            });

            await ReceiveMessageLoop(Client, connectedProfileServerMessageBuilder);

            connectedProfileServerWantsUpdates = false;
            connectedProfileServer             = null;
            Client.Dispose();

            log.Debug("(-)");
        }
Exemple #5
0
        /// <summary>
        /// Processes RegisterServiceRequest message from client.
        /// <para>Obtains information about the profile server's NodeProfile.</para>
        /// </summary>
        /// <param name="Client">TCP client that sent the request.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        /// <param name="RequestMessage">Full request message.</param>
        /// <returns>Response message to be sent to the client.</returns>
        public Message ProcessMessageRegisterServiceRequest(TcpClient Client, MessageBuilderLocNet MessageBuilder, Message RequestMessage)
        {
            log.Trace("()");

            Message res = MessageBuilder.CreateRegisterServiceResponse(RequestMessage);

            RegisterServiceRequest registerServiceRequest = RequestMessage.Request.LocalService.RegisterService;

            byte[] serverId = registerServiceRequest.Service.ServiceData.ToByteArray();
            if ((registerServiceRequest.Service.Type == ServiceType.Profile) && (serverId.Length == 32))
            {
                profileServer.SetNetworkId(serverId);
            }
            else
            {
                log.Error("Received register service request is invalid.");
            }

            log.Trace("(-):*.Response.Status={0}", res.Response.Status);
            return(res);
        }
Exemple #6
0
        /// <summary>
        /// Processes GetNeighbourNodesByDistanceLocalRequest message from client.
        /// <para>Obtains information about the profile server's neighborhood and initiates sending updates to it.</para>
        /// </summary>
        /// <param name="Client">TCP client that sent the request.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        /// <param name="RequestMessage">Full request message.</param>
        /// <param name="KeepAlive">This is set to true if KeepAliveAndSendUpdates in the request was set.</param>
        /// <returns>Response message to be sent to the client.</returns>
        public Message ProcessMessageGetNeighbourNodesByDistanceLocalRequest(TcpClient Client, MessageBuilderLocNet MessageBuilder, Message RequestMessage, out bool KeepAlive)
        {
            log.Trace("()");

            Message res = null;

            GetNeighbourNodesByDistanceLocalRequest getNeighbourNodesByDistanceLocalRequest = RequestMessage.Request.LocalService.GetNeighbourNodes;

            KeepAlive = getNeighbourNodesByDistanceLocalRequest.KeepAliveAndSendUpdates;

            List <NodeInfo> neighborList;

            lock (neighborsLock)
            {
                neighborList = new List <NodeInfo>(neighbors);
            }

            res = MessageBuilder.CreateGetNeighbourNodesByDistanceLocalResponse(RequestMessage, neighborList);

            log.Trace("(-):*.Response.Status={0}", res.Response.Status);
            return(res);
        }
Exemple #7
0
        /// <summary>
        /// Processing of a message received from a client.
        /// </summary>
        /// <param name="Client">TCP client.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        /// <param name="IncomingMessage">Full ProtoBuf message to be processed.</param>
        /// <returns>true if the conversation with the client should continue, false if a protocol violation error occurred and the client should be disconnected.</returns>
        public async Task <bool> ProcessMessageAsync(TcpClient Client, MessageBuilderLocNet MessageBuilder, Message IncomingMessage)
        {
            bool res = false;

            log.Debug("()");
            try
            {
                log.Trace("Received message type is {0}, message ID is {1}.", IncomingMessage.MessageTypeCase, IncomingMessage.Id);
                switch (IncomingMessage.MessageTypeCase)
                {
                case Message.MessageTypeOneofCase.Request:
                {
                    Message responseMessage = MessageBuilder.CreateErrorProtocolViolationResponse(IncomingMessage);
                    Request request         = IncomingMessage.Request;

                    bool setKeepAlive = false;

                    SemVer version = new SemVer(request.Version);
                    log.Trace("Request type is {0}, version is {1}.", request.RequestTypeCase, version);
                    switch (request.RequestTypeCase)
                    {
                    case Request.RequestTypeOneofCase.LocalService:
                    {
                        log.Trace("Local service request type is {0}.", request.LocalService.LocalServiceRequestTypeCase);
                        switch (request.LocalService.LocalServiceRequestTypeCase)
                        {
                        case LocalServiceRequest.LocalServiceRequestTypeOneofCase.RegisterService:
                            responseMessage = ProcessMessageRegisterServiceRequest(Client, MessageBuilder, IncomingMessage);
                            break;

                        case LocalServiceRequest.LocalServiceRequestTypeOneofCase.DeregisterService:
                            responseMessage = ProcessMessageDeregisterServiceRequest(Client, MessageBuilder, IncomingMessage);
                            break;

                        case LocalServiceRequest.LocalServiceRequestTypeOneofCase.GetNeighbourNodes:
                            responseMessage = ProcessMessageGetNeighbourNodesByDistanceLocalRequest(Client, MessageBuilder, IncomingMessage, out setKeepAlive);
                            break;

                        default:
                            log.Error("Invalid local service request type '{0}'.", request.LocalService.LocalServiceRequestTypeCase);
                            break;
                        }
                        break;
                    }

                    default:
                        log.Error("Invalid request type '{0}'.", request.RequestTypeCase);
                        break;
                    }


                    if (responseMessage != null)
                    {
                        // Send response to client.
                        res = await SendMessageAsync(Client, responseMessage);

                        if (setKeepAlive)
                        {
                            connectedProfileServerWantsUpdates = true;
                            log.Debug("Profile server is now connected to its LOC server and waiting for updates.");
                        }
                    }
                    else
                    {
                        // If there is no response to send immediately to the client,
                        // we want to keep the connection open.
                        res = true;
                    }
                    break;
                }

                case Message.MessageTypeOneofCase.Response:
                {
                    Response response = IncomingMessage.Response;
                    log.Trace("Response status is {0}, details are '{1}', response type is {2}.", response.Status, response.Details, response.ResponseTypeCase);

                    switch (response.ResponseTypeCase)
                    {
                    case Response.ResponseTypeOneofCase.LocalService:
                    {
                        log.Trace("Local service response type is {0}.", response.LocalService.LocalServiceResponseTypeCase);
                        switch (response.LocalService.LocalServiceResponseTypeCase)
                        {
                        case LocalServiceResponse.LocalServiceResponseTypeOneofCase.NeighbourhoodUpdated:
                            // Nothing to be done here.
                            res = true;
                            break;

                        default:
                            log.Error("Invalid local service response type '{0}'.", response.LocalService.LocalServiceResponseTypeCase);
                            break;
                        }

                        break;
                    }

                    default:
                        log.Error("Unknown response type '{0}'.", response.ResponseTypeCase);
                        // Connection will be closed in ReceiveMessageLoop.
                        break;
                    }

                    break;
                }

                default:
                    log.Error("Unknown message type '{0}', connection to the client will be closed.", IncomingMessage.MessageTypeCase);
                    await SendProtocolViolation(Client);

                    // Connection will be closed in ReceiveMessageLoop.
                    break;
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred, connection to the client will be closed: {0}", e.ToString());
                await SendProtocolViolation(Client);

                // Connection will be closed in ReceiveMessageLoop.
            }

            log.Debug("(-):{0}", res);
            return(res);
        }