/// <summary>
 /// Called by a session to remove itself when it's no longer needed
 /// </summary>
 /// <param name="tftpSession">The session to remove</param>
 internal void UnregisterSession(TftpSession tftpSession)
 {
     if (!Sessions.TryRemove(tftpSession.RemoteHost, out TftpSession removedSession))
     {
         throw new Exception("Could not remove session " + tftpSession.RemoteHost.ToString() + " from known sessions");
     }
 }
Example #2
0
        /// <summary>
        /// Handle the incoming UDP packet
        /// </summary>
        public void OnUdpData(IPEndPoint source, byte[] messageData)
        {
            try
            {
                if (!Sessions.TryGetValue(source, out TftpSession session))
                {
                    LogDebug($"New client detected from {source.Address}:{source.Port}");
                    session          = new TftpSession(this, source);
                    Sessions[source] = session;
                }

                Task.Factory.StartNew(
                    async() => {
                    try
                    {
                        await session.OnReceiveAsync(messageData);
                    }
                    catch (Exception e)
                    {
                        LogError("Internal error: " + e.Message);
                    }
                }
                    );
            }
            catch (Exception e)
            {
                LogError("Internal error: " + e.Message);
            }
        }
        private void EmitSessionError(TftpSession session, string reason)
        {
            EventHandler <TftpTransferErrorEventArgs> handler =
                (session.Operation == ETftpOperationType.WriteOperation) ?
                FileReceiveError :
                FileTransmitError
            ;

            var eventArgs = new TftpTransferErrorEventArgs
            {
                Id                = session.Id,
                Operation         = session.Operation,
                Filename          = session.Filename,
                RemoteHost        = session.RemoteHost,
                Stream            = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null,
                TransferInitiated = session.TransferRequestInitiated,
                TransferCompleted = DateTimeOffset.Now,
                Transferred       = session.Position,
                FailureReason     = reason
            };

            handler?.Invoke(
                this,
                eventArgs
                );

            var invocationList =
                (session.Operation == ETftpOperationType.WriteOperation) ?
                (FileReceiveErrorAsync?.GetInvocationList()) :
                (FileTransmitErrorAsync?.GetInvocationList())
            ;

            if (invocationList == null)
            {
                return;
            }

            var handlerTasks = new Task[invocationList.Length];

            for (int i = 0; i < invocationList.Length; i++)
            {
                handlerTasks[i] = ((Func <object, TftpTransferErrorEventArgs, Task>)invocationList[i])(this, eventArgs);
            }

            Task.WhenAll(handlerTasks);
        }
        private void OnUdpData(IAsyncResult result)
        {
            var timeReceived = DateTimeOffset.Now;
            var socket       = result.AsyncState as UdpClient;

            try
            {
                IPEndPoint source      = new IPEndPoint(0, 0);
                var        messageData = socket.EndReceive(result, ref source);

                if (!Sessions.TryGetValue(source, out TftpSession session))
                {
                    LogDebug($"New client detected from {source.Address}:{source.Port}");
                    session          = new TftpSession(this, source);
                    Sessions[source] = session;
                }

                var receiveTask =
                    Task.Factory.StartNew(
                        async() => {
                    try
                    {
                        await session.OnReceiveAsync(messageData);
                    }
                    catch (Exception e)
                    {
                        LogError("Internal error: " + e.Message);
                    }
                }
                        );
            }
            catch (Exception e)
            {
                LogError("Internal error: " + e.Message);
            }

            socket.BeginReceive(new AsyncCallback(OnUdpData), socket);
        }
        /// <summary>
        /// Called by a session to signal that it's complete
        /// </summary>
        /// <param name="session">The transfer which is complete</param>
        internal async Task TransferCompleteAsync(TftpSession session)
        {
            UnregisterSession(session);

            EventHandler <TftpTransferCompleteEventArgs> handler =
                (session.Operation == ETftpOperationType.WriteOperation) ?
                FileReceived :
                FileTransmitted
            ;

            var eventArgs = new TftpTransferCompleteEventArgs
            {
                Id                = session.Id,
                Operation         = session.Operation,
                Filename          = session.Filename,
                RemoteHost        = session.RemoteHost,
                Stream            = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null,
                TransferInitiated = session.TransferRequestInitiated,
                TransferCompleted = DateTimeOffset.Now,
                Transferred       = session.Position
            };

            handler?.Invoke(
                this,
                eventArgs
                );

            var invocationList =
                (session.Operation == ETftpOperationType.WriteOperation) ?
                (FileReceivedAsync?.GetInvocationList()) :
                (FileTransmittedAsync?.GetInvocationList())
            ;

            if (invocationList == null)
            {
                return;
            }

            var handlerTasks = new Task[invocationList.Length];

            for (int i = 0; i < invocationList.Length; i++)
            {
                handlerTasks[i] =
                    ((Func <object, TftpTransferCompleteEventArgs, Task>)invocationList[i])(
                        this,
                        new TftpTransferCompleteEventArgs
                {
                    Id                = session.Id,
                    Operation         = session.Operation,
                    Filename          = session.Filename,
                    RemoteHost        = session.RemoteHost,
                    Stream            = (session.Operation == ETftpOperationType.WriteOperation) ? (MemoryStream)session.TransferStream : null,
                    TransferInitiated = session.TransferRequestInitiated,
                    TransferCompleted = DateTimeOffset.Now,
                    Transferred       = session.Position
                }
                        );
            }

            await Task.WhenAll(handlerTasks);
        }