Esempio n. 1
0
        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;
        }
Esempio n. 2
0
 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)
 {
 }
Esempio n. 3
0
 internal static void SendError(UDPSocket socket, IPEndPoint endPoint, ErrorCode code, string message)
 {
     SendError(socket, endPoint, (ushort)code, message);
 }
Esempio n. 4
0
 internal static void Send(UDPSocket socket, IPEndPoint endPoint, MemoryStream ms)
 {
     socket.Send(endPoint, new ArraySegment <byte>(ms.ToArray()));
 }
Esempio n. 5
0
 internal static void Send(UDPSocket socket, IPEndPoint endPoint, ArraySegment <byte> data)
 {
     socket.Send(endPoint, data);
 }
Esempio n. 6
0
 private void OnUDPStop(UDPSocket sender, Exception reason)
 {
     Stop(reason);
 }
Esempio n. 7
0
        private void OnUDPReceive(UDPSocket sender, IPEndPoint endPoint, ArraySegment <byte> data)
        {
            bool         notify     = false;
            int          packetSize = data.Count;
            MemoryStream ms         = new MemoryStream(data.Array, data.Offset, data.Count, false, true);

            ITFTPSession session;
            bool         found;
            ushort       opCode = ReadUInt16(ms);

            lock (m_Sessions)
            {
                found = m_Sessions.TryGetValue(endPoint, out session);
            }

            // is there a session in progress for that endpoint?
            if (found)
            {
                // yes.
                switch ((Opcode)opCode)
                {
                case Opcode.ReadRequest:
                    // session already exists, and we're getting a new readrequest?
                    SendError(sender, endPoint, ErrorCode.IllegalOperation, "Read session already in progress");
                    break;

                case Opcode.WriteRequest:
                    // session already exists, and we're getting a new writerequest?
                    SendError(sender, endPoint, ErrorCode.IllegalOperation, "Write session already in progress");
                    break;

                case Opcode.Data:
                    session.ProcessData(ReadUInt16(ms), new ArraySegment <byte>(data.Array, (int)(data.Offset + ms.Position), (int)(data.Count - ms.Position)));
                    break;

                case Opcode.Ack:
                    session.ProcessAck(ReadUInt16(ms));
                    break;

                case Opcode.Error:
                    ushort code = ReadUInt16(ms);
                    string msg  = ReadZString(ms);
                    session.ProcessError(code, msg);
                    break;

                case Opcode.OptionsAck:
                    break;

                default:
                    SendError(sender, endPoint, ErrorCode.IllegalOperation, "Unknown opcode");
                    break;
                }
            }
            else     // session==null
            {
                // no session in progress for the endpoint that sent the packet
                switch ((Opcode)opCode)
                {
                case Opcode.ReadRequest:
                {
                    string filename = ReadZString(ms);
                    if (m_ConvertPathSeparator)
                    {
                        filename = filename.Replace('/', '\\');
                    }
                    Mode         mode             = ReadMode(ms);
                    var          requestedOptions = ReadOptions(ms);
                    ushort       windowSize       = GetWindowSize(filename);
                    ITFTPSession newSession       = new DownloadSession(this, m_UseSinglePort ? m_Socket : null, endPoint, requestedOptions, filename, windowSize, OnUDPReceive);

                    lock (m_Sessions)
                    {
                        m_Sessions.Add(newSession.RemoteEndPoint, newSession);
                    }

                    notify = true;
                    Trace(string.Format("Starting transfer of file '{0}' from local '{1}' to remote '{2}', send window size {3}", newSession.Filename, newSession.LocalEndPoint, newSession.RemoteEndPoint, windowSize));
                    newSession.Start();
                }
                break;

                case Opcode.WriteRequest:
                {
                    string filename = ReadZString(ms);
                    if (m_ConvertPathSeparator)
                    {
                        filename = filename.Replace('/', '\\');
                    }
                    Mode         mode             = ReadMode(ms);
                    var          requestedOptions = ReadOptions(ms);
                    ITFTPSession newSession       = new UploadSession(this, m_UseSinglePort ? m_Socket : null, endPoint, requestedOptions, filename, OnUDPReceive);

                    lock (m_Sessions)
                    {
                        m_Sessions.Add(newSession.RemoteEndPoint, newSession);
                    }

                    notify = true;
                    Trace(string.Format("Starting transfer of file '{0}' from remote '{1}' to local '{2}'", newSession.Filename, newSession.RemoteEndPoint, newSession.LocalEndPoint));
                    newSession.Start();
                }
                break;

                default:
                    SendError(m_Socket, endPoint, (ushort)ErrorCode.UnknownTransferID, "Unknown transfer ID");
                    break;
                }
            }

            if (notify)
            {
                OnStatusChange(this, null);
            }
        }