private void OnTimer(object state) { bool notify = false; lock (m_Lock) { if (!m_Disposed) { if (m_BlockRetry < m_Parent.m_MaxRetries) { m_BlockRetry++; SendResponse(); } else { TFTPServer.SendError(m_Socket, m_RemoteEndPoint, TFTPServer.ErrorCode.Undefined, "Timeout"); notify = true; } } } if (notify) { Stop(true, new TimeoutException("Remote side didn't respond in time")); } }
public override void Start() { var sessionLogConfiguration = new SessionLogEntry.TConfiguration() { FileLength = -1, Filename = m_Filename, IsUpload = false, LocalEndPoint = m_LocalEndPoint, RemoteEndPoint = m_RemoteEndPoint, StartTime = DateTime.Now, WindowSize = m_WindowSize }; try { lock (m_Lock) { try { m_Stream = m_Parent.GetReadStream(m_Filename); m_Length = m_Stream.Length; sessionLogConfiguration.FileLength = m_Length; m_Position = 0; } catch (Exception e) { TFTPServer.SendError(m_Socket, m_RemoteEndPoint, TFTPServer.ErrorCode.FileNotFound, e.Message); throw; } finally { m_SessionLog = m_Parent.SessionLog.CreateSession(sessionLogConfiguration); } // handle tsize option if (m_RequestedOptions.ContainsKey(TFTPServer.Option_TransferSize)) { if (m_Length >= 0) { m_AcceptedOptions.Add(TFTPServer.Option_TransferSize, m_Length.ToString()); } } if (m_AcceptedOptions.Count > 0) { m_BlockNumber = 0; SendOptionsAck(); } else { m_BlockNumber = 1; SendData(); } } } catch (Exception e) { Stop(true, e); } }
protected override void SendResponse() { // resend blocks in the window for (int t = 0; t < m_Window.Count; t++) { TFTPServer.Send(m_Socket, m_RemoteEndPoint, m_Window[t].Segment); } StartTimer(); }
public DownloadSession( TFTPServer parent, UDPSocket socket, IPEndPoint remoteEndPoint, Dictionary <string, string> requestedOptions, string filename, ushort windowSize, UDPSocket.OnReceiveDelegate onReceive) : base(parent, socket, remoteEndPoint, requestedOptions, filename, onReceive, 0) { m_WindowSize = windowSize; }
private void SendOptionsAck() { var seg = TFTPServer.GetOptionsAckPacket(m_AcceptedOptions); m_Window.Add(new WindowEntry() { IsData = false, Length = 0, Segment = seg }); TFTPServer.Send(m_Socket, m_RemoteEndPoint, seg); m_BlockRetry = 0; StartTimer(); }
private void SendData() { // fill the window up to the window size & send all the new packets while (m_Window.Count < m_WindowSize && !m_LastBlock) { byte[] buffer = new byte[m_CurrentBlockSize]; int dataSize = m_Stream.Read(buffer, 0, m_CurrentBlockSize); var seg = TFTPServer.GetDataPacket((ushort)(m_BlockNumber + m_Window.Count), buffer, dataSize); m_Window.Add(new WindowEntry() { IsData = true, Length = dataSize, Segment = seg }); m_LastBlock = (dataSize < m_CurrentBlockSize); TFTPServer.Send(m_Socket, m_RemoteEndPoint, seg); m_BlockRetry = 0; StartTimer(); } }
public override void ProcessData(ushort blockNr, ArraySegment <byte> data) { bool isComplete = false; lock (m_Lock) { if (blockNr == ((ushort)(m_BlockNumber + 1))) { m_BlockNumber = blockNr; m_LastBlock = data.Count < m_CurrentBlockSize; isComplete = m_LastBlock; m_Stream.Write(data.Array, data.Offset, data.Count); m_Position += data.Count; m_SessionLog.Progress(m_Position); // send ack for current block, client will respond with next block m_Window = TFTPServer.GetDataAckPacket(m_BlockNumber); TFTPServer.Send(m_Socket, m_RemoteEndPoint, m_Window); m_BlockRetry = 0; if (m_LastBlock) { StopTimer(); m_SessionLog.Complete(); } else { StartTimer(); } } } if (isComplete) { Stop(true, null); } }
public override void Start() { var sessionLogConfiguration = new SessionLogEntry.TConfiguration() { FileLength = -1, Filename = m_Filename, IsUpload = true, LocalEndPoint = m_LocalEndPoint, RemoteEndPoint = m_RemoteEndPoint, StartTime = DateTime.Now, WindowSize = 1 }; try { lock (m_Lock) { try { m_Length = m_RequestedOptions.ContainsKey(TFTPServer.Option_TransferSize) ? Int64.Parse(m_RequestedOptions[TFTPServer.Option_TransferSize]) : -1; sessionLogConfiguration.FileLength = m_Length; m_Stream = m_Parent.GetWriteStream(m_Filename, m_Length); m_Position = 0; } catch (Exception e) { TFTPServer.SendError(m_Socket, m_RemoteEndPoint, TFTPServer.ErrorCode.FileNotFound, e.Message); throw; } finally { // always create a SessionLog (even if the file couldn't be opened), so Stop() will have somewhere to store its errors m_SessionLog = m_Parent.SessionLog.CreateSession(sessionLogConfiguration); } // handle tsize option if (m_RequestedOptions.ContainsKey(TFTPServer.Option_TransferSize)) { // rfc2349: in Write Request packets, the size of the file, in octets, is specified in the // request and echoed back in the OACK m_AcceptedOptions.Add(TFTPServer.Option_TransferSize, m_RequestedOptions[TFTPServer.Option_TransferSize]); } if (m_AcceptedOptions.Count > 0) { // send options ack, client will respond with block number 1 m_Window = TFTPServer.GetOptionsAckPacket(m_AcceptedOptions); } else { // send ack for current block, client will respond with next block m_Window = TFTPServer.GetDataAckPacket(m_BlockNumber); } TFTPServer.Send(m_Socket, m_RemoteEndPoint, m_Window); m_BlockRetry = 0; StartTimer(); } } catch (Exception e) { Stop(true, e); } }
public UploadSession(TFTPServer parent, UDPSocket socket, IPEndPoint remoteEndPoint, Dictionary <string, string> requestedOptions, string filename, UDPSocket.OnReceiveDelegate onReceive) : base(parent, socket, remoteEndPoint, requestedOptions, filename, onReceive, 1000) { }
protected override void SendResponse() { TFTPServer.Send(m_Socket, m_RemoteEndPoint, m_Window); StartTimer(); }
public TFTPSession(TFTPServer parent, UDPSocket socket, IPEndPoint remoteEndPoint, Dictionary <string, string> requestedOptions, string filename, UDPSocket.OnReceiveDelegate onReceive, int socketDisposeDelay) { m_Parent = parent; m_CurrentBlockSize = TFTPServer.DefaultBlockSize; m_ResponseTimeout = m_Parent.m_ResponseTimeout; m_RemoteEndPoint = remoteEndPoint; m_Timer = new Timer(new System.Threading.TimerCallback(OnTimer), this, Timeout.Infinite, Timeout.Infinite); m_RequestedOptions = requestedOptions; m_Filename = filename; m_SocketDisposeDelay = socketDisposeDelay; m_Length = 0; m_LastBlock = false; m_BlockNumber = 0; m_BlockRetry = 0; foreach (var kvp in m_RequestedOptions) { switch (kvp.Key) { case TFTPServer.Option_Multicast: // not supported break; case TFTPServer.Option_Timeout: //Console.WriteLine("Timeout of {0}", kvp.Value); int requestedTimeout = int.Parse(kvp.Value); // rfc2349 : valid values range between "1" and "255" seconds if (requestedTimeout >= 1 && requestedTimeout <= 255) { m_ResponseTimeout = requestedTimeout * 1000; m_AcceptedOptions.Add(TFTPServer.Option_Timeout, kvp.Value); } break; case TFTPServer.Option_TransferSize: // handled in inherited classes break; case TFTPServer.Option_BlockSize: //Console.WriteLine("Blocksize of {0}", kvp.Value); int requestedBlockSize = int.Parse(kvp.Value); // rfc2348 : valid values range between "8" and "65464" octets, inclusive if (requestedBlockSize >= 8 && requestedBlockSize <= 65464) { m_CurrentBlockSize = Math.Min(TFTPServer.MaxBlockSize, requestedBlockSize); m_AcceptedOptions.Add(TFTPServer.Option_BlockSize, m_CurrentBlockSize.ToString()); } break; } } if (socket != null) { m_OwnSocket = false; m_Socket = socket; } else { m_OwnSocket = true; m_Socket = new UDPSocket( new IPEndPoint(m_Parent.m_ServerEndPoint.Address, 0), m_CurrentBlockSize + 4, m_Parent.m_DontFragment, m_Parent.m_Ttl, onReceive, (sender, reason) => { Stop(true, reason); }); } m_LocalEndPoint = (IPEndPoint)m_Socket.LocalEndPoint; }